[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*.cs]\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_indent_block_contents\ncsharp_indent_block_contents = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_indent_braces\ncsharp_indent_braces = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_indent_case_contents\ncsharp_indent_case_contents = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_indent_switch_labels\ncsharp_indent_switch_labels = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_new_line_before_catch\ncsharp_new_line_before_catch = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_new_line_before_else\ncsharp_new_line_before_else = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_new_line_before_finally\ncsharp_new_line_before_finally = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_new_line_before_members_in_anonymous_types\ncsharp_new_line_before_members_in_anonymous_types = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_new_line_before_members_in_object_initializers\ncsharp_new_line_before_members_in_object_initializers = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_new_line_before_open_brace\ncsharp_new_line_before_open_brace = all\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_after_cast\ncsharp_space_after_cast = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_after_colon_in_inheritance_clause\ncsharp_space_after_colon_in_inheritance_clause = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_after_comma\ncsharp_space_after_comma = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_after_dot\ncsharp_space_after_dot = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_after_keywords_in_control_flow_statements\ncsharp_space_after_keywords_in_control_flow_statements = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_after_semicolon_in_for_statement\ncsharp_space_after_semicolon_in_for_statement = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_around_binary_operators \ncsharp_space_around_binary_operators = before_and_after\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_before_colon_in_inheritance_clause\ncsharp_space_before_colon_in_inheritance_clause = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_before_comma\ncsharp_space_before_comma = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_before_dot\ncsharp_space_before_dot = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_before_open_square_brackets\ncsharp_space_before_open_square_brackets = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_before_semicolon_in_for_statement\ncsharp_space_before_semicolon_in_for_statement = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_empty_square_brackets\ncsharp_space_between_empty_square_brackets = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_method_call_empty_parameter_list_parentheses\ncsharp_space_between_method_call_empty_parameter_list_parentheses = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_method_call_name_and_opening_parenthesis\ncsharp_space_between_method_call_name_and_opening_parenthesis = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_method_call_parameter_list_parentheses\ncsharp_space_between_method_call_parameter_list_parentheses = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_method_declaration_empty_parameter_list_parentheses\ncsharp_space_between_method_declaration_empty_parameter_list_parentheses = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_method_declaration_name_and_open_parenthesis\ncsharp_space_between_method_declaration_name_and_open_parenthesis = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_method_declaration_parameter_list_parentheses\ncsharp_space_between_method_declaration_parameter_list_parentheses = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_parentheses\ncsharp_space_between_parentheses = none\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_between_square_brackets\ncsharp_space_between_square_brackets = false\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_expression_bodied_accessors\ncsharp_style_expression_bodied_accessors = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_expression_bodied_constructors\ncsharp_style_expression_bodied_constructors = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_expression_bodied_indexers\ncsharp_style_expression_bodied_indexers = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_expression_bodied_methods\ncsharp_style_expression_bodied_methods = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_expression_bodied_operators\ncsharp_style_expression_bodied_operators = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_expression_bodied_properties\ncsharp_style_expression_bodied_properties = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_inlined_variable_declaration\ncsharp_style_inlined_variable_declaration = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_pattern_matching_over_as_with_null_check\ncsharp_style_pattern_matching_over_as_with_null_check = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_pattern_matching_over_is_with_cast_check\ncsharp_style_pattern_matching_over_is_with_cast_check = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_throw_expression\ncsharp_style_throw_expression = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_var_elsewhere\ncsharp_style_var_elsewhere = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_var_for_built_in_types\ncsharp_style_var_for_built_in_types = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_var_when_type_is_apparent\ncsharp_style_var_when_type_is_apparent = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_sort_system_directives_first\ndotnet_sort_system_directives_first = true\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_coalesce_expression\ndotnet_style_coalesce_expression = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_collection_initializer\ndotnet_style_collection_initializer = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_explicit_tuple_names\ndotnet_style_explicit_tuple_names = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_null_propagation\ndotnet_style_null_propagation = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_object_initializer\ndotnet_style_object_initializer = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_predefined_type_for_locals_parameters_members\ndotnet_style_predefined_type_for_locals_parameters_members = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_predefined_type_for_member_access\ndotnet_style_predefined_type_for_member_access = true:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_qualification_for_event\ndotnet_style_qualification_for_event = false:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_qualification_for_field\ndotnet_style_qualification_for_field = false:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_qualification_for_method\ndotnet_style_qualification_for_method = false:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#dotnet_style_qualification_for_property\ndotnet_style_qualification_for_property = false:suggestion\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#end_of_line\nend_of_line = lf\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#indent_size\nindent_size = 4\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#indent_style\nindent_style = space\n\n# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#insert_final_newline\ninsert_final_newline = true\n"
  },
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms.\n\ngithub: [louthy]\npatreon: louthy\nko_fi: louthy\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n**.idea\n*.iml\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\nx64/\nbuild/\nbld/\n[Bb]in/\n[Oo]bj/\nlib/\n.vs/\n\n# Roslyn cache directories\n*.ide/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n#NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n*.lock.json\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding addin-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n## TODO: Comment the next line if you want to checkin your\n## web deploy settings but do note that will include unencrypted\n## passwords\n#*.pubxml\n\n# NuGet Packages Directory\npackages/*\n## TODO: If the tool you use requires repositories.config\n## uncomment the next line\n#!packages/repositories.config\n\n# Enable \"build/\" folder in the NuGet Packages folder since\n# NuGet packages use it for MSBuild targets.\n# This line needs to be after the ignore of the build folder\n# (and the packages folder if the line above has been uncommented)\n!packages/build/\n\n# Windows Azure Build Output\ncsx/\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\nsql/\n*.Cache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\nbower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# LightSwitch generated files\nGeneratedArtifacts/\n_Pvt_Extensions/\nModelManifest.xml\n/SettingsParser.playlist\n/Parsec Tests.playlist\n/LanguageExt.Tests/LanguageExt.Tests.nuget.props\n/.idea/.idea.language-ext\n\n# Benchmark artifacts\nBenchmarkDotNet.Artifacts/\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at p.louth@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## How to contribute to language-ext\n\n#### **Did you find a bug?**\n\n* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/louthy/language-ext/issues).\n\n* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/louthy/language-ext/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring.\n\n#### **Did you write a patch that fixes a bug?**\n\n* Open a new GitHub pull request with the patch.\n\n* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.\n\n#### **Do you intend to add a new feature or change an existing one?**\n\n* First suggest your change in the [language-ext issues page](https://github.com/louthy/language-ext/issues).\n\n* There are no fixed rules on what should and shouldn't be in this library, but some features are more valuable than others, and some require long-term maintenance that outweighs the value of the feature. So please get sign-off from the project leader (Paul Louth) before putting in an excessive amount of work.\n\n#### **Do you have questions about the source code?**\n\n* Ask any question about how to use language-ext in the [language-ext issues page](https://github.com/louthy/language-ext/issues).\n\n#### **Do you want to contribute to the language-ext documentation?**\n\nThis is very welcome:\n\n* The APi documentation is generated from the source code - please make sure you use back-tick markdown code-blocks within `<summary>...</summary>` and other XmlDoc sections for variable, method, or type-names and code-examples.  If unclear, ask on the [language-ext issues page](https://github.com/louthy/language-ext/issues)\n\n* The [language-ext wiki](https://github.com/louthy/language-ext/wiki) is always crying out for general usage examples.  If you want to talk about a larger subject that is enabled by language-ext (like parsing for example), then clear it first on the [language-ext issues page](https://github.com/louthy/language-ext/issues).\n\nThanks! :heart: :heart: :heart:\n\nPaul Louth\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014-2025 Paul Louth\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "LanguageExt.Benchmarks/HashMapAddBenchmarks.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing Sasa.Collections;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class HashMapAddBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        Dictionary<T, T> values;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            values = ValuesGenerator.Default.GenerateDictionary<T, T>(N);\n        }\n\n        [Benchmark]\n        public ImmutableDictionary<T, T> SysColImmutableDictionary()\n        {\n            var map = ImmutableDictionary.Create<T, T>();\n            foreach (var kvp in values)\n            {\n                map = map.Add(kvp.Key, kvp.Value);\n            }\n\n            return map;\n        }\n\n        [Benchmark]\n        public ImmutableSortedDictionary<T, T> SysColImmutableSortedDictionary()\n        {\n            var map = ImmutableSortedDictionary.Create<T, T>();\n            foreach (var kvp in values)\n            {\n                map = map.Add(kvp.Key, kvp.Value);\n            }\n\n            return map;\n        }\n        \n        [Benchmark]\n        public Trie<T, T> SasaTrie()\n        {\n            var map = Trie<T, T>.Empty;\n            foreach (var kvp in values)\n            {\n                map = map.Add(kvp.Key, kvp.Value);\n            }\n\n            return map;\n        }\n        \n        [Benchmark]\n        public Dictionary<T, T> SysColDictionary()\n        {\n            var map = new Dictionary<T, T>();\n            foreach (var kvp in values)\n            {\n                map.Add(kvp.Key, kvp.Value);\n            }\n\n            return map;\n        }\n\n        [Benchmark]\n        public HashMap<TOrd, T, T> LangExtHashMap()\n        {\n            var map = HashMap<TOrd, T, T>();\n            foreach (var kvp in values)\n            {\n                map = map.Add(kvp.Key, kvp.Value);\n            }\n\n            return map;\n        }\n\n        [Benchmark]\n        public Map<TOrd, T, T> LangExtMap()\n        {\n            var map = Map<TOrd, T, T>();\n            foreach (var kvp in values)\n            {\n                map = map.Add(kvp.Key, kvp.Value);\n            }\n\n            return map;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/HashMapContainsKeyBenchmarks.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing Sasa.Collections;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class HashMapContainsKeyBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        T[] keys;\n\n        ImmutableDictionary<T, T> immutableMap;\n        ImmutableSortedDictionary<T, T> immutableSortedMap;\n        Dictionary<T, T> dictionary;\n        HashMap<TOrd, T, T> hashMap;\n        Map<TOrd, T, T> map;\n        Trie<T, T> sasaTrie;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            var values = ValuesGenerator.Default.GenerateDictionary<T, T>(N);\n            keys = values.Keys.ToArray();\n\n            sasaTrie = ValuesGenerator.SasaTrieSetup(values);\n            immutableMap = ValuesGenerator.SysColImmutableDictionarySetup(values);\n            immutableSortedMap = ValuesGenerator.SysColImmutableSortedDictionarySetup(values);\n            dictionary = ValuesGenerator.SysColDictionarySetup(values);\n            hashMap = ValuesGenerator.LangExtHashMapSetup<T, TOrd>(values);\n            map = ValuesGenerator.LangExtMapSetup<T, TOrd>(values);\n        }\n\n        [Benchmark]\n        public bool SysColImmutableDictionary()\n        {\n            var result = true;\n            foreach (var key in keys)\n            {\n                result &= immutableMap.ContainsKey(key);\n            }\n\n            return result;\n        }\n        \n        [Benchmark]\n        public bool SasaTrie()\n        {\n            var result = true;\n            foreach (var key in keys)\n            {\n                result &= sasaTrie.ContainsKey(key);\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public bool SysColImmutableSortedDictionary()\n        {\n            var result = true;\n            foreach (var key in keys)\n            {\n                result &= immutableSortedMap.ContainsKey(key);\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public bool SysColDictionary()\n        {\n            var result = true;\n            foreach (var key in keys)\n            {\n                result &= dictionary.ContainsKey(key);\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public bool LangExtHashMap()\n        {\n            var result = true;\n            foreach (var key in keys)\n            {\n                result &= hashMap.ContainsKey(key);\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public bool LangExtMap()\n        {\n            var result = true;\n            foreach (var key in keys)\n            {\n                result &= map.ContainsKey(key);\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/HashMapIterateBenchmarks.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing Sasa.Collections;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class HashMapIterateBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        ImmutableDictionary<T, T> immutableMap;\n        ImmutableSortedDictionary<T, T> immutableSortedMap;\n        Dictionary<T, T> dictionary;\n        HashMap<TOrd, T, T> hashMap;\n        Map<TOrd, T, T> map;\n        Trie<T, T> sasaTrie;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            var values = ValuesGenerator.Default.GenerateDictionary<T, T>(N);\n\n            sasaTrie = ValuesGenerator.SasaTrieSetup(values);\n            immutableMap = ValuesGenerator.SysColImmutableDictionarySetup(values);\n            immutableSortedMap = ValuesGenerator.SysColImmutableSortedDictionarySetup(values);\n            dictionary = ValuesGenerator.SysColDictionarySetup(values);\n            hashMap = ValuesGenerator.LangExtHashMapSetup<T, TOrd>(values);\n            map = ValuesGenerator.LangExtMapSetup<T, TOrd>(values);\n        }\n\n        [Benchmark]\n        public T SysColImmutableDictionary()\n        {\n            T result = default;\n\n            var collection = immutableMap;\n            foreach (var item in collection)\n            {\n                result = item.Value;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T SysColImmutableSortedDictionary()\n        {\n            T result = default;\n\n            var collection = immutableSortedMap;\n            foreach (var item in collection)\n            {\n                result = item.Value;\n            }\n\n            return result;\n        }\n        \n        [Benchmark]\n        public T SasaTrie()\n        {\n            T result = default;\n\n            var collection = sasaTrie;\n            foreach (var item in collection)\n            {\n                result = item.Value;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T SysColDictionary()\n        {\n            T result = default;\n\n            var collection = dictionary;\n            foreach (var item in collection)\n            {\n                result = item.Value;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T LangExtHashMap()\n        {\n            T result = default;\n\n            var collection = hashMap;\n            foreach (var item in collection)\n            {\n                result = item.Value;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T LangExtMap()\n        {\n            T result = default;\n\n            var collection = map;\n            foreach (var item in collection)\n            {\n                result = item.Value;\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/HashMapRandomRemovalBenchmarks.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing Sasa.Collections;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class HashMapRandomRemovalBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        T[] keys;\n\n        ImmutableDictionary<T, T> immutableMap;\n        ImmutableSortedDictionary<T, T> immutableSortedMap;\n        Dictionary<T, T> dictionary;\n        HashMap<TOrd, T, T> hashMap;\n        Map<TOrd, T, T> map;\n        Trie<T, T> sasaTrie;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            var values = ValuesGenerator.Default.GenerateDictionary<T, T>(N);\n            keys = values.Keys.ToArray();\n\n            sasaTrie = ValuesGenerator.SasaTrieSetup(values);\n            immutableMap = ValuesGenerator.SysColImmutableDictionarySetup(values);\n            immutableSortedMap = ValuesGenerator.SysColImmutableSortedDictionarySetup(values);\n            dictionary = ValuesGenerator.SysColDictionarySetup(values);\n            hashMap = ValuesGenerator.LangExtHashMapSetup<T, TOrd>(values);\n            map = ValuesGenerator.LangExtMapSetup<T, TOrd>(values);\n        }\n\n        [Benchmark]\n        public bool SysColImmutableDictionary()\n        {\n            var localImmutableMap = immutableMap;\n            foreach (var key in keys)\n            {\n                localImmutableMap = localImmutableMap.Remove(key);\n            }\n\n            return localImmutableMap.IsEmpty;\n        }\n\n        [Benchmark]\n        public bool SysColImmutableSortedDictionary()\n        {\n            var localSortedMap = immutableSortedMap;\n            foreach (var key in keys)\n            {\n                localSortedMap = localSortedMap.Remove(key);\n            }\n\n            return localSortedMap.IsEmpty;\n        }\n        \n        \n        [Benchmark]\n        public bool SasaTrie()\n        {\n            var localImmutableMap = sasaTrie;\n            foreach (var key in keys)\n            {\n                localImmutableMap = localImmutableMap.Remove(key);\n            }\n\n            return localImmutableMap.IsEmpty();\n        }\n\n        [Benchmark]\n        public bool SysColDictionary()\n        {\n            // NB! no local variable - mutating field instance\n            foreach (var key in keys)\n            {\n                dictionary.Remove(key);\n            }\n\n            return dictionary.Count == 0;\n        }\n\n        [Benchmark]\n        public bool LangExtHashMap()\n        {\n            var localHashMap = hashMap;\n            foreach (var key in keys)\n            {\n                localHashMap = localHashMap.Remove(key);\n            }\n\n            return localHashMap.IsEmpty;\n        }\n\n        [Benchmark]\n        public bool LangExtMap()\n        {\n            var localMap = map;\n            foreach (var key in keys)\n            {\n                localMap = localMap.Remove(key);\n            }\n\n            return localMap.IsEmpty;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/HashSetAddBenchmarks.cs",
    "content": "﻿using System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class HashSetAddBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        T[] values;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            values = ValuesGenerator.Default.GenerateUniqueValues<T>(N);\n        }\n\n        [Benchmark]\n        public ImmutableHashSet<T> SysColImmutableHashSet()\n        {\n            var set = ImmutableHashSet.Create<T>();\n            foreach (var value in values)\n            {\n                set = set.Add(value);\n            }\n\n            return set;\n        }\n\n        [Benchmark]\n        public ImmutableSortedSet<T> SysColImmutableSortedSet()\n        {\n            var set = ImmutableSortedSet.Create<T>();\n            foreach (var value in values)\n            {\n                set = set.Add(value);\n            }\n\n            return set;\n        }\n\n        [Benchmark]\n        public System.Collections.Generic.HashSet<T> SysColHashSet()\n        {\n            var set = new System.Collections.Generic.HashSet<T>();\n            foreach (var value in values)\n            {\n                set.Add(value);\n            }\n\n            return set;\n        }\n\n        [Benchmark]\n        public HashSet<TOrd, T> LangExtHashSet()\n        {\n            var set = HashSet<TOrd, T>();\n            foreach (var value in values)\n            {\n                set = set.Add(value);\n            }\n\n            return set;\n        }\n\n        [Benchmark]\n        public Set<TOrd, T> LangExtSet()\n        {\n            var set = Set<TOrd, T>();\n            foreach (var value in values)\n            {\n                set = set.Add(value);\n            }\n\n            return set;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/HashSetContainsBenchmarks.cs",
    "content": "﻿using System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class HashSetContainsBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        T[] values;\n\n        ImmutableHashSet<T> immutableHashSet;\n        ImmutableSortedSet<T> immutableSortedSet;\n        System.Collections.Generic.HashSet<T> sysHashSet;\n        HashSet<TOrd, T> hashSet;\n        Set<TOrd, T> set;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            values = ValuesGenerator.Default.GenerateUniqueValues<T>(N);\n\n            immutableHashSet = ValuesGenerator.SysColImmutableHashSetSetup(values);\n            immutableSortedSet = ValuesGenerator.SysColImmutableSortedSetSetup(values);\n            sysHashSet = ValuesGenerator.SysColHashSetSetup(values);\n            hashSet = ValuesGenerator.LangExtHashSetSetup<T, TOrd>(values);\n            set = ValuesGenerator.LangExtSetSetup<T, TOrd>(values);\n        }\n\n        [Benchmark]\n        public bool SysColImmutableHashSet()\n        {\n            var result = true;\n            foreach (var value in values)\n            {\n                result &= immutableHashSet.Contains(value);\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public bool SysColImmutableSortedSet()\n        {\n            var result = true;\n            foreach (var value in values)\n            {\n                result &= immutableSortedSet.Contains(value);\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public bool SysColHashSet()\n        {\n            var result = true;\n            foreach (var value in values)\n            {\n                result &= sysHashSet.Contains(value);\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public bool LangExtHashSet()\n        {\n            var result = true;\n            foreach (var value in values)\n            {\n                result &= hashSet.Contains(value);\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public bool LangExtSet()\n        {\n            var result = true;\n            foreach (var value in values)\n            {\n                result &= set.Contains(value);\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/HashSetIterationBenchmarks.cs",
    "content": "﻿using System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class HashSetIterationBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        T[] values;\n\n        ImmutableHashSet<T> immutableHashSet;\n        ImmutableSortedSet<T> immutableSortedSet;\n        System.Collections.Generic.HashSet<T> sysHashSet;\n        HashSet<TOrd, T> hashSet;\n        Set<TOrd, T> set;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            values = ValuesGenerator.Default.GenerateUniqueValues<T>(N);\n\n            immutableHashSet = ValuesGenerator.SysColImmutableHashSetSetup(values);\n            immutableSortedSet = ValuesGenerator.SysColImmutableSortedSetSetup(values);\n            sysHashSet = ValuesGenerator.SysColHashSetSetup(values);\n            hashSet = ValuesGenerator.LangExtHashSetSetup<T, TOrd>(values);\n            set = ValuesGenerator.LangExtSetSetup<T, TOrd>(values);\n        }\n\n        [Benchmark]\n        public T SysColImmutableHashSet()\n        {\n            T result = default;\n\n            var collection = immutableHashSet;\n            foreach (var item in collection)\n            {\n                result = item;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T SysColImmutableSortedSet()\n        {\n            T result = default;\n\n            var collection = immutableSortedSet;\n            foreach (var item in collection)\n            {\n                result = item;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T SysColHashSet()\n        {\n            T result = default;\n\n            var collection = sysHashSet;\n            foreach (var item in collection)\n            {\n                result = item;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T LangExtHashSet()\n        {\n            T result = default;\n\n            var collection = hashSet;\n            foreach (var item in collection)\n            {\n                result = item;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T LangExtSet()\n        {\n            T result = default;\n\n            var collection = set;\n            foreach (var item in collection)\n            {\n                result = item;\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/HashSetRandomRemovalBenchmarks.cs",
    "content": "﻿using System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class HashSetRandomRemovalBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        T[] values;\n\n        ImmutableHashSet<T> immutableSet;\n        ImmutableSortedSet<T> immutableSortedSet;\n        System.Collections.Generic.HashSet<T> sysHashSet;\n        HashSet<TOrd, T> hashSet;\n        Set<TOrd, T> set;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            values = ValuesGenerator.Default.GenerateUniqueValues<T>(N);\n\n            immutableSet = ValuesGenerator.SysColImmutableHashSetSetup(values);\n            immutableSortedSet = ValuesGenerator.SysColImmutableSortedSetSetup(values);\n            sysHashSet = ValuesGenerator.SysColHashSetSetup(values);\n            hashSet = ValuesGenerator.LangExtHashSetSetup<T, TOrd>(values);\n            set = ValuesGenerator.LangExtSetSetup<T, TOrd>(values);\n        }\n\n        [Benchmark]\n        public bool SysColImmutableHashSet()\n        {\n            var localImmutableSet = immutableSet;\n            foreach (var value in values)\n            {\n                localImmutableSet = localImmutableSet.Remove(value);\n            }\n\n            return localImmutableSet.IsEmpty;\n        }\n\n        [Benchmark]\n        public bool SysColImmutableSortedSet()\n        {\n            var localImmutableSortedSet = immutableSortedSet;\n            foreach (var value in values)\n            {\n                localImmutableSortedSet = localImmutableSortedSet.Remove(value);\n            }\n\n            return localImmutableSortedSet.IsEmpty;\n        }\n\n        [Benchmark]\n        public bool SysColHashSet()\n        {\n            // NB! no local variable - mutating field instance\n            foreach (var value in values)\n            {\n                sysHashSet.Remove(value);\n            }\n\n            return sysHashSet.Count == 0;\n        }\n\n        [Benchmark]\n        public bool LangExtHashSet()\n        {\n            var localHashSet = hashSet;\n            foreach (var value in values)\n            {\n                localHashSet = localHashSet.Remove(value);\n            }\n\n            return localHashSet.IsEmpty;\n        }\n\n        [Benchmark]\n        public bool LangExtSet()\n        {\n            var localSet = set;\n            foreach (var value in values)\n            {\n                localSet = localSet.Remove(value);\n            }\n\n            return localSet.IsEmpty;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/LanguageExt.Benchmarks.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net10.0</TargetFramework>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"BenchmarkDotNet\" Version=\"0.13.5\" />\n    <PackageReference Include=\"Sasa.Collections\" Version=\"1.0.0-RC4\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "LanguageExt.Benchmarks/ListAddBenchmarks.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class ListAddBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        T[] values;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            values = ValuesGenerator.Default.GenerateUniqueValues<T>(N);\n        }\n\n        [Benchmark]\n        public ImmutableList<T> SysColImmutableList()\n        {\n            var collection = ImmutableList.Create<T>();\n            foreach (var value in values)\n            {\n                collection = collection.Add(value);\n            }\n\n            return collection;\n        }\n\n        [Benchmark]\n        public Lst<T> LangExtLst()\n        {\n            var collection = List<T>();\n            foreach (var value in values)\n            {\n                collection = collection.Add(value);\n            }\n\n            return collection;\n        }\n\n        [Benchmark]\n        public Seq<T> LangExtSeq()\n        {\n            var collection = Seq<T>();\n            foreach (var value in values)\n            {\n                collection = collection.Add(value);\n            }\n\n            return collection;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/ListIterationBenchmarks.cs",
    "content": "﻿using System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Benchmarks\n{\n    [RPlotExporter, RankColumn]\n    [GenericTypeArguments(typeof(int), typeof(OrdInt))]\n    [GenericTypeArguments(typeof(string), typeof(OrdString))]\n    public class ListIterationBenchmarks<T, TOrd>\n        where TOrd : Ord<T>\n    {\n        [Params(100, 1000, 10000, 100000)]\n        public int N;\n\n        T[] values;\n        ImmutableList<T> immutableList;\n        Lst<T> lst;\n        Seq<T> seq;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            values = ValuesGenerator.Default.GenerateUniqueValues<T>(N);\n            immutableList = ImmutableList.CreateRange(ValuesGenerator.Default.GenerateUniqueValues<T>(N));\n            lst = ValuesGenerator.Default.GenerateUniqueValues<T>(N).AsIterable().ToLst();\n            seq = toSeq(ValuesGenerator.Default.GenerateUniqueValues<T>(N)).Strict();\n        }\n\n        [Benchmark]\n        public T SysColImmutableList()\n        {\n            T result = default;\n\n            var collection = immutableList;\n            foreach (var item in collection)\n            {\n                result = item;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T LangExtLst()\n        {\n            T result = default;\n\n            var collection = lst;\n            foreach (var item in collection)\n            {\n                result = item;\n            }\n\n            return result;\n        }\n\n        [Benchmark]\n        public T LangExtSeq()\n        {\n            T result = default;\n\n            var collection = seq;\n            foreach (var item in collection)\n            {\n                result = item;\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/Program.cs",
    "content": "﻿using BenchmarkDotNet.Running;\n\nnamespace LanguageExt.Benchmarks\n{\n    class Program\n    {\n        static void Main(string[] args) =>\n            BenchmarkSwitcher\n                .FromAssembly(typeof(Program).Assembly)\n                .Run(args);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/ValuesGenerator.MapSetup.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing LanguageExt.Traits;\nusing Sasa.Collections;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Benchmarks\n{\n    internal partial class ValuesGenerator\n    {\n        public static Trie<T, T> SasaTrieSetup<T>(Dictionary<T, T> values)\n        {\n            var trie = Trie<T, T>.Empty;\n            foreach (var kvp in values)\n            {\n                trie = trie.Add(kvp.Key, kvp.Value);\n            }\n            return trie;\n        }\n        \n        public static ImmutableDictionary<T, T> SysColImmutableDictionarySetup<T>(Dictionary<T, T> values)\n        {\n            var immutableMap = ImmutableDictionary.Create<T, T>();\n            foreach (var kvp in values)\n            {\n                immutableMap = immutableMap.Add(kvp.Key, kvp.Value);\n            }\n\n            return immutableMap;\n        }\n\n        public static ImmutableSortedDictionary<T, T> SysColImmutableSortedDictionarySetup<T>(Dictionary<T, T> values)\n        {\n            var immutableMap = ImmutableSortedDictionary.Create<T, T>();\n            foreach (var kvp in values)\n            {\n                immutableMap = immutableMap.Add(kvp.Key, kvp.Value);\n            }\n\n            return immutableMap;\n        }\n\n        public static Dictionary<T, T> SysColDictionarySetup<T>(Dictionary<T, T> values)\n        {\n            var dictionary = new Dictionary<T, T>();\n            foreach (var kvp in values)\n            {\n                dictionary.Add(kvp.Key, kvp.Value);\n            }\n\n            return dictionary;\n        }\n\n        public static HashMap<TEq, T, T> LangExtHashMapSetup<T, TEq>(Dictionary<T, T> values)\n            where TEq : Eq<T>\n        {\n            var hashMap = HashMap<TEq, T, T>();\n            foreach (var kvp in values)\n            {\n                hashMap = hashMap.Add(kvp.Key, kvp.Value);\n            }\n\n            return hashMap;\n        }\n\n        public static Map<TOrd, T, T> LangExtMapSetup<T, TOrd>(Dictionary<T, T> values)\n            where TOrd : Ord<T>\n        {\n            var hashMap = Map<TOrd, T, T>();\n            foreach (var kvp in values)\n            {\n                hashMap = hashMap.Add(kvp.Key, kvp.Value);\n            }\n\n            return hashMap;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/ValuesGenerator.SetSetup.cs",
    "content": "﻿using System.Collections.Immutable;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Benchmarks\n{\n    internal partial class ValuesGenerator\n    {\n        public static ImmutableHashSet<T> SysColImmutableHashSetSetup<T>(T[] values)\n        {\n            var immutableSet = ImmutableHashSet.Create<T>();\n            foreach (var value in values)\n            {\n                immutableSet = immutableSet.Add(value);\n            }\n\n            return immutableSet;\n        }\n\n        public static ImmutableSortedSet<T> SysColImmutableSortedSetSetup<T>(T[] values)\n        {\n            var immutableSet = ImmutableSortedSet.Create<T>();\n            foreach (var value in values)\n            {\n                immutableSet = immutableSet.Add(value);\n            }\n\n            return immutableSet;\n        }\n\n        public static System.Collections.Generic.HashSet<T> SysColHashSetSetup<T>(T[] values)\n        {\n            var hashSet = new System.Collections.Generic.HashSet<T>();\n            foreach (var value in values)\n            {\n                hashSet.Add(value);\n            }\n\n            return hashSet;\n        }\n\n        public static HashSet<TEq, T> LangExtHashSetSetup<T, TEq>(T[] values)\n            where TEq : Eq<T>\n        {\n            var hashSet = HashSet<TEq, T>();\n            foreach (var value in values)\n            {\n                hashSet = hashSet.Add(value);\n            }\n\n            return hashSet;\n        }\n\n        public static Set<TOrd, T> LangExtSetSetup<T, TOrd>(T[] values)\n            where TOrd : Ord<T>\n        {\n            var set = Set<TOrd, T>();\n            foreach (var value in values)\n            {\n                set = set.Add(value);\n            }\n\n            return set;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Benchmarks/ValuesGenerator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace LanguageExt.Benchmarks\n{\n    internal partial class ValuesGenerator\n    {\n        public static readonly ValuesGenerator Default = new ValuesGenerator(12345);\n\n        readonly int randSeed;\n\n        public ValuesGenerator(int seed)\n        {\n            randSeed = seed;\n        }\n\n        public Dictionary<TKey, TValue> GenerateDictionary<TKey, TValue>(int count)\n        {\n            var rand = new Random(randSeed);\n\n            var dict = new Dictionary<TKey, TValue>(count);\n            while (dict.Count < count)\n            {\n                dict[GenerateValue<TKey>(rand)] = GenerateValue<TValue>(rand);\n            }\n\n            return dict;\n        }\n\n        public T[] GenerateUniqueValues<T>(int count)\n        {\n            var rand = new Random(randSeed);\n\n            var set = new System.Collections.Generic.HashSet<T>(count);\n            while (set.Count < count)\n            {\n                set.Add(GenerateValue<T>(rand));\n            }\n\n            return set.ToArray();\n        }\n\n        private T GenerateValue<T>(Random rand)\n        {\n            if (typeof(T) == typeof(int))\n            {\n                return (T)(object)rand.Next();\n            }\n\n            if (typeof(T) == typeof(string))\n            {\n                return (T)(object)GenerateString(rand, 1, 50);\n            }\n\n            throw new NotSupportedException($\"Generating value of type {typeof(T)} is not supported\");\n        }\n\n        private string GenerateString(Random rand, int minLength, int maxLength)\n        {\n            var length = rand.Next(minLength, maxLength);\n            var sb = new StringBuilder(length);\n\n            for (var i = 0; i < length; i++)\n            {\n                switch (rand.Next(0, 3))\n                {\n                    case 0:\n                        sb.Append((char)rand.Next('0', '9'));\n                        break;\n\n                    case 1:\n                        sb.Append((char)rand.Next('A', 'Z'));\n                        break;\n\n                    default:\n                        sb.Append((char)rand.Next('a', 'z'));\n                        break;\n                }\n            }\n\n            return sb.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Catch.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Used by `@catch`, `@exceptional`, `@expected` to represent the catching of errors\n/// </summary>\npublic readonly record struct CatchM<E, M, A>(Func<E, bool> Match, Func<E, K<M, A>> Action)\n    where M : Fallible<E, M>\n{\n    public K<M, A> Run(E error, K<M, A> otherwise) =>\n        Match(error) ? Action(error) : otherwise;\n}\n\npublic static class CatchMExtensions\n{\n    extension<E, M, A>(CatchM<E, M, A> self)\n        where M : Functor<M>, Fallible<E, M>\n    {\n        public CatchM<E, M, B> Map<B>(Func<A, B> f) =>\n            new(self.Match, e => self.Action(e).Map(f));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqArr.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Array equality\n/// </summary>\npublic struct EqArr<EqA, A> : Eq<Arr<A>> where EqA : Eq<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Arr<A> x, Arr<A> y)\n    {\n        if (x.Count != y.Count) return false;\n        var xiter = x.GetEnumerator();\n        var yiter = y.GetEnumerator();\n        while (xiter.MoveNext() && yiter.MoveNext())\n        {\n            if (!equals<EqA, A>(xiter.Current, yiter.Current)) return false;\n        }\n\n        return true;\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Arr<A> x) =>\n        HashableArr<A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Array equality\n/// </summary>\npublic struct EqArr<A> : Eq<Arr<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Arr<A> x, Arr<A> y) =>\n        EqArr<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Arr<A> x) =>\n        HashableArr<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqArray.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Array equality\n/// </summary>\npublic struct EqArray<EqA, A> : Eq<A[]> where EqA : Eq<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(A[] x, A[] y)\n    {\n        if (x.Length != y.Length) return false;\n        for (var i = 0; i < x.Length; i++)\n        {\n            if (!equals<EqA, A>(x[i], y[i])) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A[] x) =>\n        HashableArray<EqA, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Array equality\n/// </summary>\npublic struct EqArray<A> : Eq<A[]>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(A[] x, A[] y) =>\n        EqArray<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A[] x) =>\n        HashableArray<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqBigInt.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer equality\n/// </summary>\npublic struct EqBigInt : Eq<bigint>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(bigint a, bigint b) =>\n        a == b;\n\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(bigint x) =>\n        HashableBigInt.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqBool.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Boolean equality\n/// </summary>\npublic struct EqBool : Eq<bool>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(bool a, bool b)  => \n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(bool x) =>\n        HashableBool.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqChar.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Char equality\n/// </summary>\npublic struct EqChar : Eq<char>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(char a, char b) =>\n        a == b;\n\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(char x) =>\n        HashableChar.GetHashCode(x);\n}\n\n/// <summary>\n/// Char equality (ordinal, ignore case)\n/// </summary>\npublic struct EqCharOrdinalIgnoreCase : Eq<char>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    [Pure]\n    public static bool Equals(char a, char b)\n    {\n        if (a >= 'a' && a <= 'z') a = (char)(a - 0x20);\n        if (b >= 'a' && b <= 'z') b = (char)(b - 0x20);\n        return a == b;\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(char x) =>\n        HashableCharOrdinalIgnoreCase.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqCompositions.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct EqCompositions<A> : Eq<Compositions<A>>\n    where A : Monoid<A>\n{\n    [Pure]\n    public static bool Equals(Compositions<A> x, Compositions<A> y) =>\n        x == y;\n\n    [Pure]\n    public static int GetHashCode(Compositions<A> x) =>\n        HashableCompositions<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqDateTime.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// DateTime equality\n/// </summary>\npublic struct EqDateTime : Eq<DateTime>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(DateTime a, DateTime b)  => \n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(DateTime x) =>\n        HashableDateTime.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqDecimal.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Floating point equality\n/// </summary>\npublic struct EqDecimal : Eq<decimal>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(decimal a, decimal b) =>\n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(decimal x) =>\n        HashableDecimal.GetHashCode(x);\n\n    [Pure]\n    public static Task<bool> EqualsAsync(decimal x, decimal y) =>\n        Equals(x, y).AsTask();\n\n    [Pure]\n    public static Task<int> GetHashCodeAsync(decimal x) => \n        GetHashCode(x).AsTask();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqDefault.cs",
    "content": "﻿using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits.Resolve;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Finds an appropriate Eq from the loaded assemblies, if one can't be found then it\n/// falls back to the standard .NET EqualityComparer〈A〉.Default.Equals(a,b) method to\n/// provide equality testing.\n/// </summary>\npublic readonly struct EqDefault<A> : Eq<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(A a, A b)\n    {\n        if (a is null) return b is null;\n        if (b is null) return false;\n        if (ReferenceEquals(a, b)) return true;\n        return EqResolve<A>.Equals(a, b);\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A x) =>\n        HashableDefault<A>.GetHashCode(x);\n}\n\n/// <summary>\n/// This is a utility type for when two generic types are used, but it's not clear if they\n/// have the same underlying type.  We'd like to do structural equality if they are, and\n/// return false if they're not.\n/// </summary>\npublic static class EqDefault<A, B> \n{\n    static readonly Func<A, B, bool> Eq;\n\n    static EqDefault()\n    {\n        Eq = typeof(A).FullName == typeof(B).FullName\n                 ? (x, y) => y is A y1 && EqDefault<A>.Equals(x, y1)\n                 : (_, _) => false;\n    }\n        \n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(A a, B b)\n    {\n        if (isnull(a)) return isnull(b);\n        if (isnull(b)) return false;\n        if (ReferenceEquals(a, b)) return true;\n        return Eq(a, b);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqDouble.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances\n{\n    /// <summary>\n    /// Floating point equality\n    /// </summary>\n    public struct EqDouble : Eq<double>\n    {\n        /// <summary>\n        /// Equality test\n        /// </summary>\n        /// <param name=\"x\">The left hand side of the equality operation</param>\n        /// <param name=\"y\">The right hand side of the equality operation</param>\n        /// <returns>True if x and y are equal</returns>\n        [Pure]\n        public static bool Equals(double a, double b) =>\n            a.Equals(b);\n\n        /// <summary>\n        /// Get hash code of the value\n        /// </summary>\n        /// <param name=\"x\">Value to get the hash code of</param>\n        /// <returns>The hash code of x</returns>\n        [Pure]\n        public static int GetHashCode(double x) =>\n            HashableDouble.GetHashCode(x);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqEdit.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances\n{\n    /// <summary>\n    /// Equality instance for `Patch` `Edit`\n    /// </summary>\n    public struct EqEdit<EqA, A> : Eq<Edit<EqA, A>> where EqA : Eq<A>\n    {\n        [Pure]\n        public static bool Equals(Edit<EqA, A> x, Edit<EqA, A> y) => \n            x == y;\n\n        [Pure]\n        public static int GetHashCode(Edit<EqA, A> x) =>\n            HashableEdit<EqA, A>.GetHashCode(x);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqEither.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances\n{\n    /// <summary>\n    /// Either type hashing\n    /// </summary>\n    public struct EqEither<EqL, EqR, L, R> : Eq<Either<L, R>>\n        where EqL : Eq<L>\n        where EqR : Eq<R>\n    {\n        /// <summary>\n        /// Equality test\n        /// </summary>\n        [Pure]\n        public static bool Equals(Either<L, R> x, Either<L, R> y) =>\n            x.Equals<EqL, EqR>(y);\n\n\n        /// <summary>\n        /// Get hash code of the value\n        /// </summary>\n        /// <param name=\"x\">Value to get the hash code of</param>\n        /// <returns>The hash code of x</returns>\n        [Pure]\n        public static int GetHashCode(Either<L, R> x) => \n            HashableEither<EqL, EqR, L, R>.GetHashCode(x);\n\n        /// <summary>\n        /// Get hash code of the value\n        /// </summary>\n        /// <param name=\"x\">Value to get the hash code of</param>\n        /// <returns>The hash code of x</returns>\n        [Pure]\n        public static Task<int> GetHashCodeAsync(Either<L, R> x) =>\n            GetHashCode(x).AsTask();\n\n        /// <summary>\n        /// Equality test\n        /// </summary>\n        [Pure]\n        public static Task<bool> EqualsAsync(Either<L, R> x, Either<L, R> y) => \n            Equals(x, y).AsTask();\n    }\n    \n    /// <summary>\n    /// Either type hashing\n    /// </summary>\n    public struct EqEither<L, R> : Eq<Either<L, R>>\n    {\n        /// <summary>\n        /// Equality test\n        /// </summary>\n        [Pure]\n        public static bool Equals(Either<L, R> x, Either<L, R> y) => \n            EqEither<EqDefault<L>, EqDefault<R>, L, R>.Equals(x, y);\n        \n        /// <summary>\n        /// Get hash code of the value\n        /// </summary>\n        /// <param name=\"x\">Value to get the hash code of</param>\n        /// <returns>The hash code of x</returns>\n        [Pure] \n        public static int GetHashCode(Either<L, R> x) =>\n            HashableEither<HashableDefault<L>, HashableDefault<R>, L, R>.GetHashCode(x);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqEnumerable.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqEnumerable<EQ, A> : Eq<IEnumerable<A>>\n    where EQ : Eq<A>\n{\n    /// <summary>\n    /// Equality check\n    /// </summary>\n    [Pure]\n    public static bool Equals(IEnumerable<A> x, IEnumerable<A> y)\n    {\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n        while (true)\n        {\n            var a = enumx.MoveNext();\n            var b = enumy.MoveNext();\n            if (a != b) return false;\n            if (!a && !b) return true;\n            if (!EQ.Equals(enumx.Current, enumy.Current)) return false;\n        }\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(IEnumerable<A> x) =>\n        HashableEnumerable<EQ, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqEnumerable<A> : Eq<IEnumerable<A>>\n{\n    /// <summary>\n    /// Equality check\n    /// </summary>\n    [Pure]\n    public static bool Equals(IEnumerable<A> x, IEnumerable<A> y) =>\n        EqEnumerable<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(IEnumerable<A> x) =>\n        HashableEnumerable<A>.GetHashCode(x);\n}\n \n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqException.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct EqException : Eq<Exception>\n{\n    [Pure]\n    public static int GetHashCode(Exception x) =>\n        HashableException.GetHashCode(x);\n\n    [Pure]\n    public static bool Equals(Exception x, Exception y) =>\n        x.GetType() == y.GetType();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqFloat.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Floating point equality\n/// </summary>\npublic struct EqFloat : Eq<float>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(float a, float b) =>\n        a.Equals(b);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(float x) =>\n        HashableFloat.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqGuid.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Guid equality\n/// </summary>\npublic struct EqGuid : Eq<Guid>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Guid a, Guid b)  => \n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Guid x) =>\n        HashableGuid.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqHashSet.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// HashSet equality\n/// </summary>\npublic struct EqHashSet<EQ, A> : Eq<HashSet<A>> where EQ : Eq<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(HashSet<A> x, HashSet<A> y)\n    {\n        if (x.Count != y.Count) return false;\n\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n        for (var i = 0; i < x.Count; i++)\n        {\n            enumx.MoveNext();\n            enumy.MoveNext();\n            if (!EQ.Equals(enumx.Current, enumy.Current)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(HashSet<A> x) =>\n        HashableHashSet<EQ, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// HashSet equality\n/// </summary>\npublic struct EqHashSet<A> : Eq<HashSet<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(HashSet<A> x, HashSet<A> y) =>\n        EqHashSet<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(HashSet<A> x) =>\n        HashableHashSet<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqIdentity.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Identity equality\n/// </summary>\npublic struct EqIdentity<A> : Eq<Identity<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Identity<A> a, Identity<A> b)  => \n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Identity<A> x) =>\n        HashableIdentity<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqInt.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer equality\n/// </summary>\npublic struct EqInt : Eq<int>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(int a, int b)  => \n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(int x) =>\n        HashableInt.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqIterable.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqIterable<EQ, A> : Eq<Iterable<A>>\n    where EQ : Eq<A>\n{\n    /// <summary>\n    /// Equality check\n    /// </summary>\n    [Pure]\n    public static bool Equals(Iterable<A> x, Iterable<A> y)\n    {\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n        while (true)\n        {\n            var a = enumx.MoveNext();\n            var b = enumy.MoveNext();\n            if (a != b) return false;\n            if (!a && !b) return true;\n            if (!EQ.Equals(enumx.Current, enumy.Current)) return false;\n        }\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Iterable<A> x) =>\n        HashableIterable<EQ, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqIterable<A> : Eq<Iterable<A>>\n{\n    /// <summary>\n    /// Equality check\n    /// </summary>\n    [Pure]\n    public static bool Equals(Iterable<A> x, Iterable<A> y) =>\n        EqIterable<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Iterable<A> x) =>\n        HashableIterable<A>.GetHashCode(x);\n}\n \n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqLong.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer equality\n/// </summary>\npublic struct EqLong : Eq<long>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(long a, long b) =>\n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(long x) =>\n        HashableLong.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqLst.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqLst<EQ, A> : Eq<Lst<A>> where EQ : Eq<A>\n{\n    [Pure]\n    public static bool Equals(Lst<A> x, Lst<A> y)\n    {\n        if (x.Count != y.Count) return false;\n\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n        var count = x.Count;\n\n        for (var i = 0; i < count; i++)\n        {\n            enumx.MoveNext();\n            enumy.MoveNext();\n            if (!EQ.Equals(enumx.Current, enumy.Current)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Lst<A> x) =>\n        HashableLst<EQ, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqLst<A> : Eq<Lst<A>> \n{\n    [Pure]\n    public static bool Equals(Lst<A> x, Lst<A> y) =>\n        EqLst<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Lst<A> x) =>\n        HashableLst<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqMap.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct EqMap<K, V> : Eq<Map<K, V>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if `x` and `y` are equal</returns>\n    [Pure]\n    public static bool Equals(Map<K, V> x, Map<K, V> y) =>\n        x.Equals(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of `x`</returns>\n    [Pure]\n    public static int GetHashCode(Map<K, V> x) =>\n        HashableMap<K, V>.GetHashCode(x);\n}\n\npublic struct EqMap<OrdK, K, V> : Eq<Map<OrdK, K, V>>\n    where OrdK : Ord<K>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if `x` and `y` are equal</returns>\n    [Pure]\n    public static bool Equals(Map<OrdK, K, V> x, Map<OrdK, K, V> y) =>\n        x.Equals(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of `x`</returns>\n    [Pure]\n    public static int GetHashCode(Map<OrdK, K, V> x) =>\n        HashableMap<OrdK, K, V>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqOption.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Option type equality\n/// </summary>\npublic struct EqOption<A> : Eq<Option<A>>\n{\n    [Pure]\n    public static bool Equals(Option<A> x, Option<A> y) =>\n        x.Equals(y);\n\n    [Pure]\n    public static int GetHashCode(Option<A> x) =>\n        HashableOption<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqPatch.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality instance for `Patch`\n/// </summary>\npublic struct EqPatch<EqA, A> : Eq<Patch<EqA, A>> where EqA : Eq<A>\n{\n    [Pure]\n    public static bool Equals(Patch<EqA, A> x, Patch<EqA, A> y) => \n        x == y;\n\n    [Pure]\n    public static int GetHashCode(Patch<EqA, A> x) =>\n        HashablePatch<EqA, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqQue.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqQue<EQ, A> : Eq<Que<A>> where EQ : Eq<A>\n{\n    [Pure]\n    public static bool Equals(Que<A> x, Que<A> y)\n    {\n        if (x.Count != y.Count) return false;\n\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n        var count = x.Count;\n\n        for (var i = 0; i < count; i++)\n        {\n            enumx.MoveNext();\n            enumy.MoveNext();\n            if (!EQ.Equals(enumx.Current, enumy.Current)) return false;\n        }\n        return true;\n    }\n\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Que<A> x) =>\n        HashableQue<EQ, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqQue<A> : Eq<Que<A>>\n{\n    [Pure]\n    public static bool Equals(Que<A> x, Que<A> y) =>\n        EqQue<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Que<A> x) =>\n        HashableQue<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqRecord.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality class instance for all record types\n/// </summary>\n/// <typeparam name=\"A\">Record type</typeparam>\npublic struct EqRecord<A> : Eq<A> where A : Record<A>\n{\n    [Pure]\n    public static bool Equals(A x, A y) =>\n        RecordType<A>.EqualityTyped(x, y);\n\n    [Pure]\n    public static int GetHashCode(A x) =>\n        HashableRecord<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqSeq.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqSeq<EqA, A> : Eq<Seq<A>>\n    where EqA : Eq<A>\n{\n    /// <summary>\n    /// Equality check\n    /// </summary>\n    [Pure]\n    public static bool Equals(Seq<A> x, Seq<A> y)\n    {\n        if (x.Count != y.Count) return false;\n\n        while (true)\n        {\n            var a = x.IsEmpty;\n            var b = y.IsEmpty;\n            if (a != b) return false;\n            if (a && b) return true;\n\n            if (!EqA.Equals((A)x.Head,(A)y.Head)) return false;\n            x = x.Tail;\n            y = y.Tail;\n        }\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Seq<A> x) =>\n        HashableSeq<EqA, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqSeq<A> : Eq<Seq<A>>\n{\n    /// <summary>\n    /// Equality check\n    /// </summary>\n    [Pure]\n    public static bool Equals(Seq<A> x, Seq<A> y) =>\n        EqSeq<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Seq<A> x) =>\n        HashableSeq<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqSet.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Set〈T〉 equality\n/// </summary>\npublic struct EqSet<EQ, A> : Eq<Set<A>> where EQ : Eq<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Set<A> x, Set<A> y)\n    {\n        if (x.Count != y.Count) return false;\n\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n        for (var i = 0; i < x.Count; i++)\n        {\n            enumx.MoveNext();\n            enumy.MoveNext();\n            if (!EQ.Equals(enumx.Current, enumy.Current)) return false;\n        }\n        return true;\n    }\n\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Set<A> x) =>\n        HashableSet<EQ, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Set〈T〉 equality\n/// </summary>\npublic struct EqSet<A> : Eq<Set<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Set<A> x, Set<A> y) =>\n        EqSet<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Set<A> x) =>\n        HashableSet<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqShort.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer equality\n/// </summary>\npublic struct EqShort : Eq<short>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(short a, short b) =>\n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(short x) =>\n        HashableShort.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqStck.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqStck<EQ, A> : Eq<Stck<A>> where EQ : Eq<A>\n{\n    [Pure]\n    public static bool Equals(Stck<A> x, Stck<A> y)\n    {\n        if (x.Count != y.Count) return false;\n\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n        var count = x.Count;\n\n        for (var i = 0; i < count; i++)\n        {\n            enumx.MoveNext();\n            enumy.MoveNext();\n            if (!EQ.Equals(enumx.Current, enumy.Current)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Stck<A> x) =>\n        HashableStck<EQ, A>.GetHashCode(x);\n}\n\n/// <summary>\n/// Equality test\n/// </summary>\n/// <param name=\"x\">The left hand side of the equality operation</param>\n/// <param name=\"y\">The right hand side of the equality operation</param>\n/// <returns>True if x and y are equal</returns>\npublic struct EqStck<A> : Eq<Stck<A>>\n{\n    [Pure]\n    public static bool Equals(Stck<A> x, Stck<A> y) =>\n        EqStck<EqDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Stck<A> x) =>\n        HashableStck<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqString.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// String equality\n/// </summary>\npublic struct EqString : Eq<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    [Pure]\n    public static bool Equals(string a, string b) =>\n        a == b;\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        HashableString.GetHashCode(x);\n}\n    \n/// <summary>\n/// String equality (invariant culture)\n/// </summary>\npublic struct EqStringInvariantCulture : Eq<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    [Pure]\n    public static bool Equals(string a, string b) =>\n        StringComparer.InvariantCulture.Equals(a, b);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        HashableStringInvariantCulture.GetHashCode(x);\n}\n    \n/// <summary>\n/// String equality (invariant culture, ignore case)\n/// </summary>\npublic struct EqStringInvariantCultureIgnoreCase : Eq<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    [Pure]\n    public static bool Equals(string a, string b) =>\n        StringComparer.InvariantCultureIgnoreCase.Equals(a, b);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        HashableStringInvariantCultureIgnoreCase.GetHashCode(x);\n}\n\n/// <summary>\n/// String equality (ordinal, ignore case)\n/// </summary>\npublic struct EqStringOrdinalIgnoreCase : Eq<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    [Pure]\n    public static bool Equals(string a, string b) =>\n        StringComparer.OrdinalIgnoreCase.Equals(a, b);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        HashableStringOrdinalIgnoreCase.GetHashCode(x);\n}\n\n/// <summary>\n/// String equality (ordinal)\n/// </summary>\npublic struct EqStringOrdinal : Eq<string>\n{\n    public static readonly EqStringOrdinal Inst = default;\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    [Pure]\n    public static bool Equals(string a, string b) =>\n        StringComparer.Ordinal.Equals(a, b);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        HashableStringOrdinal.GetHashCode(x);\n}\n\n/// <summary>\n/// String equality (current culture, ignore case)\n/// </summary>\npublic struct EqStringCurrentCultureIgnoreCase : Eq<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    [Pure]\n    public static bool Equals(string a, string b) =>\n        StringComparer.CurrentCultureIgnoreCase.Equals(a, b);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        HashableStringCurrentCultureIgnoreCase.GetHashCode(x);\n}\n\n/// <summary>\n/// String equality (current culture)\n/// </summary>\npublic struct EqStringCurrentCulture : Eq<string>\n{\n    public static readonly EqStringCurrentCulture Inst = default;\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    [Pure]\n    public static bool Equals(string a, string b) =>\n        StringComparer.CurrentCulture.Equals(a, b);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        HashableStringCurrentCulture.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqTask.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct EqTask<A> : Eq<Task<A>>\n{\n    [Pure]\n    public static bool Equals(Task<A> x, Task<A> y) =>\n        x.Id == y.Id;\n\n    [Pure]\n    public static int GetHashCode(Task<A> x) =>\n        HashableTask<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqTrue.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Always returns true for equality checks\n/// </summary>\npublic struct EqTrue<A> : Eq<A>\n{\n    [Pure]\n    public static bool Equals(A x, A y) =>\n        true;\n\n    [Pure]\n    public static int GetHashCode(A x) =>\n        EqDefault<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqTuple2.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct EqTuple2<EqA, EqB, A, B> : Eq<(A, B)>\n    where EqA : Eq<A>\n    where EqB : Eq<B>\n{\n    public static int GetHashCode((A, B) pair) =>\n        FNV32.Next(EqA.GetHashCode(pair.Item1), \n                   EqB.GetHashCode(pair.Item2));\n\n    public static bool Equals((A, B) x, (A, B) y) =>\n        EqA.Equals(x.Item1, y.Item1) &&\n        EqB.Equals(x.Item2, y.Item2);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Eq/EqTypeInfo.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing System.Reflection;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct EqTypeInfo : Eq<TypeInfo>\n{\n    [Pure]\n    public static bool Equals(TypeInfo x, TypeInfo y) =>\n        x.Equals(y);\n\n    [Pure]\n    public static int GetHashCode(TypeInfo x) =>\n        HashableTypeInfo.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableArr.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Array hash\n/// </summary>\npublic struct HashableArr<HashA, A> : Hashable<Arr<A>> where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Arr<A> x) =>\n        hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Array hash\n/// </summary>\npublic struct HashableArr<A> : Hashable<Arr<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Arr<A> x) =>\n        HashableArr<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableArray.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Array hash\n/// </summary>\npublic struct HashableArray<HashA, A> : Hashable<A[]> where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A[] x) =>\n        hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Array hash\n/// </summary>\npublic struct HashableArray<A> : Hashable<A[]>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A[] x) =>\n        HashableArray<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableBigInt.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// bigint hash\n/// </summary>\npublic struct HashableBigInt : Hashable<bigint>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(bigint x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableBool.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Boolean hash\n/// </summary>\npublic struct HashableBool : Hashable<bool>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(bool x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableChar.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Char hash\n/// </summary>\npublic struct HashableChar : Hashable<char>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(char x) =>\n        x.GetHashCode();\n}\n\n/// <summary>\n/// Char hash (ordinal, ignore case)\n/// </summary>\npublic struct HashableCharOrdinalIgnoreCase : Hashable<char>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(char x) =>\n        x is >= 'a' and <= 'z' ? x - 0x20 : x;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableCompositions.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct HashableCompositions<A> : Hashable<Compositions<A>>\n    where A : Monoid<A>\n{\n    [Pure]\n    public static int GetHashCode(Compositions<A> x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableDateTime.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// DateTime hash\n/// </summary>\npublic struct HashableDateTime : Hashable<DateTime>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(DateTime x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableDecimal.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Floating point hash\n/// </summary>\npublic struct HashableDecimal : Hashable<decimal>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(decimal x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableDefault.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits.Resolve;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Finds an appropriate Hashable from the loaded assemblies, if one can't be found then it\n/// falls back to the standard .NET Object.GetHashCode() method to provide a hash-code.\n/// </summary>\npublic struct HashableDefault<A> : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A x) =>\n        HashableResolve<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableDouble.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Floating point hash\n/// </summary>\npublic struct HashableDouble : Hashable<double>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(double x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableEdit.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Hash for `Patch` `Edit`\n/// </summary>\npublic struct HashableEdit<EqA, A> : Hashable<Edit<EqA, A>> where EqA : Eq<A>\n{\n    [Pure]\n    public static int GetHashCode(Edit<EqA, A> x) => \n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableEither.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Either type hashing\n/// </summary>\npublic readonly struct HashableEither<HashableL, HashableR, L, R> : Hashable<Either<L, R>>\n    where HashableL : Hashable<L>\n    where HashableR : Hashable<R>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Either<L, R> x) =>\n        x switch\n        {\n            Either<L, R>.Right => HashableR.GetHashCode(x.RightValue),\n            Either<L, R>.Left  => HashableL.GetHashCode(x.LeftValue),\n            _                  => 0\n        };\n}\n    \n/// <summary>\n/// Either type hashing\n/// </summary>\npublic readonly struct HashableEither<L, R> : Hashable<Either<L, R>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure] \n    public static int GetHashCode(Either<L, R> x) =>\n        HashableEither<HashableDefault<L>, HashableDefault<R>, L, R>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableEnumerable.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Enumerable hashing\n/// </summary>\npublic struct HashableEnumerable<HashA, A> : Hashable<IEnumerable<A>>\n    where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(IEnumerable<A> x) =>\n        hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Enumerable hashing\n/// </summary>\npublic struct HashableEnumerable<A> : Hashable<IEnumerable<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(IEnumerable<A> x) =>\n        HashableEnumerable<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableException.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct HashableException : Hashable<Exception>\n{\n    [Pure]\n    public static int GetHashCode(Exception x) =>\n        x.GetType().GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableFloat.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Floating point hash\n/// </summary>\npublic struct HashableFloat : Hashable<float>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(float x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableGuid.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Guid hash\n/// </summary>\npublic struct HashableGuid : Hashable<Guid>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Guid x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableHashSet.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// HashSet hash\n/// </summary>\npublic struct HashableHashSet<HashA, A> : Hashable<HashSet<A>> where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(HashSet<A> x) =>\n        hash<HashA, A>(x);\n}\n\n/// <summary>\n/// HashSet hash\n/// </summary>\npublic struct HashableHashSet<A> : Hashable<HashSet<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(HashSet<A> x) =>\n        HashableHashSet<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableIdentity.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Identity hashing\n/// </summary>\npublic struct HashableIdentity<A> : Hashable<Identity<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Identity<A> x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableInt.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer hash\n/// </summary>\npublic struct HashableInt : Hashable<int>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(int x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableIterable.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Iterable hashing\n/// </summary>\npublic struct HashableIterable<HashA, A> : Hashable<Iterable<A>>\n    where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Iterable<A> x) =>\n        hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Iterable hashing\n/// </summary>\npublic struct HashableIterable<A> : Hashable<Iterable<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Iterable<A> x) =>\n        HashableIterable<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableLong.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer hash\n/// </summary>\npublic struct HashableLong : Hashable<long>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(long x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableLst.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Lst hash\n/// </summary>\npublic struct HashableLst<HashA, A> : Hashable<Lst<A>> where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Lst<A> x) =>\n        hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Lst hash\n/// </summary>\npublic struct HashableLst<A> : Hashable<Lst<A>> \n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Lst<A> x) =>\n        HashableLst<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableMap.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct HashableMap<K, V> : Hashable<Map<K, V>>\n{\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of `x`</returns>\n    [Pure]\n    public static int GetHashCode(Map<K, V> x) =>\n        x.GetHashCode();\n}\n\npublic struct HashableMap<OrdK, K, V> : Hashable<Map<OrdK, K, V>>\n    where OrdK : Ord<K>\n{\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of `x`</returns>\n    [Pure]\n    public static int GetHashCode(Map<OrdK, K, V> x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableOption.cs",
    "content": "﻿namespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Option type equality\n/// </summary>\npublic struct HashableOption<A> : Hashable<Option<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    public static int GetHashCode(Option<A> x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashablePair.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic struct HashablePair<HashA, HashB, A, B> : Hashable<(A, B)>\n    where HashA : Hashable<A>\n    where HashB : Hashable<B>\n{\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode((A, B) pair) =>\n        (HashB.GetHashCode(pair.Item2) ^ \n         (HashA.GetHashCode(pair.Item1) ^ FNV32.OffsetBasis) * FNV32.Prime) * FNV32.Prime;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashablePatch.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Hash for `Patch`\n/// </summary>\npublic struct HashablePatch<EqA, A> : Hashable<Patch<EqA, A>> where EqA : Eq<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(Patch<EqA, A> x) => \n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableQue.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Queue hashing\n/// </summary>\npublic struct HashableQue<HashA, A> : Hashable<Que<A>> where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Que<A> x) =>\n        Prelude.hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Queue hashing\n/// </summary>\npublic struct HashableQue<A> : Hashable<Que<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Que<A> x) =>\n        HashableQue<EqDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableRecord.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Hash for all record types\n/// </summary>\n/// <typeparam name=\"A\">Record type</typeparam>\npublic struct HashableRecord<A> : Hashable<A> where A : Record<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(A x) =>\n        RecordType<A>.Hash(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableSeq.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Seq hashing\n/// </summary>\npublic struct HashableSeq<HashA, A> : Hashable<Seq<A>>\n    where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Seq<A> x) =>\n        hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Seq hashing\n/// </summary>\npublic struct HashableSeq<A> : Hashable<Seq<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Seq<A> x) =>\n        HashableSeq<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableSet.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Set〈T〉 hashing\n/// </summary>\npublic struct HashableSet<HashA, A> : Hashable<Set<A>> where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Set<A> x) =>\n        Prelude.hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Set〈T〉 hashing\n/// </summary>\npublic struct HashableSet<A> : Hashable<Set<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Set<A> x) =>\n        HashableSet<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableShort.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer hashing\n/// </summary>\npublic struct HashableShort : Hashable<short>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(short x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableStck.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Stack hashing\n/// </summary>\npublic struct HashableStck<HashA, A> : Hashable<Stck<A>> where HashA : Hashable<A>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Stck<A> x) =>\n        Prelude.hash<HashA, A>(x);\n}\n\n/// <summary>\n/// Stack hashing\n/// </summary>\npublic struct HashableStck<A> : Hashable<Stck<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Stck<A> x) =>\n        HashableStck<HashableDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableString.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// String hashing\n/// </summary>\npublic struct HashableString : Hashable<string>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(string x) =>\n        x == null ? 0 : x.GetHashCode();\n}\n    \n/// <summary>\n/// String hashing (invariant culture)\n/// </summary>\npublic struct HashableStringInvariantCulture : Hashable<string>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(string x) =>\n        StringComparer.InvariantCulture.GetHashCode(x);\n}\n    \n        \n/// <summary>\n/// String hashing (invariant culture, ignore case)\n/// </summary>\npublic struct HashableStringInvariantCultureIgnoreCase : Hashable<string>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(string x) =>\n        x.IsNull() ? 0 : StringComparer.InvariantCultureIgnoreCase.GetHashCode(x);\n}\n\n/// <summary>\n/// String equality (ordinal, ignore case)\n/// </summary>\npublic struct HashableStringOrdinalIgnoreCase : Hashable<string>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(string x) =>\n        x.IsNull() ? 0 : StringComparer.OrdinalIgnoreCase.GetHashCode(x);\n}\n\n/// <summary>\n/// String equality (ordinal)\n/// </summary>\npublic struct HashableStringOrdinal : Hashable<string>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(string x) =>\n        x.IsNull() ? 0 : StringComparer.Ordinal.GetHashCode(x);\n}\n\n/// <summary>\n/// String equality (current culture, ignore case)\n/// </summary>\npublic struct HashableStringCurrentCultureIgnoreCase : Hashable<string>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(string x) =>\n        x.IsNull() ? 0 : StringComparer.CurrentCultureIgnoreCase.GetHashCode(x);\n}\n\n/// <summary>\n/// String equality (current culture)\n/// </summary>\npublic struct HashableStringCurrentCulture : Hashable<string>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(string x) =>\n        x.IsNull() ? 0 : StringComparer.CurrentCulture.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableTask.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct HashableTask<A> : Hashable<Task<A>>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(Task<A> x) =>\n        x.Id.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableTuple.cs",
    "content": "namespace LanguageExt.ClassInstances;\n\npublic struct HashableTuple<HashA, HashB, A, B> : Hashable<(A, B)>\n    where HashA : Hashable<A>\n    where HashB : Hashable<B>\n{\n    public static int GetHashCode((A, B) pair) =>\n        FNV32.Next(HashA.GetHashCode(pair.Item1), \n                   HashB.GetHashCode(pair.Item2));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Hashable/HashableTypeInfo.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct HashableTypeInfo : Hashable<TypeInfo>\n{\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int GetHashCode(TypeInfo x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Monoid/Addition.cs",
    "content": "﻿/*\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Trait;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Numbers form a monoid under addition.\n/// </summary>\n/// <typeparam name=\"A\">The type of the number being added.</typeparam>\npublic struct Addition<NUM, A> : Monoid<A> where NUM : Num<A>\n{\n    [Pure]\n    public static A Append(A x, A y) =>\n        plus<NUM, A>(x, y);\n\n    [Pure]\n    public static A Empty =>\n        fromInteger<NUM, A>(0);\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Monoid/All.cs",
    "content": "﻿/*\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Booleans form a monoid under disjunctions.\n/// </summary>\npublic struct All : Monoid<bool>, Bool<bool>\n{\n    [Pure]\n    public static bool Append(bool x, bool y) => x && y;\n\n    [Pure]\n    public static bool Empty => true;\n\n    [Pure]\n    public static bool And(bool a, bool b) =>\n        TBool.And(a, b);\n\n    [Pure]\n    public static bool BiCondition(bool a, bool b) =>\n        TBool.BiCondition(a, b);\n\n    [Pure]\n    public static bool False() => false;\n\n    [Pure]\n    public static bool Implies(bool a, bool b) =>\n        TBool.Implies(a, b);\n\n    [Pure]\n    public static bool Not(bool a) =>\n        TBool.Not(a);\n\n    [Pure]\n    public static bool Or(bool a, bool b) =>\n        TBool.Or(a, b);\n\n    [Pure]\n    public static bool True() =>\n        true;\n\n    [Pure]\n    public static bool XOr(bool a, bool b) =>\n        TBool.XOr(a, b);\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Monoid/Any.cs",
    "content": "﻿/*\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Booleans form a monoid under conjunction.\n/// </summary>\npublic struct Any : Monoid<bool>, Bool<bool>\n{\n    [Pure]\n    public static bool Append(bool x, bool y) => x || y;\n\n    [Pure]\n    public static bool Empty => false;\n\n    [Pure]\n    public static bool And(bool a, bool b) =>\n        TBool.And(a, b);\n\n    [Pure]\n    public static bool BiCondition(bool a, bool b) =>\n        TBool.BiCondition(a, b);\n\n    [Pure]\n    public static bool False() => false;\n\n    [Pure]\n    public static bool Implies(bool a, bool b) =>\n        TBool.Implies(a, b);\n\n    [Pure]\n    public static bool Not(bool a) =>\n        TBool.Not(a);\n\n    [Pure]\n    public static bool Or(bool a, bool b) =>\n        TBool.Or(a, b);\n\n    [Pure]\n    public static bool True() =>\n        true;\n\n    [Pure]\n    public static bool XOr(bool a, bool b) =>\n        TBool.XOr(a, b);\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Monoid/MError.cs",
    "content": "﻿/*\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Error monoid\n/// </summary>\npublic readonly struct MError : Monoid<Error>\n{\n    [Pure]\n    public static Error Append(Error x, Error y) => x + y;\n\n    [Pure]\n    public static Error Empty => Errors.None;\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Monoid/MUnit.cs",
    "content": "﻿/*\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct MUnit : Monoid<Unit>\n{\n    public static Unit Append(Unit x, Unit y) =>\n        unit;\n\n    public static Unit Empty =>\n        unit;\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Monoid/Product.cs",
    "content": "﻿/*\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Trait;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Numbers form a monoid under addition.\n/// </summary>\n/// <typeparam name=\"A\">The type of the number being added.</typeparam>\npublic struct Product<NUM, A> : Monoid<A> where NUM : Num<A>\n{\n    public static readonly Product<NUM, A> Inst = default;\n\n    [Pure]\n    public static A Append(A x, A y) =>\n        product<NUM, A>(x, y);\n\n    [Pure]\n    public static A Empty =>\n        fromInteger<NUM, A>(1);\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdArr.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdArr<OrdA, A> : Ord<Arr<A>>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Arr<A> x, Arr<A> y) =>\n        EqArr<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Arr<A> mx, Arr<A> my)\n    {\n        var cmp = mx.Count.CompareTo(my.Count);\n        if (cmp == 0)\n        {\n            var xiter = mx.GetEnumerator();\n            var yiter = my.GetEnumerator();\n            while(xiter.MoveNext() && yiter.MoveNext())\n            {\n                cmp = OrdA.Compare(xiter.Current, yiter.Current);\n                if (cmp != 0) return cmp;\n            }\n            return 0;\n        }\n        else\n        {\n            return cmp;\n        }\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Arr<A> x) =>\n        x.GetHashCode();\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdArr<A> : Ord<Arr<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Arr<A> x, Arr<A> y) =>\n        EqArr<A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Arr<A> mx, Arr<A> my) =>\n        OrdArr<OrdDefault<A>, A>.Compare(mx, my);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Arr<A> x) =>\n        OrdArr<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdArray.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdArray<OrdA, A> : Ord<A[]>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(A[] x, A[] y) =>\n        EqArray<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(A[] mx, A[] my)\n    {\n        if (ReferenceEquals(mx, my)) return 0;\n        if (ReferenceEquals(mx, null)) return -1;\n        if (ReferenceEquals(my, null)) return 1;\n\n        var cmp = mx.Length.CompareTo(my.Length);\n        if (cmp == 0)\n        {\n            for(var i = 0; i < mx.Length; i++)\n            {\n                cmp = OrdA.Compare(mx[i], my[i]);\n                if (cmp != 0) return cmp;\n            }\n            return 0;\n        }\n        else\n        {\n            return cmp;\n        }\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A[] x) =>\n        hash(x);\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdArray<A> : Ord<A[]>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(A[] x, A[] y) =>\n        EqArray<A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(A[] mx, A[] my) =>\n        OrdArray<OrdDefault<A>, A>.Compare(mx, my);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A[] x) =>\n        OrdArray<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdBigInt.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdBigInt : Ord<bigint>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(bigint x, bigint y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(bigint x, bigint y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(bigint x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdBool.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdBool : Ord<bool>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(bool x, bool y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(bool x, bool y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(bool x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdChar.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdChar : Ord<char>\n{\n    public static readonly OrdChar Inst = default(OrdChar);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(char x, char y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(char x, char y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(char x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdDateTime.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdDateTime : Ord<DateTime>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(DateTime x, DateTime y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(DateTime x, DateTime y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(DateTime x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdDecimal.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdDecimal : Ord<decimal>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(decimal x, decimal y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(decimal x, decimal y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(decimal x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdDefault.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits.Resolve;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Uses the standard .NET  Comparer〈A〉.Default.Compare(a,b) method to\n/// provide equality testing.\n/// </summary>\npublic struct OrdDefault<A> : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static int Compare(A x, A y) =>\n        OrdResolve<A>.Compare(x, y);\n\n    [Pure]\n    public static bool Equals(A x, A y) =>\n        EqDefault<A>.Equals(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(A x) =>\n        EqDefault<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdDouble.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdDouble : Ord<double>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(double x, double y) =>\n        x.Equals(y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(double x, double y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(double x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdEither.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Either type hashing\n/// </summary>\npublic struct OrdEither<OrdL, OrdR, L, R> : Ord<Either<L, R>>\n    where OrdL : Ord<L>\n    where OrdR : Ord<R>\n{\n    /// <summary>\n    /// Ordering test\n    /// </summary>\n    [Pure]\n    public static int Compare(Either<L, R> x, Either<L, R> y) =>\n        x.CompareTo<OrdL, OrdR>(y);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public static bool Equals(Either<L, R> x, Either<L, R> y) =>\n        EqEither<OrdL, OrdR, L, R>.Equals(x, y);\n\n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Either<L, R> x) => \n        HashableEither<OrdL, OrdR, L, R>.GetHashCode(x);\n}\n    \n/// <summary>\n/// Either type hashing\n/// </summary>\npublic struct OrdEither<L, R> : Ord<Either<L, R>>\n{\n    /// <summary>\n    /// Ordering test\n    /// </summary>\n    [Pure]\n    public static int Compare(Either<L, R> x, Either<L, R> y) => \n        OrdEither<OrdDefault<L>, OrdDefault<R>, L, R>.Compare(x, y);\n \n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public static bool Equals(Either<L, R> x, Either<L, R> y) => \n        EqEither<EqDefault<L>, EqDefault<R>, L, R>.Equals(x, y);\n        \n    /// <summary>\n    /// Get hash code of the value\n    /// </summary>\n    /// <param name=\"x\">Value to get the hash code of</param>\n    /// <returns>The hash code of x</returns>\n    [Pure] \n    public static int GetHashCode(Either<L, R> x) =>\n        HashableEither<HashableDefault<L>, HashableDefault<R>, L, R>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdEnumerable.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdEnumerable<OrdA, A> : Ord<IEnumerable<A>>\n    where OrdA : Ord<A>\n{\n    public static readonly OrdEnumerable<OrdA, A> Inst = default(OrdEnumerable<OrdA, A>);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(IEnumerable<A> x, IEnumerable<A> y) =>\n        EqEnumerable<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(IEnumerable<A> x, IEnumerable<A> y)\n    {\n        if (ReferenceEquals(x, y)) return 0;\n        if (ReferenceEquals(x, null)) return -1;\n        if (ReferenceEquals(y, null)) return 1;\n\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n\n        while (true)\n        {\n            bool r1 = enumx.MoveNext();\n            bool r2 = enumy.MoveNext();\n            if (!r1 && !r2) return 0;\n            if (!r1) return -1;\n            if (!r2) return 1;\n\n            var cmp = OrdA.Compare(enumx.Current, enumy.Current);\n            if (cmp != 0) return cmp;\n        }\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(IEnumerable<A> x) =>\n        hash(x);\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdEnumerable<A> : Ord<IEnumerable<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(IEnumerable<A> x, IEnumerable<A> y) =>\n        OrdEnumerable<OrdDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(IEnumerable<A> x, IEnumerable<A> y) =>\n        OrdEnumerable<OrdDefault<A>, A>.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(IEnumerable<A> x) =>\n        OrdEnumerable<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdException.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct OrdException : Ord<Exception>\n{\n    [Pure]\n    public static int GetHashCode(Exception x) =>\n        HashableException.GetHashCode(x);\n\n    [Pure]\n    public static bool Equals(Exception x, Exception y) =>\n        EqException.Equals(x, y);\n\n    [Pure]\n    public static int Compare(Exception x, Exception y)\n    {\n        if (ReferenceEquals(x, y)) return 0;\n        if (ReferenceEquals(x, null)) return -1;\n        if (ReferenceEquals(y, null)) return 1;\n        return string.Compare(x.GetType().FullName, y.Message.GetType().FullName, StringComparison.Ordinal);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdFloat.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdFloat : Ord<float>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(float x, float y) =>\n        x.Equals(y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(float x, float y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(float x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdGuid.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdGuid : Ord<Guid>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Guid x, Guid y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Guid x, Guid y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Guid x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdHashSet.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdHashSet<OrdA, A> : Ord<HashSet<A>>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(HashSet<A> x, HashSet<A> y) =>\n        EqHashSet<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(HashSet<A> x, HashSet<A> y)\n    {\n        if (x.Count > y.Count) return 1;\n        if (x.Count < y.Count) return -1;\n        var       sa    = toSet(x);\n        var       sb    = toSet(y);\n        using var iterA = sa.GetEnumerator();\n        using var iterB = sb.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            var cmp = OrdA.Compare(iterA.Current, iterB.Current);\n            if (cmp != 0) return cmp;\n        }\n\n        return 0;\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(HashSet<A> x) =>\n        x.GetHashCode();\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdHashSet<A> : Ord<HashSet<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(HashSet<A> x, HashSet<A> y) =>\n        OrdHashSet<OrdDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(HashSet<A> x, HashSet<A> y) =>\n        OrdHashSet<OrdDefault<A>, A>.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(HashSet<A> x) =>\n        OrdHashSet<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdInt.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdInt : Ord<int>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(int x, int y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(int x, int y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(int x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdIterable.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdIterable<OrdA, A> : Ord<Iterable<A>>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Iterable<A> x, Iterable<A> y) =>\n        EqIterable<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Iterable<A> x, Iterable<A> y)\n    {\n        if (ReferenceEquals(x, y)) return 0;\n        if (ReferenceEquals(x, null)) return -1;\n        if (ReferenceEquals(y, null)) return 1;\n\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n\n        while (true)\n        {\n            bool r1 = enumx.MoveNext();\n            bool r2 = enumy.MoveNext();\n            if (!r1 && !r2) return 0;\n            if (!r1) return -1;\n            if (!r2) return 1;\n\n            var cmp = OrdA.Compare(enumx.Current, enumy.Current);\n            if (cmp != 0) return cmp;\n        }\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Iterable<A> x) =>\n        hash(x);\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdIterable<A> : Ord<Iterable<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Iterable<A> x, Iterable<A> y) =>\n        OrdIterable<OrdDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Iterable<A> x, Iterable<A> y) =>\n        OrdIterable<OrdDefault<A>, A>.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Iterable<A> x) =>\n        OrdIterable<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdLong.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdLong : Ord<long>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(long x, long y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(long x, long y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(long x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdLst.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdLst<OrdA, A> : Ord<Lst<A>>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Lst<A> x, Lst<A> y) =>\n        EqLst<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Lst<A> mx, Lst<A> my)\n    {\n        var cmp = mx.Count.CompareTo(my.Count);\n        if (cmp == 0)\n        {\n            using var xiter = mx.GetEnumerator();\n            using var yiter = my.GetEnumerator();\n            while (xiter.MoveNext() && yiter.MoveNext())\n            {\n                cmp = OrdA.Compare(xiter.Current, yiter.Current);\n                if (cmp != 0) return cmp;\n            }\n            return 0;\n        }\n        else\n        {\n            return cmp;\n        }\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Lst<A> x) =>\n        x.GetHashCode();\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdLst<A> : Ord<Lst<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Lst<A> x, Lst<A> y) =>\n        OrdLst<OrdDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Lst<A> x, Lst<A> y) =>\n        OrdLst<OrdDefault<A>, A>.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Lst<A> x) =>\n        OrdLst<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdMap.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdMap<OrdK, K, V> : Ord<Map<OrdK, K, V>>\n    where OrdK : Ord<K>\n{\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if `x` greater than `y` : `1`\n    /// if `x` less than `y`    : `-1`\n    /// if `x` equals `y`       : `0`\n    /// </returns>\n    [Pure]\n    public static int Compare(Map<OrdK, K, V> x, Map<OrdK, K, V> y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if `x` and `y` are equal</returns>\n    [Pure]\n    public static bool Equals(Map<OrdK, K, V> x, Map<OrdK, K, V> y) =>\n        x.Equals(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of `x`</returns>\n    [Pure]\n    public static int GetHashCode(Map<OrdK, K, V> x) =>\n        x.GetHashCode();\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdMap<K, V> : Ord<Map<K, V>>\n{\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if `x` greater than `y` : `1`\n    /// if `x` less than `y`    : `-1`\n    /// if `x` equals `y`       : `0`\n    /// </returns>\n    [Pure]\n    public static int Compare(Map<K, V> x, Map<K, V> y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if `x` and `y` are equal</returns>\n    [Pure]\n    public static bool Equals(Map<K, V> x, Map<K, V> y) =>\n        x.Equals(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of `x`</returns>\n    [Pure]\n    public static int GetHashCode(Map<K, V> x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdOption.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct OrdOption<OrdA, A> : Ord<Option<A>>\n    where OrdA : Ord<A>\n{\n    [Pure]\n    public static int Compare(Option<A> x, Option<A> y) =>\n        x.CompareTo<OrdA>(y);\n\n    [Pure]\n    public static bool Equals(Option<A> x, Option<A> y) =>\n        x.Equals<OrdA>(y);\n\n    [Pure]\n    public static int GetHashCode(Option<A> x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdQue.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdQue<OrdA, A> : Ord<Que<A>>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Que<A> x, Que<A> y) =>\n        EqQue<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Que<A> x, Que<A> y)\n    {\n        var cmp = x.Count.CompareTo(y.Count);\n        if (cmp == 0)\n        {\n            using var enumx = x.GetEnumerator();\n            using var enumy = y.GetEnumerator();\n            var count = x.Count;\n\n            for (var i = 0; i < count; i++)\n            {\n                enumx.MoveNext();\n                enumy.MoveNext();\n                cmp = OrdA.Compare(enumx.Current, enumy.Current);\n                if (cmp != 0) return cmp;\n            }\n            return 0;\n        }\n        else\n        {\n            return cmp;\n        }\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Que<A> x) =>\n        x.GetHashCode();\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdQue<A> : Ord<Que<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Que<A> x, Que<A> y) =>\n        OrdQue<OrdDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Que<A> x, Que<A> y) =>\n        OrdQue<OrdDefault<A>, A>.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Que<A> x) =>\n        OrdQue<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdRecord.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Ordering class instance for all record types\n/// </summary>\n/// <typeparam name=\"A\">Record type</typeparam>\npublic struct OrdRecord<A> : Ord<A> where A : Record<A>\n{\n    [Pure]\n    public static int Compare(A x, A y) =>\n        RecordType<A>.Compare(x, y);\n\n    [Pure]\n    public static bool Equals(A x, A y) =>\n        RecordType<A>.EqualityTyped(x, y);\n\n    [Pure]\n    public static int GetHashCode(A x) =>\n        RecordType<A>.Hash(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdSeq.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdSeq<OrdA, A> : Ord<Seq<A>>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Seq<A> x, Seq<A> y) =>\n        EqSeq<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Seq<A> x, Seq<A> y)\n    {\n        using var enumx = x.GetEnumerator();\n        using var enumy = y.GetEnumerator();\n\n        while(true)\n        {\n            var r1 = enumx.MoveNext();\n            var r2 = enumy.MoveNext();\n            if (!r1 && !r2) return 0;\n            if (!r1) return -1;\n            if (!r2) return 1;\n\n            var cmp = OrdA.Compare(enumx.Current, enumy.Current);\n            if (cmp != 0) return cmp;\n        }\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Seq<A> x) =>\n        hash(x);\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdSeq<A> : Ord<Seq<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Seq<A> x, Seq<A> y) =>\n        OrdSeq<OrdDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Seq<A> x, Seq<A> y) =>\n        OrdSeq<OrdDefault<A>, A>.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Seq<A> x) =>\n        OrdSeq<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdSet.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdSet<OrdA, A> : Ord<Set<A>>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Set<A> x, Set<A> y) =>\n        EqSet<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Set<A> x, Set<A> y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Set<A> x) =>\n        x.GetHashCode();\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdSet<A> : Ord<Set<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Set<A> x, Set<A> y) =>\n        OrdSet<OrdDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Set<A> x, Set<A> y) =>\n        OrdSet<OrdDefault<A>, A>.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Set<A> x) =>\n        OrdSet<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdShort.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdShort : Ord<short>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(short x, short y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(short x, short y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(short x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdStck.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdStck<OrdA, A> : Ord<Stck<A>>\n    where OrdA : Ord<A>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Stck<A> x, Stck<A> y) =>\n        EqStck<OrdA, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Stck<A> x, Stck<A> y)\n    {\n        var cmp = x.Count.CompareTo(y.Count);\n        if (cmp == 0)\n        {\n            using var enumx = x.GetEnumerator();\n            using var enumy = y.GetEnumerator();\n            var count = x.Count;\n\n            for (int i = 0; i < count; i++)\n            {\n                enumx.MoveNext();\n                enumy.MoveNext();\n                cmp = OrdA.Compare(enumx.Current, enumy.Current);\n                if (cmp != 0) return cmp;\n            }\n            return 0;\n        }\n        else\n        {\n            return cmp;\n        }\n    }\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Stck<A> x) =>\n        x.GetHashCode();\n}\n\n/// <summary>\n/// Equality and ordering\n/// </summary>\npublic struct OrdStck<A> : Ord<Stck<A>>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(Stck<A> x, Stck<A> y) =>\n        OrdStck<OrdDefault<A>, A>.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// if x less than y    : -1\n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(Stck<A> x, Stck<A> y) =>\n        OrdStck<OrdDefault<A>, A>.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(Stck<A> x) =>\n        OrdStck<OrdDefault<A>, A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdString.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// String comparison\n/// </summary>\npublic struct OrdString : Ord<string>\n{\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if a greater than b : 1\n    /// if a less than b    : -1\n    /// if a equals b       : 0\n    /// </returns>\n    public static int Compare(string a, string b) =>\n        a?.CompareTo(b) ?? 1;\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    public static bool Equals(string a, string b) =>\n        EqString.Equals(a, b);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    public static int GetHashCode(string x) =>\n        HashableString.GetHashCode(x);\n}\n\n/// <summary>\n/// String comparison (ordinal, ignore case)\n/// </summary>\npublic struct OrdStringOrdinalIgnoreCase : Ord<string>\n{\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if a greater than b : 1\n    /// if a less than b    : -1\n    /// if a equals b       : 0\n    /// </returns>\n    public static int Compare(string a, string b) =>\n        StringComparer.OrdinalIgnoreCase.Compare(a, b);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    public static bool Equals(string a, string b) =>\n        EqStringOrdinalIgnoreCase.Equals(a, b);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    public static int GetHashCode(string x) =>\n        HashableStringOrdinalIgnoreCase.GetHashCode(x);\n}\n\n/// <summary>\n/// String comparison (ordinal)\n/// </summary>\npublic struct OrdStringOrdinal : Ord<string>\n{\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if a greater than b : 1\n    /// if a less than b    : -1\n    /// if a equals b       : 0\n    /// </returns>\n    public static int Compare(string a, string b) =>\n        StringComparer.Ordinal.Compare(a, b);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    public static bool Equals(string a, string b) =>\n        EqStringOrdinal.Equals(a, b);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    public static int GetHashCode(string x) =>\n        HashableStringOrdinal.GetHashCode(x);\n}\n\n/// <summary>\n/// String comparison (current culture, ignore case)\n/// </summary>\npublic struct OrdStringCurrentCultureIgnoreCase : Ord<string>\n{\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if a greater than b : 1\n    /// if a less than b    : -1\n    /// if a equals b       : 0\n    /// </returns>\n    public static int Compare(string a, string b) =>\n        StringComparer.CurrentCultureIgnoreCase.Compare(a, b);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    public static bool Equals(string a, string b) =>\n        EqStringCurrentCultureIgnoreCase.Equals(a, b);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    public static int GetHashCode(string x) =>\n        HashableStringCurrentCultureIgnoreCase.GetHashCode(x);\n}\n\n/// <summary>\n/// String comparison (current culture)\n/// </summary>\npublic struct OrdStringCurrentCulture : Ord<string>\n{\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if a greater than b : 1\n    /// if a less than b    : -1\n    /// if a equals b       : 0\n    /// </returns>\n    public static int Compare(string a, string b) =>\n        StringComparer.CurrentCulture.Compare(a, b);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"a\">The left hand side of the equality operation</param>\n    /// <param name=\"b\">The right hand side of the equality operation</param>\n    /// <returns>True if a and b are equal</returns>\n    public static bool Equals(string a, string b) =>\n        EqStringCurrentCulture.Equals(a, b);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    public static int GetHashCode(string x) =>\n        HashableStringCurrentCulture.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdTask.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct OrdTask<A> : Ord<Task<A>>\n{\n    public static int Compare(Task<A> x, Task<A> y) =>\n        x.Id.CompareTo(y.Id);\n\n    public static bool Equals(Task<A> x, Task<A> y) =>\n        EqTask<A>.Equals(x, y);\n\n    public static int GetHashCode(Task<A> x) =>\n        HashableTask<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdTrue.cs",
    "content": "﻿using LanguageExt.Traits;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Always returns true for equality checks and 0 for ordering\n/// </summary>\npublic struct OrdTrue<A> : Ord<A>\n{\n    public static int Compare(A x, A y) =>\n        0;\n\n    public static bool Equals(A x, A y) =>\n        true;\n\n    public static int GetHashCode(A x) =>\n        OrdDefault<A>.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdTupleFirst.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Ord instance for a pair tuple.  It orders using the first\n/// item in the tuple only and the provided OrdA.\n/// </summary>\npublic struct OrdTupleFirst<OrdA, A, B> : Ord<ValueTuple<A, B>> where OrdA : Ord<A>\n{\n    public static int Compare((A, B) x, (A, B) y) =>\n        OrdA.Compare(x.Item1, y.Item1);\n\n    public static bool Equals((A, B) x, (A, B) y) =>\n        OrdA.Equals(x.Item1, y.Item1);\n\n    public static int GetHashCode((A, B) x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/Ord/OrdTypeInfo.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Reflection;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct OrdTypeInfo : Ord<TypeInfo>\n{\n    public static int Compare(TypeInfo x, TypeInfo y) =>\n        string.Compare(x.ToString(), y.ToString(), StringComparison.Ordinal);\n\n    public static bool Equals(TypeInfo x, TypeInfo y) =>\n        EqTypeInfo.Equals(x, y);\n\n    public static int GetHashCode(TypeInfo x) =>\n        EqTypeInfo.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/README.md",
    "content": "__If you're new to this library or functional-programming this is almost certainly not the place to start browsing!__\n\nClass-instances try to replicate the instances of Haskell in C#.  They pair with the traits using ad-hoc polymorphism.\n\nAd-hoc polymorphism has long been believed to not be possible in C#. However with some cunning _it is_. Ad-hoc polymorphism allows \nprogrammers to add traits to a type later. For example in C# it would be amazing if we had an interface called `INumeric` for numeric \ntypes like `int`, `long`, `double`, etc. The reason this doesn't exist is if you write a function like:\n\n    INumeric Add(INumeric x, INumeric y) => x + y;\n\nThen it would cause boxing. Which is slow (well, slower). I can only assume that's why it wasn't added by the BCL team. Anyway, it's \npossible to create a numeric type, very much like a trait in Haskell, and ad-hoc instances of the numeric trait that allow \nfor generic numeric operations without boxing.  [See the wiki for a deeper dive into ad-hoc polymorphism](https://github.com/louthy/language-ext/wiki/Ad-hoc-polymorphism)"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TBigInt.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer number \n/// </summary>\npublic struct TBigInt : Num<bigint>, Bool<bigint>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(bigint x, bigint y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(bigint x, bigint y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Find the sum of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static bigint Add(bigint x, bigint y) =>\n        x + y;\n\n    /// <summary>\n    /// Find the difference between two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The difference between x and y</returns>\n    [Pure]\n    public static bigint Subtract(bigint x, bigint y) =>\n        x - y;\n\n    /// <summary>\n    /// Find the product of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static bigint Multiply(bigint x, bigint y) =>\n        x * y;\n\n    /// <summary>\n    /// Divide two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static bigint Divide(bigint x, bigint y) =>\n        x / y;\n\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static bigint Abs(bigint x) =>\n        x < bigint.Zero\n            ? -x\n            : x;\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static bigint Signum(bigint x) =>\n        x   == bigint.Zero ? 0\n        : x < bigint.Zero  ? -1\n                             : 1;\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static bigint FromInteger(int x) =>\n        x;\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static bigint FromDecimal(decimal x) =>\n        (bigint)x;\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static bigint FromFloat(float x) =>\n        (bigint)x;\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static bigint FromDouble(double x) =>\n        (bigint)x;\n\n    /// <summary>\n    /// Monoid empty value (0)\n    /// </summary>\n    /// <returns>0</returns>\n    [Pure]\n    public static bigint Empty => bigint.Zero;\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static bigint Negate(bigint x) => -x;\n\n    /// <summary>\n    /// Semigroup append (sum)\n    /// </summary>\n    /// <param name=\"x\">left hand side of the append operation</param>\n    /// <param name=\"y\">right hand side of the append operation</param>\n    /// <returns>x + y</returns>\n    [Pure]\n    public static bigint Append(bigint x, bigint y) => \n        x + y;\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(bigint x) =>\n        x.GetHashCode();\n\n    /// <summary>\n    /// Returns True\n    /// </summary>\n    /// <returns>True</returns>\n    [Pure]\n    public static bigint True() =>\n        bigint.MinusOne;\n\n    /// <summary>\n    /// Returns False\n    /// </summary>\n    /// <returns>False</returns>\n    [Pure]\n    public static bigint False() =>\n        bigint.Zero;\n\n    /// <summary>\n    /// Returns the result of the bitwise AND operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise AND operation between `a` and `b`</returns>\n    [Pure]\n    public static bigint And(bigint a, bigint b) =>\n        a & b;\n\n    /// <summary>\n    /// Returns the result of the bitwise OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise OR operation between `a` and `b`</returns>\n    [Pure]\n    public static bigint Or(bigint a, bigint b) =>\n        a | b;\n\n    /// <summary>\n    /// Returns the result of the bitwise NOT operation on `a`\n    /// </summary>\n    /// <returns>The result of the bitwise NOT operation on `a`</returns>\n    [Pure]\n    public static bigint Not(bigint a) =>\n        ~a;\n\n    /// <summary>\n    /// Returns the result of the bitwise exclusive-OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise exclusive-OR operation between `a` and `b`</returns>\n    [Pure]\n    public static bigint XOr(bigint a, bigint b) =>\n        a ^ b;\n\n    /// <summary>\n    /// Logical implication\n    /// </summary>\n    /// <returns>If `a` is true that implies `b`, else `true`</returns>\n    [Pure]\n    public static bigint Implies(bigint a, bigint b) =>\n        And(a, True()) == False()\n            ? True()\n            : b;\n\n    /// <summary>\n    /// Bitwise bi-conditional. \n    /// </summary>\n    /// <returns>`Not(XOr(a, b))`</returns>\n    [Pure]\n    public static bigint BiCondition(bigint a, bigint b) =>\n        Not(XOr(a, b));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TBool.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Bool class instance.  Implements\n/// \n///     Eq〈bool〉\n///     Ord〈bool〉\n///     Bool〈bool〉\n/// </summary>\npublic struct TBool : Ord<bool>, Bool<bool>\n{\n    /// <summary>\n    /// Returns the result of the logical AND operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical AND operation between `a` and `b`</returns>\n    [Pure]\n    public static bool And(bool a, bool b) =>\n        a && b;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    public static int Compare(bool x, bool y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(bool x, bool y) =>\n        x == y;\n\n    /// <summary>\n    /// Returns False\n    /// </summary>\n    /// <returns>False</returns>\n    [Pure]\n    public static bool False() =>\n        false;\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(bool x) =>\n        x.GetHashCode();\n\n    /// <summary>\n    /// Returns the result of the logical NOT operation on `a`\n    /// </summary>\n    /// <returns>The result of the logical NOT operation on `a`</returns>\n    [Pure]\n    public static bool Not(bool a) =>\n        !a;\n\n    /// <summary>\n    /// Returns the result of the logical OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical OR operation between `a` and `b`</returns>\n    [Pure]\n    public static bool Or(bool a, bool b) =>\n        a || b;\n\n    /// <summary>\n    /// Returns True\n    /// </summary>\n    /// <returns>True</returns>\n    [Pure]\n    public static bool True() =>\n        true;\n\n    /// <summary>\n    /// Returns the result of the logical exclusive-OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical exclusive-OR operation between `a` and `b`</returns>\n    [Pure]\n    public static bool XOr(bool a, bool b) =>\n        a ^ b;\n\n    /// <summary>\n    /// Logical implication\n    /// </summary>\n    /// <returns>If `a` is true that implies `b`, else `true`</returns>\n    [Pure]\n    public static bool Implies(bool a, bool b) =>\n        !a || b;\n\n    /// <summary>\n    /// Logical bi-conditional.  Both `a` and `b` must be `true`, or both `a` and `b` must\n    /// be false.\n    /// </summary>\n    /// <returns>`true` if `a == b`, `false` otherwise</returns>\n    [Pure]\n    public static bool BiCondition(bool a, bool b) =>\n        a == b;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TBoolBool.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// TBoolBool class instance.  Implements\n/// \n///     Eq〈(bool, bool)〉\n///     Ord〈(bool, bool)〉\n///     Bool〈(bool, bool)〉\n/// </summary>\npublic struct TBoolBool : Ord<(bool, bool)>, Bool<(bool, bool)>\n{\n    /// <summary>\n    /// Returns the result of the logical AND operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical AND operation between `a` and `b`</returns>\n    [Pure]\n    public static (bool, bool) And((bool, bool) a, (bool, bool) b) =>\n        (a.Item1 && b.Item1,\n         a.Item2 && b.Item2);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    public static int Compare((bool, bool) x, (bool, bool) y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals((bool, bool) x, (bool, bool) y) =>\n        x.Item1 == y.Item1 && x.Item2 == y.Item2;\n\n    /// <summary>\n    /// Returns False\n    /// </summary>\n    /// <returns>False</returns>\n    [Pure]\n    public static (bool, bool) False() =>\n        (false, false);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode((bool, bool) x) =>\n        x.GetHashCode();\n\n    /// <summary>\n    /// Returns the result of the logical NOT operation on `a`\n    /// </summary>\n    /// <returns>The result of the logical NOT operation on `a`</returns>\n    [Pure]\n    public static (bool, bool) Not((bool, bool) a) =>\n        (!a.Item1, !a.Item2);\n\n    /// <summary>\n    /// Returns the result of the logical OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical OR operation between `a` and `b`</returns>\n    [Pure]\n    public static (bool, bool) Or((bool, bool) a, (bool, bool) b) =>\n        (a.Item1 || b.Item1,\n         a.Item2 || b.Item2);\n\n    /// <summary>\n    /// Returns True\n    /// </summary>\n    /// <returns>True</returns>\n    [Pure]\n    public static (bool, bool) True() =>\n        (true, true);\n\n    /// <summary>\n    /// Returns the result of the logical exclusive-OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical exclusive-OR operation between `a` and `b`</returns>\n    [Pure]\n    public static (bool, bool) XOr((bool, bool) a, (bool, bool) b) =>\n        (a.Item1 ^ b.Item1,\n         a.Item2 ^ b.Item2);\n\n    /// <summary>\n    /// Logical implication\n    /// </summary>\n    /// <returns>If `a` is true that implies `b`, else `true`</returns>\n    [Pure]\n    public static (bool, bool) Implies((bool, bool) a, (bool, bool) b) =>\n        (!a.Item1 || b.Item1,\n         !a.Item2 || b.Item2);\n\n    /// <summary>\n    /// Logical bi-conditional.  Both `a` and `b` must be `true`, or both `a` and `b` must\n    /// be false.\n    /// </summary>\n    /// <returns>`true` if `a == b`, `false` otherwise</returns>\n    [Pure]\n    public static (bool, bool) BiCondition((bool, bool) a, (bool, bool) b) =>\n        (a.Item1 == b.Item1, a.Item2 == b.Item2);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TChar.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer number \n/// </summary>\npublic struct TChar : Ord<char>, Arithmetic<char>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(char x, char y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(char x, char y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(char x) =>\n        x.GetHashCode();\n\n    [Pure]\n    public static char Add(char x, char y) =>\n        (char)(x + y);\n\n    [Pure]\n    public static char Subtract(char x, char y) =>\n        (char)(x - y);\n\n    [Pure]\n    public static char Multiply(char x, char y) =>\n        (char) (x * y);\n\n    [Pure]\n    public static char Negate(char x) =>\n        (char)-x;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TDecimal.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct TDecimal : Floating<decimal>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the equality operation</param>\n    /// <param name=\"y\">Right hand side of the equality operation</param>\n    /// <returns>True if parameters are equal</returns>\n    [Pure]\n    public static bool Equals(decimal x, decimal y) => x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(decimal x, decimal y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Find the sum of two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static decimal Add(decimal x, decimal y) => x + y;\n\n    /// <summary>\n    /// Find the difference between two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The difference between x and y</returns>\n    [Pure]\n    public static decimal Subtract(decimal x, decimal y) => x - y;\n\n    /// <summary>\n    /// Find the product of two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static decimal Multiply(decimal x, decimal y) => x * y;\n\n    /// <summary>\n    /// Divide two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static decimal Divide(decimal x, decimal y) =>\n        x / y;\n\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static decimal Abs(decimal x) => Math.Abs(x);\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static decimal Signum(decimal x) => \n        Math.Sign(x);\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static decimal FromInteger(int x) => \n        x;\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static decimal FromDecimal(decimal x) => \n        x;\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static decimal FromFloat(float x) => \n        (decimal)x;\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static decimal FromDouble(double x) => (decimal)x;\n\n    /// <summary>\n    /// Generates a fractional value from an integer ratio.\n    /// </summary>\n    /// <param name=\"x\">The ratio to convert</param>\n    /// <returns>The equivalent of x in the implementing type.</returns>\n    [Pure]\n    public static decimal FromRational(Ratio<int> x) => \n        (decimal)x.Numerator / x.Denominator;\n\n    /// <summary>\n    /// Returns an approximation of pi.\n    /// </summary>\n    /// <returns>A reasonable approximation of pi in this type</returns>\n    [Pure]\n    public static decimal Pi() => \n        (decimal)Math.PI;\n\n    /// <summary>\n    /// The exponential function.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the exponential</param>\n    /// <returns>The value of <c>e^x</c></returns>\n    [Pure]\n    public static decimal Exp(decimal x) => \n        (decimal)Math.Exp((double)x);\n\n    /// <summary>\n    /// Calculates the square root of a value.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the square root.</param>\n    /// <returns>The value of <c>sqrt(x)</c>.</returns>\n    [Pure]\n    public static decimal Sqrt(decimal x) => \n        (decimal)Math.Sqrt((double)x);\n\n    /// <summary>\n    /// Calculates the natural logarithm of a value.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which we are calculating the natural logarithm.\n    /// </param>\n    /// <returns>The value of <c>ln(x)</c>.</returns>\n    [Pure]\n    public static decimal Log(decimal x) => \n        (decimal)Math.Log((double)x);\n\n    /// <summary>Raises x to the power y\n    /// </summary>\n    /// <param name=\"x\">The base to be raised to y</param>\n    /// <param name=\"y\">The exponent to which we are raising x</param>\n    /// <returns>The value of <c>x^y</c>.</returns>\n    [Pure]\n    public static decimal Pow(decimal x, decimal y) => \n        (decimal)Math.Pow((double)x, (double)y);\n\n    /// <summary>\n    /// Calculates the logarithm of a value with respect to an arbitrary base.\n    /// </summary>\n    /// <param name=\"x\">The base to use for the logarithm of t</param>\n    /// <param name=\"y\">The value for which we are calculating the logarithm.</param>\n    /// <returns>The value of <c>log x (y)</c>.</returns>\n    [Pure]\n    public static decimal LogBase(decimal b, decimal x) => \n        (decimal)Math.Log((double)x, (double)b);\n\n    /// <summary>\n    /// Calculates the sine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>sin(x)</c></returns>\n    [Pure]\n    public static decimal Sin(decimal x) => \n        (decimal)Math.Sin((double)x);\n\n    /// <summary>\n    /// Calculates the cosine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>cos(x)</c></returns>\n    [Pure]\n    public static decimal Cos(decimal x) => \n        (decimal)Math.Cos((double)x);\n\n    /// <summary>\n    ///     Calculates the tangent of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>tan(x)</c></returns>\n    [Pure]\n    public static decimal Tan(decimal x) => \n        (decimal)Math.Tan((double)x);\n\n    /// <summary>\n    /// Calculates an arcsine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arcsine is to be calculated.</param>\n    /// <returns>The value of <c>asin(x)</c>, in radians.</returns>\n    [Pure]\n    public static decimal Asin(decimal x) => \n        (decimal)Math.Asin((double)x);\n\n    /// <summary>\n    /// Calculates an arc-cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-cosine is to be calculated</param>\n    /// <returns>The value of <c>acos(x)</c>, in radians</returns>\n    [Pure]\n    public static decimal Acos(decimal x) => \n        (decimal)Math.Acos((double)x);\n\n    /// <summary>\n    /// Calculates an arc-tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-tangent is to be calculated</param>\n    /// <returns>The value of <c>atan(x)</c>, in radians</returns>\n    [Pure]\n    public static decimal Atan(decimal x) => \n        (decimal)Math.Atan((double)x);\n\n    /// <summary>\n    /// Calculates a hyperbolic sine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic sine is to be calculated</param>\n    /// <returns>The value of <c>sinh(x)</c></returns>\n    [Pure]\n    public static decimal Sinh(decimal x) => \n        (decimal)Math.Sinh((double)x);\n\n    /// <summary>\n    /// Calculates a hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic cosine is to be calculated</param>\n    /// <returns>The value of <c>cosh(x)</c></returns>\n    [Pure]\n    public static decimal Cosh(decimal x) => \n        (decimal)Math.Cosh((double)x);\n\n    /// <summary>\n    /// Calculates a hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which a hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>tanh(x)</c></returns>\n    [Pure]\n    public static decimal Tanh(decimal x) => \n        (decimal)Math.Tanh((double)x);\n\n    /// <summary>Calculates an area hyperbolic sine</summary>\n    /// <param name=\"x\">The value for which an area hyperbolic sine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>asinh(x)</c>.</returns>\n    [Pure]\n    public static decimal Asinh(decimal x) => \n        Log(x + Sqrt((x * x) + 1m));\n\n    /// <summary>\n    /// Calculates an area hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic cosine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>acosh(x)</c>.</returns>\n    [Pure]\n    public static decimal Acosh(decimal x) => \n        Log(x + Sqrt((x * x) - 1m));\n\n    /// <summary>\n    /// Calculates an area hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>atanh(x)</c></returns>\n    [Pure]\n    public static decimal Atanh(decimal x) => \n        0.5m * Log((1m + x) / (1m - x));\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static decimal Negate(decimal x) => \n        -x;\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(decimal x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TDouble.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct TDouble : Floating<double>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the equality operation</param>\n    /// <param name=\"y\">Right hand side of the equality operation</param>\n    /// <returns>True if parameters are equal</returns>\n    [Pure]\n    public static bool Equals(double x, double y) => \n        x.Equals(y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(double x, double y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Find the sum of two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static double Add(double x, double y) => \n        x + y;\n\n    /// <summary>\n    /// Find the difference between two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The difference between x and y</returns>\n    [Pure]\n    public static double Subtract(double x, double y) => \n        x - y;\n\n    /// <summary>\n    /// Find the product of two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static double Multiply(double x, double y) => \n        x * y;\n\n    /// <summary>\n    /// Divide two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static double Divide(double x, double y) =>\n        x / y;\n\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static double Abs(double x) => \n        Math.Abs(x);\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static double Signum(double x) => \n        Math.Sign(x);\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static double FromInteger(int x) => \n        x;\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static double FromDecimal(decimal x) => \n        (double)x;\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static double FromFloat(float x) => \n        x;\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static double FromDouble(double x) => \n        x;\n\n    /// <summary>\n    /// Generates a fractional value from an integer ratio.\n    /// </summary>\n    /// <param name=\"x\">The ratio to convert</param>\n    /// <returns>The equivalent of x in the implementing type.</returns>\n    [Pure]\n    public static double FromRational(Ratio<int> x) => \n        (double)x.Numerator / x.Denominator;\n\n    /// <summary>\n    /// Returns an approximation of pi.\n    /// </summary>\n    /// <returns>A reasonable approximation of pi in this type</returns>\n    [Pure]\n    public static double Pi() => \n        Math.PI;\n\n    /// <summary>\n    /// The exponential function.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the exponential</param>\n    /// <returns>The value of <c>e^x</c></returns>\n    [Pure]\n    public static double Exp(double x) => \n        Math.Exp(x);\n\n    /// <summary>\n    /// Calculates the square root of a value.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the square root.</param>\n    /// <returns>The value of <c>sqrt(x)</c>.</returns>\n    [Pure]\n    public static double Sqrt(double x) => \n        Math.Sqrt(x);\n\n    /// <summary>\n    /// Calculates the natural logarithm of a value.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which we are calculating the natural logarithm.\n    /// </param>\n    /// <returns>The value of <c>ln(x)</c>.</returns>\n    [Pure]\n    public static double Log(double x) => \n        Math.Log(x);\n\n    /// <summary>Raises x to the power y\n    /// </summary>\n    /// <param name=\"x\">The base to be raised to y</param>\n    /// <param name=\"y\">The exponent to which we are raising x</param>\n    /// <returns>The value of <c>x^y</c>.</returns>\n    [Pure]\n    public static double Pow(double x, double y) => \n        Math.Pow(x, y);\n\n    /// <summary>\n    /// Calculates the logarithm of a value with respect to an arbitrary base.\n    /// </summary>\n    /// <param name=\"x\">The base to use for the logarithm of t</param>\n    /// <param name=\"y\">The value for which we are calculating the logarithm.</param>\n    /// <returns>The value of <c>log x (y)</c>.</returns>\n    [Pure]\n    public static double LogBase(double b, double x) => \n        Math.Log(x, b);\n\n    /// <summary>\n    /// Calculates the sine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>sin(x)</c></returns>\n    [Pure]\n    public static double Sin(double x) => \n        Math.Sin(x);\n\n    /// <summary>\n    /// Calculates the cosine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>cos(x)</c></returns>\n    [Pure]\n    public static double Cos(double x) => \n        Math.Cos(x);\n\n    /// <summary>\n    ///     Calculates the tangent of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>tan(x)</c></returns>\n    [Pure]\n    public static double Tan(double x) => \n        Math.Tan(x);\n\n    /// <summary>\n    /// Calculates an arcsine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arcsine is to be calculated.</param>\n    /// <returns>The value of <c>asin(x)</c>, in radians.</returns>\n    [Pure]\n    public static double Asin(double x) => \n        Math.Asin(x);\n\n    /// <summary>\n    /// Calculates an arc-cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-cosine is to be calculated</param>\n    /// <returns>The value of <c>acos(x)</c>, in radians</returns>\n    [Pure]\n    public static double Acos(double x) => \n        Math.Acos(x);\n\n    /// <summary>\n    /// Calculates an arc-tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-tangent is to be calculated</param>\n    /// <returns>The value of <c>atan(x)</c>, in radians</returns>\n    [Pure]\n    public static double Atan(double x) => \n        Math.Atan(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic sine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic sine is to be calculated</param>\n    /// <returns>The value of <c>sinh(x)</c></returns>\n    [Pure]\n    public static double Sinh(double x) => \n        Math.Sinh(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic cosine is to be calculated</param>\n    /// <returns>The value of <c>cosh(x)</c></returns>\n    [Pure]\n    public static double Cosh(double x) => \n        Math.Cosh(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which a hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>tanh(x)</c></returns>\n    [Pure]\n    public static double Tanh(double x) => \n        Math.Tanh(x);\n\n    /// <summary>Calculates an area hyperbolic sine</summary>\n    /// <param name=\"x\">The value for which an area hyperbolic sine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>asinh(x)</c>.</returns>\n    [Pure]\n    public static double Asinh(double x) => \n        Math.Log(x + Math.Sqrt(x * x + 1.0));\n\n    /// <summary>\n    /// Calculates an area hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic cosine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>acosh(x)</c>.</returns>\n    [Pure]\n    public static double Acosh(double x) => \n        Math.Log(x + Math.Sqrt(x * x - 1.0));\n\n    /// <summary>\n    /// Calculates an area hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>atanh(x)</c></returns>\n    [Pure]\n    public static double Atanh(double x) => \n        0.5 * Math.Log((1.0 + x) / (1.0 - x));\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static double Negate(double x) => \n        -x;\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(double x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TFloat.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct TFloat : Floating<float>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the equality operation</param>\n    /// <param name=\"y\">Right hand side of the equality operation</param>\n    /// <returns>True if parameters are equal</returns>\n    [Pure]\n    public static bool Equals(float x, float y) => \n        x.Equals(y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(float x, float y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Find the sum of two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static float Add(float x, float y) => x + y;\n\n    /// <summary>\n    /// Find the difference between two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The difference between x and y</returns>\n    [Pure]\n    public static float Subtract(float x, float y) => \n        x - y;\n\n    /// <summary>\n    /// Find the product of two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static float Multiply(float x, float y) => x * y;\n\n    /// <summary>\n    /// Divide two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static float Divide(float x, float y) =>\n        x / y;\n\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static float Abs(float x) => Math.Abs(x);\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static float Signum(float x) => Math.Sign(x);\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static float FromInteger(int x) => x;\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static float FromDecimal(decimal x) => (float)x;\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static float FromFloat(float x) => x;\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static float FromDouble(double x) => (float)x;\n\n    /// <summary>\n    /// Generates a fractional value from an integer ratio.\n    /// </summary>\n    /// <param name=\"x\">The ratio to convert</param>\n    /// <returns>The equivalent of x in the implementing type.</returns>\n    [Pure]\n    public static float FromRational(Ratio<int> x) => (float)x.Numerator / x.Denominator;\n\n    /// <summary>\n    /// Returns an approximation of pi.\n    /// </summary>\n    /// <returns>A reasonable approximation of pi in this type</returns>\n    [Pure]\n    public static float Pi() => (float)Math.PI;\n\n    /// <summary>\n    /// The exponential function.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the exponential</param>\n    /// <returns>The value of <c>e^x</c></returns>\n    [Pure]\n    public static float Exp(float x) => (float)Math.Exp(x);\n\n    /// <summary>\n    /// Calculates the square root of a value.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the square root.</param>\n    /// <returns>The value of <c>sqrt(x)</c>.</returns>\n    [Pure]\n    public static float Sqrt(float x) => (float)Math.Sqrt(x);\n\n    /// <summary>\n    /// Calculates the natural logarithm of a value.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which we are calculating the natural logarithm.\n    /// </param>\n    /// <returns>The value of <c>ln(x)</c>.</returns>\n    [Pure]\n    public static float Log(float x) => (float)Math.Log(x);\n\n    /// <summary>Raises x to the power y\n    /// </summary>\n    /// <param name=\"x\">The base to be raised to y</param>\n    /// <param name=\"y\">The exponent to which we are raising x</param>\n    /// <returns>The value of <c>x^y</c>.</returns>\n    [Pure]\n    public static float Pow(float x, float y) => (float)Math.Pow(x, y);\n\n    /// <summary>\n    /// Calculates the logarithm of a value with respect to an arbitrary base.\n    /// </summary>\n    /// <param name=\"x\">The base to use for the logarithm of t</param>\n    /// <param name=\"y\">The value for which we are calculating the logarithm.</param>\n    /// <returns>The value of <c>log x (y)</c>.</returns>\n    [Pure]\n    public static float LogBase(float b, float x) => (float)Math.Log(x, b);\n\n    /// <summary>\n    /// Calculates the sine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>sin(x)</c></returns>\n    [Pure]\n    public static float Sin(float x) => (float)Math.Sin(x);\n\n    /// <summary>\n    /// Calculates the cosine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>cos(x)</c></returns>\n    [Pure]\n    public static float Cos(float x) => (float)Math.Cos(x);\n\n    /// <summary>\n    ///     Calculates the tangent of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>tan(x)</c></returns>\n    [Pure]\n    public static float Tan(float x) => (float)Math.Tan(x);\n\n    /// <summary>\n    /// Calculates an arcsine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arcsine is to be calculated.</param>\n    /// <returns>The value of <c>asin(x)</c>, in radians.</returns>\n    [Pure]\n    public static float Asin(float x) => (float)Math.Asin(x);\n\n    /// <summary>\n    /// Calculates an arc-cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-cosine is to be calculated</param>\n    /// <returns>The value of <c>acos(x)</c>, in radians</returns>\n    [Pure]\n    public static float Acos(float x) => (float)Math.Acos(x);\n\n    /// <summary>\n    /// Calculates an arc-tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-tangent is to be calculated</param>\n    /// <returns>The value of <c>atan(x)</c>, in radians</returns>\n    [Pure]\n    public static float Atan(float x) => (float)Math.Atan(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic sine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic sine is to be calculated</param>\n    /// <returns>The value of <c>sinh(x)</c></returns>\n    [Pure]\n    public static float Sinh(float x) => (float)Math.Sinh(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic cosine is to be calculated</param>\n    /// <returns>The value of <c>cosh(x)</c></returns>\n    [Pure]\n    public static float Cosh(float x) => (float)Math.Cosh(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which a hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>tanh(x)</c></returns>\n    [Pure]\n    public static float Tanh(float x) => (float)Math.Tanh(x);\n\n    /// <summary>Calculates an area hyperbolic sine</summary>\n    /// <param name=\"x\">The value for which an area hyperbolic sine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>asinh(x)</c>.</returns>\n    [Pure]\n    public static float Asinh(float x) => (float)Math.Log(x + Math.Sqrt((x * x) + 1.0));\n\n    /// <summary>\n    /// Calculates an area hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic cosine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>acosh(x)</c>.</returns>\n    [Pure]\n    public static float Acosh(float x) => (float)Math.Log(x + Math.Sqrt((x * x) - 1.0));\n\n    /// <summary>\n    /// Calculates an area hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>atanh(x)</c></returns>\n    [Pure]\n    public static float Atanh(float x) => 0.5f * (float)Math.Log((1.0 + x) / (1.0 - x));\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static float Negate(float x) => -x;\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(float x) =>\n        x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TInt.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer number \n/// </summary>\npublic struct TInt : Num<int>, Bool<int>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(int x, int y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(int x, int y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Find the sum of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static int Add(int x, int y) =>\n        x + y;\n\n    /// <summary>\n    /// Find the difference between two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The difference between x and y</returns>\n    [Pure]\n    public static int Subtract(int x, int y) =>\n        x - y;\n\n    /// <summary>\n    /// Find the product of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static int Multiply(int x, int y) =>\n        x * y;\n\n    /// <summary>\n    /// Divide two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static int Divide(int x, int y) =>\n        x / y;\n\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static int Abs(int x) =>\n        Math.Abs(x);\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static int Signum(int x) =>\n        Math.Sign(x);\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static int FromInteger(int x) =>\n        x;\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static int FromDecimal(decimal x) =>\n        (int)x;\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static int FromFloat(float x) =>\n        (int)x;\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static int FromDouble(double x) =>\n        (int)x;\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static int Negate(int x) => -x;\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(int x) =>\n        x.GetHashCode();\n\n    /// <summary>\n    /// Returns True\n    /// </summary>\n    /// <returns>True</returns>\n    [Pure]\n    public static int True() =>\n        -1;\n\n    /// <summary>\n    /// Returns False\n    /// </summary>\n    /// <returns>False</returns>\n    [Pure]\n    public static int False() =>\n        0;\n\n    /// <summary>\n    /// Returns the result of the bitwise AND operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise AND operation between `a` and `b`</returns>\n    [Pure]\n    public static int And(int a, int b) =>\n        a & b;\n\n    /// <summary>\n    /// Returns the result of the bitwise OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise OR operation between `a` and `b`</returns>\n    [Pure]\n    public static int Or(int a, int b) =>\n        a | b;\n\n    /// <summary>\n    /// Returns the result of the bitwise NOT operation on `a`\n    /// </summary>\n    /// <returns>The result of the bitwise NOT operation on `a`</returns>\n    [Pure]\n    public static int Not(int a) =>\n        ~a;\n\n    /// <summary>\n    /// Returns the result of the bitwise exclusive-OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise exclusive-OR operation between `a` and `b`</returns>\n    [Pure]\n    public static int XOr(int a, int b) =>\n        a ^ b;\n\n    /// <summary>\n    /// Logical implication\n    /// </summary>\n    /// <returns>If `a` is true that implies `b`, else `true`</returns>\n    [Pure]\n    public static int Implies(int a, int b) =>\n        And(a, True()) == False()\n            ? True()\n            : b;\n\n    /// <summary>\n    /// Bitwise bi-conditional. \n    /// </summary>\n    /// <returns>`Not(XOr(a, b))`</returns>\n    [Pure]\n    public static int BiCondition(int a, int b) =>\n        Not(XOr(a, b));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TLong.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Long integer number\n/// </summary>\npublic struct TLong : Num<long>, Bool<long>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(long x, long y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(long x, long y) =>\n        x.CompareTo(y);\n\n    /// <summary>\n    /// Find the sum of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static long Add(long x, long y) =>\n        x + y;\n\n    /// <summary>\n    /// Find the difference between two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The difference between x and y</returns>\n    [Pure]\n    public static long Subtract(long x, long y) =>\n        x - y;\n\n    /// <summary>\n    /// Fund the product of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static long Multiply(long x, long y) =>\n        x * y;\n\n    /// <summary>\n    /// Divide x by y\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static long Divide(long x, long y) =>\n        x / y;\n\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static long Abs(long x) =>\n        Math.Abs(x);\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static long Signum(long x) =>\n        Math.Sign(x);\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static long FromInteger(int x) =>\n        x;\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static long FromDecimal(decimal x) =>\n        (long)x;\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static long FromFloat(float x) =>\n        (long)x;\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static long FromDouble(double x) =>\n        (long)x;\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static long Negate(long x) => -x;\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(long x) =>\n        x.GetHashCode();\n\n    /// <summary>\n    /// Returns True\n    /// </summary>\n    /// <returns>True</returns>\n    [Pure]\n    public static long True() =>\n        -1;\n\n    /// <summary>\n    /// Returns False\n    /// </summary>\n    /// <returns>False</returns>\n    [Pure]\n    public static long False() =>\n        0;\n\n    /// <summary>\n    /// Returns the result of the bitwise AND operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise AND operation between `a` and `b`</returns>\n    [Pure]\n    public static long And(long a, long b) =>\n        a & b;\n\n    /// <summary>\n    /// Returns the result of the bitwise OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise OR operation between `a` and `b`</returns>\n    [Pure]\n    public static long Or(long a, long b) =>\n        a | b;\n\n    /// <summary>\n    /// Returns the result of the bitwise NOT operation on `a`\n    /// </summary>\n    /// <returns>The result of the bitwise NOT operation on `a`</returns>\n    [Pure]\n    public static long Not(long a) =>\n        ~a;\n\n    /// <summary>\n    /// Returns the result of the bitwise exclusive-OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise exclusive-OR operation between `a` and `b`</returns>\n    [Pure]\n    public static long XOr(long a, long b) =>\n        a ^ b;\n\n    /// <summary>\n    /// Logical implication\n    /// </summary>\n    /// <returns>If `a` is true that implies `b`, else `true`</returns>\n    [Pure]\n    public static long Implies(long a, long b) =>\n        And(a, True()) == False()\n            ? True()\n            : b;\n\n    /// <summary>\n    /// Bitwise bi-conditional. \n    /// </summary>\n    /// <returns>`Not(XOr(a, b))`</returns>\n    [Pure]\n    public static long BiCondition(long a, long b) =>\n        Not(XOr(a, b));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TNumericChar.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Integer number \n/// </summary>\npublic struct TNumericChar : Num<char>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(char x, char y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(char x, char y) =>\n        CharToInt(x).CompareTo(CharToInt(y));\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(char x) =>\n        x.GetHashCode();\n\n    [Pure]\n    public static char Add(char x, char y) =>\n        (char)(CharToInt(x) + CharToInt(y));\n\n    [Pure]\n    public static char Subtract(char x, char y) =>\n        (char)(CharToInt(x) - CharToInt(y));\n\n    [Pure]\n    public static char Multiply(char x, char y) =>\n        (char)(CharToInt(x) * CharToInt(y));\n\n    [Pure]\n    public static char Negate(char x) =>\n        (char)(-CharToInt(x));\n\n    static int CharToInt(int x) =>\n        x > 32768\n            ? -(65536 - x)\n            : x;\n\n    public static char Abs(char x) => \n        x;\n\n    public static char Signum(char x) => \n        (char)1;\n\n    public static char FromInteger(int x) =>\n        (char)x;\n\n    public static char FromDecimal(decimal x) => \n        (char)x;\n\n    public static char FromFloat(float x) => \n        (char)x;\n\n    public static char FromDouble(double x) => \n        (char)x;\n\n    public static char Divide(char x, char y) =>\n        (char)(CharToInt(x) / CharToInt(y));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TShort.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\n/// <summary>\n/// Short integer number\n/// </summary>\npublic struct TShort : Num<short>, Bool<short>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(short x, short y) =>\n        x == y;\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(short x, short y) => \n        x.CompareTo(y);\n\n    /// <summary>\n    /// Find the sum of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static short Add(short x, short y) =>\n        (short)(x + y);\n\n    /// <summary>\n    /// Find the difference between two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The difference between x and y</returns>\n    [Pure]\n    public static short Subtract(short x, short y) =>\n        (short)(x - y);\n\n    /// <summary>\n    /// Fund the product of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static short Multiply(short x, short y) =>\n        (short)(x * y);\n\n    /// <summary>\n    /// Divide x by y\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static short Divide(short x, short y) =>\n        (short)(x / y);\n\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static short Abs(short x) =>\n        Math.Abs(x);\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static short Signum(short x) =>\n        (short)Math.Sign(x);\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static short FromInteger(int x) =>\n        (short)x;\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static short FromDecimal(decimal x) =>\n        (short)x;\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static short FromFloat(float x) =>\n        (short)x;\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static short FromDouble(double x) =>\n        (short)x;\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static short Negate(short x) => (short)-x;\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(short x) =>\n        x.GetHashCode();\n\n    /// <summary>\n    /// Returns True\n    /// </summary>\n    /// <returns>True</returns>\n    [Pure]\n    public static short True() =>\n        -1;\n\n    /// <summary>\n    /// Returns False\n    /// </summary>\n    /// <returns>False</returns>\n    [Pure]\n    public static short False() =>\n        0;\n\n    /// <summary>\n    /// Returns the result of the bitwise AND operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise AND operation between `a` and `b`</returns>\n    [Pure]\n    public static short And(short a, short b) =>\n        (short)(a & b);\n\n    /// <summary>\n    /// Returns the result of the bitwise OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise OR operation between `a` and `b`</returns>\n    [Pure]\n    public static short Or(short a, short b) =>\n        (short)(a | b);\n\n    /// <summary>\n    /// Returns the result of the bitwise NOT operation on `a`\n    /// </summary>\n    /// <returns>The result of the bitwise NOT operation on `a`</returns>\n    [Pure]\n    public static short Not(short a) =>\n        (short)(~a);\n\n    /// <summary>\n    /// Returns the result of the bitwise exclusive-OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the bitwise exclusive-OR operation between `a` and `b`</returns>\n    [Pure]\n    public static short XOr(short a, short b) =>\n        (short)(a ^ b);\n\n    /// <summary>\n    /// Logical implication\n    /// </summary>\n    /// <returns>If `a` is true that implies `b`, else `true`</returns>\n    [Pure]\n    public static short Implies(short a, short b) =>\n        And(a, True()) == False()\n            ? True()\n            : b;\n\n    /// <summary>\n    /// Bitwise bi-conditional. \n    /// </summary>\n    /// <returns>`Not(XOr(a, b))`</returns>\n    [Pure]\n    public static short BiCondition(short a, short b) =>\n        Not(XOr(a, b));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Class Instances/TString.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct TString : Ord<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(string x, string y) =>\n        EqString.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(string x, string y) =>\n        OrdString.Compare(x,y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        OrdString.GetHashCode(x);\n}\n\npublic struct TStringOrdinalIgnoreCase : Ord<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(string x, string y) =>\n        EqStringOrdinalIgnoreCase.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(string x, string y) =>\n        OrdStringOrdinalIgnoreCase.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) => \n        x.IsNull() ? 0 : x.GetHashCode();\n}\n\npublic struct TStringOrdinal : Ord<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(string x, string y) =>\n        EqStringOrdinal.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(string x, string y) =>\n        OrdStringOrdinal.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        x.GetHashCode();\n}\n\npublic struct TStringCurrentCultureIgnoreCase : Ord<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(string x, string y) =>\n        EqStringCurrentCultureIgnoreCase.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(string x, string y) =>\n        OrdStringCurrentCultureIgnoreCase.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        x.IsNull() ? 0 : x.GetHashCode();\n}\n\npublic struct TStringCurrentCulture : Ord<string>\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals(string x, string y) =>\n        EqStringCurrentCulture.Equals(x, y);\n\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static int Compare(string x, string y) =>\n        OrdStringCurrentCulture.Compare(x, y);\n\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int GetHashCode(string x) =>\n        x.IsNull() ? 0 : x.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Combinators.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt\n{\n    public static class CombinatorsDynamic\n    {\n        /// <summary>\n        /// Identity function, or the Idiot bird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<dynamic, dynamic> I =\n            (dynamic x) =>\n                x;\n\n        /// <summary>\n        /// The Mockingbird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<dynamic, Func<dynamic, dynamic>> M =\n            (dynamic x) =>\n                (dynamic a) =>\n                    x(x(a));\n\n        /// <summary>\n        /// The Kestrel [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<dynamic, Func<dynamic, dynamic>> K =\n            (dynamic x) =>\n                (dynamic y) =>\n                    x;\n\n        /// <summary>\n        /// The Thrush [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<dynamic, Func<dynamic, dynamic>> T =\n            (dynamic x) =>\n                (dynamic y) =>\n                    y(x);\n\n        /// <summary>\n        /// The Queer bird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<dynamic, Func<dynamic, Func<dynamic, dynamic>>> Q =\n            (dynamic x) =>\n                (dynamic y) =>\n                    (dynamic z) =>\n                        y(x(z));\n\n        /// <summary>\n        /// The Starling [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<dynamic, Func<dynamic, Func<dynamic, dynamic>>> S =\n            (dynamic x) =>\n                (dynamic y) =>\n                    (dynamic z) =>\n                        x(z)(y(z));\n\n        /// <summary>\n        /// The infamous Y-combinator, or Sage bird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<dynamic, Func<dynamic, dynamic>> Y =\n            (dynamic f) =>\n                (dynamic x) =>\n                    f(Y(f), x);\n    }\n\n    public static class Combinators<A>\n    {\n        /// <summary>\n        /// Identity function, or the Idiot bird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<A, A> I = \n            (A x) => \n                x;\n\n        /// <summary>\n        /// The Mockingbird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<Func<A, A>, Func<A, A>> M = \n            (Func<A, A> x) =>\n                a => \n                    x(x(a));\n    }\n\n    public static class Combinators<A, B>\n    {\n        /// <summary>\n        /// The Kestrel [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<A, Func<B, A>> K =\n            (A x) =>\n                (B y) =>\n                    x;\n\n        /// <summary>\n        /// The Thrush [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<A, Func<Func<A, B>, B>> T =\n            (A x) =>\n                (Func<A, B> y) =>\n                    y(x);\n    }\n\n    public static class Combinators<A, B, C>\n    {\n        /// <summary>\n        /// The Queer bird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<Func<A, B>, Func<Func<B, C>, Func<A, C>>> Q = \n            (Func<A, B> x) => \n                (Func<B, C> y) => \n                    (A z) =>\n                        y(x(z));\n\n        /// <summary>\n        /// The Starling [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<Func<A, Func<B, C>>, Func<Func<A, B>, Func<A, C>>> S = \n            (Func<A, Func<B, C>> x) => \n                (Func<A, B> y) => \n                    (A z) =>\n                        x(z)(y(z));\n\n        /// <summary>\n        /// The infamous Y-combinator, or Sage bird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<Func<Func<A, B>, A, B>, Func<A, B>> Y = \n            (Func<Func<A, B>, A, B> f) => \n                (A x) =>\n                    f(Y!(f), x);\n    }\n\n    public static class Combinators\n    {\n        /// <summary>\n        /// Identity function, or the Idiot bird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static A I<A>(A x) => x;\n\n        /// <summary>\n        /// The Kestrel [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<B, A> K<A, B>(A x) => (B y) => x;\n\n        /// <summary>\n        /// The Mockingbird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<A, A> M<A>(Func<A, A> x) =>\n            a => x(x(a));\n\n        /// <summary>\n        /// The Thrush [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<Func<A, B>, B> T<A, B>(A x) => (Func<A, B> y) =>\n            y(x);\n\n        /// <summary>\n        /// The Queer bird [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<Func<B, C>, Func<A, C>> Q<A, B, C>(Func<A, B> x) => (Func<B, C> y) => (A z) =>\n             y(x(z));\n\n        /// <summary>\n        /// The Starling [dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n        /// </summary>\n        public static Func<Func<A, B>, Func<A, C>> S<A, B, C>(Func<A, B, C> x) => (Func<A, B> y) => (A z) =>\n            x(z, y(z));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Comment Alternatives.cs",
    "content": "namespace LanguageExt.Core;\n\n/// <summary>\n/// Certain characters don't work in the XML comments, so we use these alternatives\n///\n///     &lt;  becomes 〈     (Unicode 3008)\n///     &gt;  becomes 〉     (Unicode 3009)\n///     &amp; becomes ＆     (Unicode FF06)\n/// \n/// </summary>\npublic class Comment_Alternatives;\n"
  },
  {
    "path": "LanguageExt.Core/Common/Error.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.ExceptionServices;\nusing System.Runtime.Serialization;\nusing System.Text;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Common;\n\n/// <summary>\n/// Abstract error value\n/// </summary>\n[DataContract]\npublic abstract record Error : Monoid<Error>\n{\n    /// <summary>\n    /// Error code\n    /// </summary>\n    [Pure]\n    [DataMember]\n    public virtual int Code =>\n        0;\n\n    /// <summary>\n    /// Error message\n    /// </summary>\n    [Pure]\n    [DataMember]\n    public abstract string Message { get; }\n\n    /// <summary>\n    /// Inner error\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public virtual Option<Error> Inner =>\n        None;\n\n    /// <summary>\n    /// If this error represents an exceptional error, then this will return true if the exceptional error is of type E\n    /// </summary>\n    [Pure]\n    public virtual bool HasException<E>() where E : Exception =>\n        false;\n\n    /// <summary>\n    /// Return true if an `Error` with `Code` equalling `code` is contained within \n    /// </summary>\n    [Pure]\n    public virtual bool HasCode(int code) =>\n        Code == code;\n    \n    /// <summary>\n    /// Return true if this error contains or *is* the `error` provided\n    /// </summary>\n    [Pure]\n    public virtual bool IsType<E>() where E : Error =>\n        this is E;\n\n    /// <summary>\n    /// Return true if this error contains or *is* the `error` provided\n    /// </summary>\n    [Pure]\n    public virtual bool Is(Error error) =>\n        error is ManyErrors errors\n            ? errors.Errors.Exists(Is) \n            : Code == 0\n                ? Message == error.Message\n                : Code == error.Code;\n\n    /// <summary>\n    /// Filter the error(s) so that only errors of type `E` are left\n    /// </summary>\n    /// <remarks>\n    /// If no errors match, then returns `Errors.None`.\n    /// </remarks>\n    [Pure]\n    public virtual Error Filter<E>() where E : Error =>\n        this is E ? this : Errors.None;\n    \n    /// <summary>\n    /// For each error in this structure, invoke the `f` function and\n    /// monad bind it with the subsequent value.\n    ///\n    /// If any `f` invocation yields a failure, then subsequent error will\n    /// not be processed.\n    /// monad\n    /// </summary>\n    /// <remarks>\n    /// The final `A` is returned.\n    /// </remarks>\n    /// <param name=\"f\">Function</param>\n    /// <returns>The final `A` is returned.</returns>\n    [Pure]\n    public virtual K<M, A> ForAllM<M, A>(Func<Error, K<M, A>> f) \n        where M : Monad<M>, Fallible<Error, M> =>\n        f(this);\n    \n    /// <summary>\n    /// For each error in this structure, invoke the `f` function and\n    /// monoid combine it with the subsequent value.\n    ///\n    /// If any `f` invocation yields a failure, then subsequent error\n    /// values may be processed.  This is dependent on the `M` monoid. \n    /// </summary>\n    /// <remarks>\n    /// The aggregated `K〈M, A〉` is returned.\n    /// </remarks>\n    /// <param name=\"f\">Function</param>\n    /// <returns>The aggregated `K〈M, A〉` is returned.</returns>\n    [Pure]\n    public virtual K<M, A> FoldM<M, A>(Func<Error, K<M, A>> f) \n        where M : MonoidK<M> =>\n        f(this);\n\n    /// <summary>\n    /// True if the error is exceptional\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public abstract bool IsExceptional { get; }\n\n    /// <summary>\n    /// True if the error is expected\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public abstract bool IsExpected { get; }\n\n    /// <summary>\n    /// Get the first error (this will be `Errors.None` if there are zero errors)\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public virtual Error Head =>\n        this;\n\n    /// <summary>\n    /// Get the errors with the head removed (this may be `Errors.None` if there are zero errors in the tail)\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public virtual Error Tail =>\n        Errors.None;\n\n    /// <summary>\n    /// This type can contain zero or more errors.\n    ///\n    /// If `IsEmpty` is `true` then this is like `None` in `Option`: still an error, but without any specific\n    /// information about the error.\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public virtual bool IsEmpty =>\n        false;\n\n    /// <summary>\n    /// This type can contain zero or more errors.  This property returns the number of information carrying errors.\n    ///\n    /// If `Count` is `0` then this is like `None` in `Option`: still an error, but without any specific information\n    /// about the error.\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public virtual int Count =>\n        1;\n\n    /// <summary>\n    /// If this error represents an exceptional error, then this will return that exception, otherwise it will\n    /// generate a new ErrorException that contains the code, message, and inner of this Error.\n    /// </summary>\n    [Pure]\n    public virtual Exception ToException() =>\n        ToErrorException();\n\n    /// <summary>\n    /// If this error represents an exceptional error, then this will return that exception, otherwise `None`\n    /// </summary>\n    [Pure]\n    public Option<Exception> Exception =>\n        IsExceptional\n            ? Some(ToException())\n            : None;\n\n    /// <summary>\n    /// Convert to an `ErrorException` which is like `Error` but derived from the `Exception` hierarchy\n    /// </summary>\n    [Pure]\n    public abstract ErrorException ToErrorException();\n    \n    /// <summary>\n    /// Append an error to this error\n    /// </summary>\n    /// <remarks>Single errors will be converted to `ManyErrors`;  `ManyErrors` will have their collection updated</remarks>\n    /// <param name=\"error\">Error</param>\n    /// <returns></returns>\n    [Pure]\n    public Error Combine(Error error) =>\n        (this, error) switch\n        {\n            ({IsEmpty: true}, var e)       => e,\n            (var e, {IsEmpty: true})       => e,\n            (ManyErrors e1, ManyErrors e2) => new ManyErrors(e1.Errors + e2.Errors), \n            (ManyErrors e1, var e2)        => new ManyErrors(e1.Errors.Add(e2)), \n            (var e1,        ManyErrors e2) => new ManyErrors(e1.Cons(e2.Errors)), \n            (var e1,        var e2)        => new ManyErrors(Seq(e1, e2)) \n        };\n\n    [Pure]\n    public static Error Empty =>\n        ManyErrors.Empty;\n    \n    /// <summary>\n    /// Append an error to this error\n    /// </summary>\n    /// <remarks>Single errors will be converted to `ManyErrors`;  `ManyErrors` will have their collection updated</remarks>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error operator+(Error lhs, Error rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public virtual Iterable<Error> AsIterable()\n    {\n        return Iterable.createRange(go());\n        IEnumerable<Error> go() \n        {\n            yield return this;\n        }\n    }\n\n    /// <summary>\n    /// Convert the error to a string\n    /// </summary>\n    [Pure]\n    public override string ToString() => \n        Message;\n\n    /// <summary>\n    /// Create an `Exceptional` error \n    /// </summary>\n    /// <param name=\"thisException\">Exception</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error New(Exception? thisException) =>\n        thisException switch\n        {\n            null                               => Errors.None,\n            WrappedErrorExceptionalException w => w.ToError(),\n            WrappedErrorExpectedException w    => w.ToError(),\n            ErrorException e                   => e.ToError(),\n            OperationCanceledException         => Errors.Cancelled,\n            TimeoutException                   => Errors.TimedOut,\n            AggregateException a               => ManyErrors.FromAggregate(a),\n            var e                              => new Exceptional(e)\n        };\n        \n\n    /// <summary>\n    /// Create a `Exceptional` error with an overriden message.  This can be useful for sanitising the display message\n    /// when internally we're carrying the exception. \n    /// </summary>\n    /// <param name=\"message\">Error message</param>\n    /// <param name=\"thisException\">Exception</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error New(string message, Exception? thisException) =>\n        new Exceptional(message, thisException ?? new BottomException());\n\n    /// <summary>\n    /// Create an `Expected` error \n    /// </summary>\n    /// <param name=\"message\">Error message</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error New(string message) =>\n        new Expected(message, 0, None);\n\n    /// <summary>\n    /// Create an `Expected` error \n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"message\">Error message</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error New(int code, string message) =>\n        new Expected(message, code, None);\n    \n    /// <summary>\n    /// Create an `Expected` error \n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"message\">Error message</param>\n    /// <param name=\"inner\">The inner error to this error</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error New(int code, string message, Error inner) =>\n        new Expected(message, code, inner);\n\n    /// <summary>\n    /// Create an `Expected` error \n    /// </summary>\n    /// <param name=\"message\">Error message</param>\n    /// <param name=\"inner\">The inner error to this error</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error New(string message, Error inner) =>\n        new Expected(message, 0, inner);\n\n    /// <summary>\n    /// Create a `ManyErrors` error \n    /// </summary>\n    /// <remarks>Collects many errors into a single `Error` type, called `ManyErrors`</remarks>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"inner\">The inner error to this error</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error Many(params Error[] errors) =>\n        errors.Length == 0\n            ? Errors.None\n            : errors.Length == 1\n                ? errors[0]\n                : new ManyErrors(errors.AsIterable().ToSeq());\n\n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"inner\">The inner error to this error</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Error Many(Seq<Error> errors) =>\n        errors.IsEmpty\n            ? Errors.None\n            : errors.Tail.IsEmpty\n                ? (Error)errors.Head\n                : new ManyErrors(errors);\n\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static explicit operator Error(string e) =>\n        New(e);\n\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Error((int Code, string Message) e) =>\n        New(e.Code, e.Message);\n\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Error(Exception e) =>\n        New(e);\n\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Exception(Error e) =>\n        e.ToException();\n\n    /// <summary>\n    /// Attempt to recover an error from an object.\n    /// Will accept Error, ErrorException, Exception, string, Option〈Error〉\n    /// If it fails, Errors.Bottom is returned\n    /// </summary>\n    [Pure]\n    public static Error FromObject(object? value) =>\n        value switch\n        {\n            Error err                          => err,\n            WrappedErrorExceptionalException w => w.ToError(),\n            WrappedErrorExpectedException w    => w.ToError(),\n            ErrorException ex                  => ex.ToError(),\n            Exception ex                       => New(ex),\n            string str                         => New(str),\n            Option<Error> oerr                 => oerr.IfNone(Errors.Bottom),\n            _                                  => Errors.Bottom\n        };\n    \n    [Pure]\n    internal static Option<FAIL> Convert<FAIL>(object? err) => \n        err switch\n    {\n        // Messy, but we're doing our best to recover an error rather than return Bottom\n            \n        FAIL fail                                           => fail,\n        Exception e  when typeof(FAIL) == typeof(Error)     => (FAIL)(object)New(e),\n        Exception e  when typeof(FAIL) == typeof(string)    => (FAIL)(object)e.Message,\n        Error e      when typeof(FAIL) == typeof(Exception) => (FAIL)(object)e.ToException(),\n        Error e      when typeof(FAIL) == typeof(string)    => (FAIL)(object)e.ToString(),\n        string e     when typeof(FAIL) == typeof(Exception) => (FAIL)(object)new Exception(e),\n        string e     when typeof(FAIL) == typeof(Error)     => (FAIL)(object)New(e),\n        _ => None\n    };\n\n    /// <summary>\n    /// Throw the error as an exception\n    /// </summary>\n    public Unit Throw()\n    {\n        ExceptionDispatchInfo.Capture(ToException()).Throw();\n        return default;\n    }\n\n    /// <summary>\n    /// Throw the error as an exception\n    /// </summary>\n    public virtual R Throw<R>()\n    {\n        ExceptionDispatchInfo.Capture(ToException()).Throw();\n        return default;\n    }\n\n    protected virtual bool PrintMembers(StringBuilder builder)\n    {\n        builder.Append(\"Message = \");\n        builder.Append(Message);\n        if (Code != 0)\n        {\n            builder.Append(\", Code = \");\n            builder.Append(Code);\n        }\n        return true;\n    }\n}\n\n/// <summary>\n/// Contains the following:\n/// \n/// * `Code` - an integer value\n/// * `Message` - display text\n/// * `Option〈Error〉` - a nested inner error\n/// \n/// It returns `false` when `IsExceptional` is called against it; and `true` when `IsExpected` is\n/// called against it.\n/// \n/// Equality is done via the `Code`, so any two `Expected` errors with the same `Code` will be considered\n/// the same.  This is useful when using the `@catch` behaviours with the `Aff` and `Eff` monads.  If the\n/// `Code` is `0` then equality is done by comparing `Message`.\n/// \n/// > This allows for localised error messages where the message is ignored when matching/catching\n/// </summary>\n/// <param name=\"Message\">Error message</param>\n/// <param name=\"Code\">Error code</param>\n/// <param name=\"Inner\">Optional inner error</param>\n[DataContract]\npublic record Expected(string Message, int Code, Option<Error> Inner = default) : Error\n{\n    /// <summary>\n    /// Error message\n    /// </summary>\n    [Pure]\n    [DataMember] \n    public override string Message { get; } = \n        Message;\n\n    /// <summary>\n    /// Error code\n    /// </summary>\n    [Pure]\n    [DataMember] \n    public override int Code { get; } = \n        Code;\n    \n    /// <summary>\n    /// Inner error\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override Option<Error> Inner { get; } = \n        Inner;\n    \n    [Pure]\n    public override string ToString() => \n        Message;\n    \n    /// <summary>\n    /// Generates a new `ErrorException` that contains the `Code`, `Message`, and `Inner` of this `Error`.\n    /// </summary>\n    [Pure]\n    public override ErrorException ToErrorException() => \n        new WrappedErrorExpectedException(this);\n\n    public override R Throw<R>() => \n        throw ToErrorException();\n\n    /// <summary>\n    /// Returns false because this type isn't exceptional\n    /// </summary>\n    [Pure]\n    public override bool HasException<E>() =>\n        false;\n\n    /// <summary>\n    /// True if the error is exceptional\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsExceptional =>\n        false;\n\n    /// <summary>\n    /// True if the error is expected\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsExpected =>\n        true;\n}\n\n/// <summary>\n/// This contains an `Exception` is the classic sense.  This also returns `true` when `IsExceptional` is \n/// called against it; and `false` when `IsExpected` is called against it.  \n/// </summary>\n/// <remarks>\n/// If this record is constructed via deserialisation, or the default constructor then the internal `Exception`\n/// will be `null`.  This is intentional to stop exceptions leaking over application boundaries.  The type will\n/// gracefully handle that, but all stack-trace information (and the like) will be erased.  It is still considered\n/// an exceptional error, however.\n/// </remarks>\n[DataContract]\npublic record Exceptional(string Message, int Code) : Error\n{\n    /// <summary>\n    /// Internal exception.  If this record is constructed via deserialisation, or the default constructor then this\n    /// value will be `null`.  This is intentional to stop exceptions leaking over application boundaries. \n    /// </summary>\n    [IgnoreDataMember]\n    readonly Exception? Value;\n    \n    /// <summary>\n    /// Construct from an exception\n    /// </summary>\n    /// <param name=\"value\">Exception</param>\n    internal Exceptional(Exception value) : this(value.Message, value.HResult) =>\n        Value = value;\n\n    /// <summary>\n    /// Construct from an exception, but override the message\n    /// </summary>\n    /// <param name=\"message\">Message to override with</param>\n    /// <param name=\"value\">Exception</param>\n    internal Exceptional(string message, Exception value) : this(message, value.HResult) =>\n        Value = value;\n\n    [DataMember]\n    public override string Message { get; } = Message;\n\n    [DataMember]\n    public override int Code { get; } = Code;\n\n    public override string ToString() => \n        Message;\n\n    /// <summary>\n    /// Returns the inner exception as an `Error` (if one exists), `None` otherwise\n    /// </summary>\n    [Pure]\n    public override Option<Error> Inner => \n        Value?.InnerException == null\n            ? None\n            : New(Value.InnerException);\n    \n    /// <summary>\n    /// Gets the `Exception`\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public override Exception ToException() => \n        Value ?? new ExceptionalException(Message, Code);\n    \n    /// <summary>\n    /// Gets the `ErrorException`\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public override ErrorException ToErrorException() =>\n        Value == null\n            ? new WrappedErrorExceptionalException(this)\n            : new ExceptionalException(Value);\n\n    public override R Throw<R>() =>\n        Value is null\n            ? throw ToErrorException()\n            : Value.Rethrow<R>();\n\n    /// <summary>\n    /// Return true if the exceptional error is of type E\n    /// </summary>\n    [Pure]\n    public override bool HasException<E>() =>\n        Value is E;\n\n    [Pure]\n    public override bool Is(Error error) =>\n        error is ManyErrors errors\n            ? errors.Errors.Exists(Is) \n            : Value == null\n                ? error.IsExceptional && Code == error.Code && Message == error.Message \n                : error.IsExceptional && Value.GetType().IsInstanceOfType(error.ToException());\n\n    /// <summary>\n    /// True if the error is exceptional\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsExceptional =>\n        true;\n\n    /// <summary>\n    /// True if the error is expected\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsExpected =>\n        false;\n}\n\n/// <summary>\n/// Bottom error\n/// </summary>\n[DataContract]\npublic sealed record BottomError() : Exceptional(BottomException.Default)\n{\n    public static readonly Error Default = new BottomError();\n    \n    [DataMember]\n    public override int Code => \n        ErrorCodes.Bottom; \n\n    [DataMember]\n    public override string Message => \n        Errors.BottomText;\n\n    public override string ToString() => \n        Message;\n    \n    /// <summary>\n    /// Gets the Exception\n    /// </summary>\n    /// <returns></returns>\n    public override Exception ToException() => \n        BottomException.Default;\n    \n    /// <summary>\n    /// Gets the `ErrorException`\n    /// </summary>\n    /// <returns></returns>\n    public override ErrorException ToErrorException() => \n        BottomException.Default;\n\n    public override R Throw<R>() =>\n        throw new BottomException();\n\n    /// <summary>\n    /// Return true if the exceptional error is of type E\n    /// </summary>\n    [Pure]\n    public override bool HasException<E>() =>\n        BottomException.Default is E;\n\n    /// <summary>\n    /// Return true this error contains or *is* the `error` provided\n    /// </summary>\n    [Pure]\n    public override bool Is(Error error) =>\n        error is ManyErrors errors\n            ? errors.Errors.Exists(Is) \n            : error is BottomError;\n\n    /// <summary>\n    /// True if the error is exceptional\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsExceptional =>\n        true;\n\n    /// <summary>\n    /// True if the error is expected\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsExpected =>\n        false;\n}\n\n/// <summary>\n/// `ManyErrors` allows for zero or more errors to be collected.  This is useful for applicative behaviours\n/// like validation.  It effectively turns the `Error` type into a monoid, with 'zero' being `Errors.None`,\n/// and 'append' coming from the `Append` method or use of `operator+` \n/// </summary>\n/// <param name=\"Errors\">Errors</param>\n[DataContract]\npublic sealed record ManyErrors([property: DataMember] Seq<Error> Errors) : Error\n{\n    public new static Error Empty { get; } =\n        new ManyErrors(Seq.empty<Error>()); \n\n    public override int Code => \n        ErrorCodes.ManyErrors;\n\n    public override string Message { get; } =\n        Errors.ToFullArrayString();\n\n    public override string ToString() => \n        Errors.ToFullArrayString();\n\n    /// <summary>\n    /// Gets the `Exception`\n    /// </summary>\n    public override Exception ToException() => \n        new AggregateException(Errors.Map(static e => e.ToException()));\n\n    /// <summary>\n    /// Gets the `ErrorException`\n    /// </summary>\n    public override ErrorException ToErrorException() =>\n        new ManyExceptions(Errors.Map(static e => e.ToErrorException()));\n\n    public override R Throw<R>() =>\n        throw ToErrorException();\n    \n    /// <summary>\n    /// Return true if an exception of type E is contained within \n    /// </summary>\n    [Pure]\n    public override bool HasException<E>() =>\n        Errors.Exists(static e => e.HasException<E>());\n\n    /// <summary>\n    /// Return true if an `Error` with `Code` equalling `code` is contained within \n    /// </summary>\n    [Pure]\n    public override bool HasCode(int code) =>\n        Errors.Exists(e => e.Code == code);\n    \n    [Pure]\n    public override bool IsType<E>() =>\n        Errors.Exists(static e => e.IsType<E>());\n    \n    /// <summary>\n    /// Return true this error contains or *is* the `error` provided\n    /// </summary>\n    [Pure]\n    public override bool Is(Error error) =>\n        Errors.Exists(e => e.Is(error));\n\n    /// <summary>\n    /// Filter the error(s) so that only errors of type `E` are left\n    /// </summary>\n    /// <remarks>\n    /// If no errors match, then returns `Errors.None`.\n    /// </remarks>\n    [Pure]\n    public override Error Filter<E>() =>\n        Errors.Choose(e => e.IsType<E>() ? Some(e.Filter<E>()) : None) switch\n        {\n            []     => Common.Errors.None,\n            var es => Many(es)\n        };\n\n    /// <summary>\n    /// For each error in this structure, invoke the `f` function and\n    /// monad bind it with the subsequent value.\n    ///\n    /// If any `f` invocation yields a failure, then subsequent error will\n    /// not be processed.\n    /// monad\n    /// </summary>\n    /// <remarks>\n    /// The final `A` is returned.\n    /// </remarks>\n    /// <param name=\"f\">Function</param>\n    /// <returns>The final `A` is returned.</returns>\n    [Pure]\n    public override K<M, A> ForAllM<M, A>(Func<Error, K<M, A>> f)\n    {\n        if(Errors.IsEmpty) return M.Fail<A>(this);\n        var result = Errors[0].ForAllM(f);\n        foreach (var e in Errors.Tail)\n        {\n            result = result.Bind(_ => e.ForAllM(f));\n        }\n        return result;\n    }\n    \n    /// <summary>\n    /// For each error in this structure, invoke the `f` function and\n    /// monoid combine it with the subsequent value.\n    ///\n    /// If any `f` invocation yields a failure, then subsequent error\n    /// values may be processed.  This is dependent on the `M` monoid. \n    /// </summary>\n    /// <remarks>\n    /// The aggregated `K〈M, A〉` is returned.\n    /// </remarks>\n    /// <param name=\"f\">Function</param>\n    /// <returns>The aggregated `K〈M, A〉` is returned.</returns>\n    [Pure]\n    public override K<M, A> FoldM<M, A>(Func<Error, K<M, A>> f)\n    {\n        var result = M.Empty<A>();\n        foreach (var e in Errors)\n        {\n            result = result.Combine(e.FoldM(f));\n        }\n        return result;\n    }\n\n    /// <summary>\n    /// True if any errors are exceptional\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsExceptional =>\n        Errors.Exists(static e => e.IsExceptional);\n\n    /// <summary>\n    /// True if all the errors are expected\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsExpected =>\n        Errors.ForAll(static e => e.IsExpected);\n\n    /// <summary>\n    /// Get the first error (this may be `Errors.None` if there are zero errors)\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override Error Head =>\n        Errors.IsEmpty\n            ? Common.Errors.None\n            : (Error)Errors.Head;\n\n    /// <summary>\n    /// Get the errors with the head removed (this may be `Errors.None` if there are zero errors in the tail)\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override Error Tail =>\n        Errors.Tail.IsEmpty\n            ? Common.Errors.None\n            : this with {Errors = Errors.Tail};\n\n    /// <summary>\n    /// This type can contain zero or more errors.  If `IsEmpty` is `true` then this is like `None` in `Option`:  still\n    /// an error, but without any specific information about the error.\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override bool IsEmpty =>\n        Errors.IsEmpty;\n\n    /// <summary>\n    /// This type can contain zero or more errors.  This property returns the number of information carrying errors.\n    ///\n    /// If `Count` is `0` then this is like `None` in `Option`: still an error, but without any specific information\n    /// about the error.\n    /// </summary>\n    [Pure]\n    [IgnoreDataMember]\n    public override int Count =>\n        Errors.Count;\n\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override Iterable<Error> AsIterable() =>\n        Errors.AsIterable();\n\n    [Pure]\n    internal static Error FromAggregate(AggregateException? e)\n    {\n        if (e is null) return Common.Errors.None;\n        var errs = e.InnerExceptions.Bind(x => New(x).AsIterable()).AsIterable().ToSeq();\n        if (errs.Count == 0) return Common.Errors.None;\n        if (errs.Count == 1) return (Error)errs.Head;\n        return Many(errs);\n    }\n} \n"
  },
  {
    "path": "LanguageExt.Core/Common/ErrorCodes.cs",
    "content": "namespace LanguageExt.Common;\n\npublic static class ErrorCodes\n{\n    /// <summary>\n    /// An error that indicates a value from an operation couldn't be evaluated.  This is a hard\n    /// fail for systems that depend on expressions to produce results. \n    /// </summary>\n    public const int Bottom = -2000000000;\n\n    /// <summary>\n    /// Cancelled error\n    /// </summary>\n    public const int Cancelled = -2000000001;\n\n    /// <summary>\n    /// Timed-out error\n    /// </summary>\n    public const int TimedOut = -2000000002;\n\n    /// <summary>\n    /// Sequence-empty error\n    /// </summary>\n    public const int SequenceEmpty = -2000000003;\n\n    /// <summary>\n    /// Closed error\n    /// </summary>\n    public const int Closed = -2000000004;\n\n    /// <summary>\n    /// Parsing error\n    /// </summary>\n    public const int ParseError = -2000000005;\n\n    /// <summary>\n    /// Error code that represents multiple errors\n    /// </summary>\n    public const int ManyErrors = -2000000006;\n\n    /// <summary>\n    /// IO monad not in transformer stack or `MonadIO.LiftIO` not implemented\n    /// </summary>\n    public const int LiftIONotSupported = -2000000007;\n\n    /// <summary>\n    /// IO monad not in transformer stack or `MonadIO.Fork` not implemented \n    /// </summary>\n    public const int ForkIONotSupported = -2000000008;\n\n    /// <summary>\n    /// IO monad not in transformer stack or `MonadUnliftIO.ToIO` not implemented \n    /// </summary>\n    public const int ToIONotSupported = -2000000009;\n\n    /// <summary>\n    /// End of stream error code\n    /// </summary>\n    public const int EndOfStream = -2000000010;\n\n    /// <summary>\n    /// Validation failed\n    /// </summary>\n    public const int ValidationFailed = -2000000011;\n\n    /// <summary>\n    /// Source complete\n    /// </summary>\n    public const int SourceCompleted = -2000000012;\n\n    /// <summary>\n    /// Source is closed\n    /// </summary>\n    public const int SourceClosed = -2000000013;\n\n    /// <summary>\n    /// The programmer is trying to extend the `IO` type, they need to use specific base-types:\n    ///\n    ///     * `InvokeAsync`\n    ///     * `InvokeSync`\n    ///     * `InvokeAsyncIO`\n    ///     * `InvokeSyncIO`\n    ///     * `IOCatch`\n    /// </summary>\n    public const int IODSLExtension = -2000000014;\n\n    /// <summary>\n    /// Sink full error\n    /// </summary>\n    public const int SinkFull = -2000000015;\n}\n\n"
  },
  {
    "path": "LanguageExt.Core/Common/ErrorException.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.ExceptionServices;\nusing System.Text;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Common;\n\n/// <summary>\n/// Error value\n/// </summary>\n/// <remarks>\n/// This is a pair to the `Error` type, to allow `Error` to be converted to-and-from a classic `Exception`.\n///\n/// This allows code that can't handle the `Error` type to still throw something that keeps the fidelity of the `Error`\n/// type, and can be converted directly to an `Error` in a `catch` block. \n/// </remarks>\n/// <remarks>\n/// Unlike exceptions, `Error` can be either:\n/// \n/// * `ExceptionalException`    - representing an unexpected error\n/// * `ExpectedException`       - representing an expected error\n/// * `ManyExceptions`          - representing many errors\n///\n/// i.e. it is either created from an exception or it isn't.  This allows for expected errors to be represented\n/// without throwing exceptions.  \n/// </remarks>\npublic abstract class ErrorException : Exception, IEnumerable<ErrorException>, Monoid<ErrorException>\n{\n    protected ErrorException(int code) =>\n        HResult = code;\n    \n    /// <summary>\n    /// Error code\n    /// </summary>\n    [Pure]\n    public abstract int Code { get; }\n\n    /// <summary>\n    /// Inner error\n    /// </summary>\n    [Pure]\n    public abstract Option<ErrorException> Inner { get; }\n\n    /// <summary>\n    /// Convert to an `Error`\n    /// </summary>\n    [Pure]\n    public abstract Error ToError();\n\n    /// <summary>\n    /// This type can contain zero or more errors.  If `IsEmpty` is `true` then this is like `None` in `Option`:  still\n    /// an error, but without any specific information about the error.\n    /// </summary>\n    [Pure]\n    public virtual bool IsEmpty =>\n        false;\n\n    /// <summary>\n    /// True if the error is exceptional\n    /// </summary>\n    [Pure]\n    public abstract bool IsExceptional { get; }\n\n    /// <summary>\n    /// True if the error is expected\n    /// </summary>\n    [Pure]\n    public abstract bool IsExpected { get; }\n\n    /// <summary>\n    /// Append an error to this error\n    /// </summary>\n    /// <remarks>Single errors will be converted to `ManyErrors`;  `ManyErrors` will have their collection updated</remarks>\n    [Pure]\n    public abstract ErrorException Combine(ErrorException error);\n\n    [Pure]\n    public static ErrorException Empty => \n        ManyExceptions.Empty;\n    \n    /// <summary>\n    /// Append an error to this error\n    /// </summary>\n    /// <remarks>Single errors will be converted to `ManyErrors`;  `ManyErrors` will have their collection updated</remarks>\n    [Pure]\n    public static ErrorException operator+(ErrorException lhs, ErrorException rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure]\n    public virtual IEnumerator<ErrorException> GetEnumerator()\n    {\n        yield return this;\n    }\n\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();\n\n    /// <summary>\n    /// Convert the error to a string\n    /// </summary>\n    [Pure]\n    public override string ToString() => \n        Message;\n\n\n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"message\">Error message</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ErrorException New(Exception thisException) =>\n        new ExceptionalException(thisException);\n\n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"message\">Error message</param>\n    /// <param name=\"thisException\">The exception this error represents</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ErrorException New(string message, Exception thisException) =>\n        new ExceptionalException(message, thisException);\n\n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"message\">Error message</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ErrorException New(string message) =>\n        new ExpectedException(message, 0, None);\n\n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"message\">Error message</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ErrorException New(int code, string message) =>\n        new ExpectedException(message, code, None);\n    \n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"message\">Error message</param>\n    /// <param name=\"inner\">The inner error to this error</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ErrorException New(int code, string message, ErrorException inner) =>\n        new ExpectedException(message, code, inner);\n\n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"inner\">The inner error to this error</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ErrorException New(string message, ErrorException inner) =>\n        new ExpectedException(message, 0, inner);\n\n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"inner\">The inner error to this error</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ErrorException Many(params ErrorException[] errors) =>\n        new ManyExceptions(errors.AsIterable().ToSeq());\n\n    /// <summary>\n    /// Create a new error \n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"inner\">The inner error to this error</param>\n    [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ErrorException Many(Seq<ErrorException> errors) =>\n        new ManyExceptions(errors);\n}\n\n/// <summary>\n/// Represents expected errors\n/// </summary>\npublic class ExpectedException(string message, int code, Option<ErrorException> inner = default) : ErrorException(code)\n{\n    /// <summary>\n    /// Error code\n    /// </summary>\n    [Pure]\n    public override int Code { get; } = code;\n\n    /// <summary>\n    /// Error message\n    /// </summary>\n    [Pure]\n    public override string Message { get; } = message;\n\n    /// <summary>\n    /// Convert the error to a string\n    /// </summary>\n    [Pure]\n    public override string ToString() => \n        Message;\n\n    /// <summary>\n    /// Inner error\n    /// </summary>\n    [Pure]\n    public override Option<ErrorException> Inner { get; } = inner;\n\n    /// <summary>\n    /// Generates a new `Error` that contains the `Code`, `Message`, and `Inner` of this `ErrorException`.\n    /// </summary>\n    [Pure]\n    public override Error ToError() => \n        new Expected(Message, Code, Inner.Map(static e => e.ToError()));\n\n    /// <summary>\n    /// True if the error is exceptional\n    /// </summary>\n    [Pure]\n    public override bool IsExceptional =>\n        false;\n\n    /// <summary>\n    /// True if the error is expected\n    /// </summary>\n    [Pure]\n    public override bool IsExpected =>\n        true;\n\n    /// <summary>\n    /// Append an error to this error\n    /// </summary>\n    /// <remarks>Single errors will be converted to `ManyErrors`;  `ManyErrors` will have their collection updated</remarks>\n    [Pure]\n    public override ErrorException Combine(ErrorException error) =>\n        error is ManyExceptions m\n            ? new ManyExceptions(error.Cons(m.Errors))\n            : new ManyExceptions(Seq(this, error));\n}\n\n/// <summary>\n/// Wraps an `Error` maintaining its type for subsequent conversion back to an `Error` later\n/// </summary>\n/// <param name=\"Error\"></param>\npublic sealed class WrappedErrorExpectedException(Error Error) : \n    ExpectedException(Error.Message, Error.Code, Error.Inner.Map(e => e.ToErrorException()))\n{\n    /// <summary>\n    /// Convert back to an `Error`\n    /// </summary>\n    /// <returns></returns>\n    public override Error ToError() => \n        Error;\n    \n    /// <summary>\n    /// Convert the error to a string\n    /// </summary>\n    [Pure]\n    public override string ToString() => \n        Error.ToString();\n}\n\n/// <summary>\n/// Represents an exceptional (unexpected) error\n/// </summary>\n/// <param name=\"Exception\">Exceptional error</param>\npublic class ExceptionalException : ErrorException\n{\n    public ExceptionalException(Exception Exception) : base(Exception.HResult)\n    {\n        this.Exception = Exception;\n        Code = Exception.HResult;\n        Message = Exception.Message;\n    }\n\n    public ExceptionalException(string Message, int Code) : base(Code)\n    {\n        this.Code = Code;\n        this.Message = Message;\n    }\n\n    public ExceptionalException(string Message, Exception Exception) : base(Exception.HResult)\n    {\n        Code = Exception.HResult;\n        this.Message = Message;\n    }\n\n    public readonly Exception? Exception;\n    public override int Code { get; }\n    public override string Message { get; }\n    \n    /// <summary>\n    /// Convert the error to a string\n    /// </summary>\n    [Pure]\n    public override string ToString() => \n        Message;\n\n    /// <summary>\n    /// Returns the inner exception as an `Error` (if one exists), None otherwise\n    /// </summary>\n    [Pure]\n    public override Option<ErrorException> Inner => \n        Exception?.InnerException == null\n            ? None\n            : New(Exception.InnerException);\n\n    /// <summary>\n    /// Gets the `Error`\n    /// </summary>\n    /// <returns></returns>\n    public override Error ToError() =>\n        Exception == null\n            ? new Exceptional(Message, Code)\n            : new Exceptional(Exception);\n\n                /// <summary>\n    /// True if the error is exceptional\n    /// </summary>\n    [Pure]\n    public override bool IsExceptional =>\n        true;\n\n    /// <summary>\n    /// True if the error is expected\n    /// </summary>\n    [Pure]\n    public override bool IsExpected =>\n        false;\n\n    /// <summary>\n    /// Append an error to this error\n    /// </summary>\n    /// <remarks>Single errors will be converted to `ManyErrors`;  `ManyErrors` will have their collection updated</remarks>\n    /// <param name=\"error\">Error</param>\n    /// <returns></returns>\n    [Pure]\n    public override ErrorException Combine(ErrorException error) =>\n        error is ManyExceptions m\n            ? new ManyExceptions(error.Cons(m.Errors))\n            : new ManyExceptions(Seq(this, error));\n}\n\n/// <summary>\n/// Wraps an `Error` maintaining its type for subsequent conversion back to an `Error` later\n/// </summary>\n/// <param name=\"Error\"></param>\npublic sealed class WrappedErrorExceptionalException(Error Error) : \n    ExceptionalException(Error.Message, Error.Code)\n{\n    /// <summary>\n    /// Convert back to an `Error`\n    /// </summary>\n    /// <returns></returns>\n    public override Error ToError() => \n        Error;\n    \n    /// <summary>\n    /// Convert the error to a string\n    /// </summary>\n    [Pure]\n    public override string ToString() => \n        Message;\n}\n\n/// <summary>\n/// Represents multiple errors\n/// </summary>\n/// <param name=\"Errors\">Errors</param>\npublic sealed class ManyExceptions(Seq<ErrorException> errors) : ErrorException(0)\n{\n    public new static ErrorException Empty { get; } = new ManyExceptions([]);\n\n    public readonly Seq<ErrorException> Errors = errors;\n\n    public override int Code => \n        ErrorCodes.ManyErrors;\n\n    public override string Message =>\n        Errors.ToFullArrayString();\n\n    /// <summary>\n    /// Returns the inner exception as an `Error` (if one exists), None otherwise\n    /// </summary>\n    [Pure]\n    public override Option<ErrorException> Inner => \n        None;\n    \n    /// <summary>\n    /// Gets the Exception\n    /// </summary>\n    public override Error ToError() => \n        new ManyErrors(Errors.Map(static e => e.ToError()));\n    \n    /// <summary>\n    /// Convert the error to a string\n    /// </summary>\n    [Pure]\n    public override string ToString() => \n        Errors.ToFullArrayString();\n\n    /// <summary>\n    /// This type can contain zero or more errors.  If `IsEmpty` is `true` then this is like `None` in `Option`:  still\n    /// an error, but without any specific information about the error.\n    /// </summary>\n    [Pure]\n    public override bool IsEmpty =>\n        Errors.IsEmpty;\n\n    /// <summary>\n    /// True if any of the errors are exceptional\n    /// </summary>\n    [Pure]\n    public override bool IsExceptional =>\n        Errors.Exists(static e => e.IsExceptional);\n\n    /// <summary>\n    /// True if all the errors are expected\n    /// </summary>\n    [Pure]\n    public override bool IsExpected =>\n        Errors.ForAll(static e => e.IsExpected);\n\n    /// <summary>\n    /// Append an error to this error\n    /// </summary>\n    /// <remarks>Single errors will be converted to `ManyErrors`;  `ManyErrors` will have their collection updated</remarks>\n    /// <param name=\"error\">Error</param>\n    /// <returns></returns>\n    [Pure]\n    public override ErrorException Combine(ErrorException error) =>\n        error is ManyExceptions m\n            ? new ManyExceptions(Errors + m.Errors)\n            : new ManyExceptions(Seq(this, error));\n\n    [Pure]\n    public override IEnumerator<ErrorException> GetEnumerator() =>\n        Errors.GetEnumerator();\n\n}\n\n\n/// <summary>\n/// Value is bottom\n/// </summary>\n[Serializable]\npublic class BottomException() : \n    ExceptionalException(Errors.BottomText, ErrorCodes.Bottom)\n{\n    public static readonly BottomException Default;\n\n    static BottomException() => \n        Default = new();\n\n    public override string Message =>\n        Errors.BottomText;\n\n    public override int Code =>\n        ErrorCodes.Bottom;\n    \n    public override Option<ErrorException> Inner =>\n        default;\n    \n    public override Error ToError() => \n        BottomError.Default;\n    \n    public override ErrorException Combine(ErrorException error) => throw new NotImplementedException();\n}\n\npublic static class ExceptionExtensions\n{\n    /// <summary>\n    /// Throw the error as an exception\n    /// </summary>\n    public static Unit Rethrow(this Exception e)\n    {\n        ExceptionDispatchInfo.Capture(e).Throw();\n        return default;\n    }\n\n    /// <summary>\n    /// Throw the error as an exception\n    /// </summary>\n    public static R Rethrow<R>(this Exception e)\n    {\n        ExceptionDispatchInfo.Capture(e).Throw();\n        return default;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Common/Errors.cs",
    "content": "﻿namespace LanguageExt.Common;\n\npublic static class Errors\n{\n    /// <summary>\n    /// An error state without any error values\n    /// </summary>\n    public static readonly Error None = new ManyErrors(Seq<Error>.Empty);\n\n    /// <summary>\n    /// Bottom error text\n    /// </summary>\n    public const string BottomText =\n        \"In a bottom state and therefore cannot proceed.  This can happen when an expression couldn't \"           +\n        \"evaluate to a value.  This might be due to filter/where, or sometimes if a `struct` wasn't initialised \" +\n        \"properly (i.e. via `default(T)` or an uninitialised member).\";\n        \n    /// <summary>\n    /// An error that indicates a value from an operation couldn't be evaluated.  This is a hard\n    /// fail for systems that depend on expressions to produce results. \n    /// </summary>\n    public static readonly Error Bottom = BottomError.Default;\n\n    /// <summary>\n    /// Cancelled error\n    /// </summary>\n    public static readonly Error Cancelled = (ErrorCodes.Cancelled, \"cancelled\");\n\n    /// <summary>\n    /// Timed-out error\n    /// </summary>\n    public static readonly Error TimedOut = (ErrorCodes.TimedOut, \"timed out\");    \n\n    /// <summary>\n    /// Sequence-empty error\n    /// </summary>\n    public static readonly Error SequenceEmpty = (ErrorCodes.SequenceEmpty, \"sequence empty\");    \n\n    /// <summary>\n    /// Closed error\n    /// </summary>\n    public static readonly Error Closed = (ErrorCodes.Closed, \"closed\");    \n\n    /// <summary>\n    /// Parse error\n    /// </summary>\n    public static Error ParseError(string msg) => (ErrorCodes.ParseError, msg);\n\n    /// <summary>\n    /// IO monad not in transformer stack or `MonadIO.LiftIO` not implemented\n    /// </summary>\n    public static readonly Error LiftIONotSupported = \n        (ErrorCodes.LiftIONotSupported, \n         \"The IO monad is not in the monad-transformer stack or MonadIO.LiftIO has not been implemented in the trait \"   +\n         \"implementation for your monad-type.  Therefore it's not possible to leverage `MonadIO` lifting functionality. \" +\n         \"To resolve this, implement `MonadIO.LiftIO`.\");\n\n    /// <summary>\n    /// Transformer stack has no `ToIO` support error\n    /// </summary>\n    public static readonly Error ToIONotSupported = \n        (ErrorCodes.ToIONotSupported, \n         \"The IO monad is not in the monad-transformer stack or MonadIO.ToIO has not been implemented in the trait \" +\n         \"implementation for your monad-type.  Therefore it's not possible to leverage `MonadIO` unlifting trait \"   +\n         \"functionality. To resolve this, implement `MonadIO.ToIO` and/or `MonadIO.MapIO`.\");\n\n    /// <summary>\n    /// Transformer stack has no `Fork` support error\n    /// </summary>\n    public static readonly Error ForkNotSupported =\n        (ErrorCodes.ForkIONotSupported,\n         \"The IO monad is not in the monad-transformer stack or MonadIO.Fork has not been implemented in the trait \" +\n         \"implementation for your monad-type.\");\n\n    /// <summary>\n    /// Transformer stack has no `Await` support error\n    /// </summary>\n    public static readonly Error AwaitNotSupported =\n        (ErrorCodes.ForkIONotSupported,\n         \"The IO monad is not in the monad-transformer stack or MonadIO.Await has not been implemented in the trait \" +\n         \"implementation for your monad-type.\");\n\n    /// <summary>\n    /// End-of-stream error\n    /// </summary>\n    public static readonly Error EndOfStream = (ErrorCodes.EndOfStream, \"end of stream\");\n\n    /// <summary>\n    /// Validation failed error\n    /// </summary>\n    public static readonly Error ValidationFailed = (ErrorCodes.ValidationFailed, \"validation failed\");\n\n    /// <summary>\n    /// Source completed error\n    /// </summary>\n    public static readonly Error SourceCompleted = (ErrorCodes.SourceCompleted,  \"source completed\");\n\n    /// <summary>\n    /// IO DSL extension error\n    /// </summary>\n    public static readonly Error IODSLExtension = new Exceptional(\n        \"If you are trying to extend the `IO` type then you must use: `InvokeAsync`, `InvokeSync`, `InvokeAsyncIO`, \"+\n        \"`InvokeSyncIO`, or `IOCatch` as the base-type, not `IO`\",\n        ErrorCodes.IODSLExtension);\n\n    /// <summary>\n    /// Sink is full error\n    /// </summary>\n    public static readonly Error SinkFull = new Expected(\"Sink is full\", ErrorCodes.SinkFull);\n\n    /// <summary>\n    /// Source is closed error\n    /// </summary>\n    public static readonly Error SourceClosed = new Expected(\"Source is closed\", ErrorCodes.SourceClosed);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Common/Exceptions.cs",
    "content": "namespace LanguageExt.Common;\n\npublic class Exceptions\n{\n    /// <summary>\n    /// An error state without any error values\n    /// </summary>\n    public static readonly ErrorException None = new ManyExceptions([]);\n\n    /// <summary>\n    /// An error that indicates a value from an operation couldn't be evaluated.  This is a hard\n    /// fail for systems that depend on expressions to produce results. \n    /// </summary>\n    public static readonly ExceptionalException Bottom = new (Errors.Bottom.Message, Errors.Bottom.Code);\n\n    /// <summary>\n    /// Cancelled error\n    /// </summary>\n    public static readonly ExpectedException Cancelled = new (Errors.Cancelled.Message, Errors.Cancelled.Code);\n \n    /// <summary>\n    /// Timed-out error\n    /// </summary>\n    public static readonly ExpectedException TimedOut = new (Errors.TimedOut.Message, Errors.TimedOut.Code);\n\n    /// <summary>\n    /// Sequence-empty error\n    /// </summary>\n    public static readonly ExpectedException SequenceEmpty = new (Errors.SequenceEmpty.Message, Errors.SequenceEmpty.Code);\n    /// <summary>\n    /// Closed error\n    /// </summary>\n    public static readonly ExpectedException Closed = new (Errors.Closed.Message, Errors.Closed.Code);\n\n    /// <summary>\n    /// Parse error code\n    /// </summary>\n    public const int ParseErrorCode = -2000000005;\n\n    /// <summary>\n    /// Parse error\n    /// </summary>\n    public static ExpectedException ParseError(string msg) => new (msg, ErrorCodes.ParseError);\n\n    /// <summary>\n    /// IO monad not in transformer stack error\n    /// </summary>\n    public static readonly ExceptionalException LiftIONotSupported = new (Errors.LiftIONotSupported.Message, Errors.LiftIONotSupported.Code);\n\n    /// <summary>\n    /// Transformer stack has no unliftIO support error\n    /// </summary>\n    public static readonly ExceptionalException UnliftIONotSupported = new (Errors.ToIONotSupported.Message, Errors.ToIONotSupported.Code);\n\n    /// <summary>\n    /// End-of-stream error\n    /// </summary>\n    public static readonly ExpectedException EndOfStream = new (Errors.EndOfStream.Message, Errors.EndOfStream.Code);\n\n    /// <summary>\n    /// Validation failed error\n    /// </summary>\n    public static readonly ExpectedException ValidationFailed = new (Errors.ValidationFailed.Message, Errors.ValidationFailed.Code);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Common/README.md",
    "content": "## `Error`\n\nThe `Error` type works like a discriminated-union, it is an `abstract record` type with many sub-cases\n(which are listed below).  It is used extensively with various monadic types, like `Fin<A>`, the \n_Effect System_ monads of `Eff<A>`, `Eff<RT, A>`, `Aff<A>`, `Aff<RT, A>` and the compositional \nstreaming Pipes features.  \n\n> The reason they're buried in the `Common` namespace is because, `Error` is a common type name.  And so, this gives\nthe programmer a chance to not include it when `using LanguageExt;`\n\n`Error` exists because `Exception` is really only meant for _exceptional_ errors. However, in C#-land we've been trained\nto throw them even for *expected* errors.  \n\nInstead we use `Error` to represent three key types of error:\n\n* `Exceptional` - An unexpected error\n* `Expected`    - An expected error\n* `ManyErrors`  - Many errors (possibly zero)\n\nThese are the key base-types that indicate the *'flavour'* of the error.  For example, a 'user not found' error isn't\nsomething exceptional, it's something we expect *might* happen.  An `OutOfMemoryException` however, *is*\nexceptional - it should never happen, and we should treat it as such.\n\nMost of the time we want sensible handling of expected errors, and bail out completely for something exceptional.  We also want \nto protect ourselves from information leakage.  Leaking exceptional errors via public APIs is a surefire way to open up more\ninformation to hackers than you would like.  The `Error` derived types all try to protect against this kind of leakage without\nlosing the context of the type of error thrown.\n\nEssentially an error is either created from an `Exception` or it isn't.  This allows for expected errors to be\nrepresented without throwing exceptions, but also it allows for more principled error handling.  We can pattern-match on the\ntype, or use some of the built-in properties and methods to inspect the `Error`:\n\n* `IsExceptional` - `true` for exceptional errors.  For `ManyErrors` this is `true` if _any_ of the errors are exceptional.\n* `IsExpected` - `true` for non-exceptional/expected errors.  For `ManyErrors` this is `true` if _all_ of the errors are expected.\n* `Is<E>(E exception)` - `true` if the `Error` is exceptional and any of the the internal `Exception` values are of type `E`.\n* `Is(Error error)` - `true` if the `Error` matches the one provided.  i.e. `error.Is(Errors.TimedOut)`. \n\nThe `Error` type can be constructed to be exceptional or expected.  For example, this is an expected error:\n\n    Error.New(\"This error was expected\")\n\nWhen expected errors are used with codes then equality and matching is done via the code only:\n\n    Error.New(404, \"Page not found\");\n\nAnd this is an exceptional error:\n\n    try\n    {\n        // This wraps up the exceptional error\n    }\n    catch(Exception e)\n    {\n        return Error.New(e);\n    }\n\nFinally, you can collect many errors:\n\n    Error.Many(Error.New(\"error one\"), Error.New(\"error two\"));\n\nOr more simply:\n\n    Error.New(\"error one\") + Error.New(\"error two\")\n\nYou can extend the set of error types (perhaps for passing through extra data) by creating a new \nrecord inherits `Exceptional` or `Expected`:   \n\n    public record BespokeError(bool MyData) \n        : Expected(\"Something bespoke\", 100, None); \n\nBy default the properties of the new error-type won't be serialised.  So, if you want to pass a \npayload over the wire, add the `[property: DataMember]` attribute to each member:\n\n    public record BespokeError([property: DataMember] bool MyData) \n        : Expected(\"Something bespoke\", 100, None); \n\nUsing this technique it's trivial to create new error-types when additional data needs to be moved\naround, but also there's a ton of built-in functionality for the most common use-cases.\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Async/Async.Module.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Async;\n\n/// <summary>\n/// The `Async` module helps transition away from the `Task` / `async` / `await` world and into one\n/// where awaiting is the default setting for concurrent programming and branching/forking is the\n/// thing we do the least.\n///\n/// The `Async.await` function will convert a `Task〈A〉` into an `A` by waiting for the `Task` to\n/// complete; it will yield the thread whilst it's waiting (to play nice with other tasks in the\n/// task-pool).  This is just like the regular `await` keyword without all the ceremony and\n/// colouring of methods.\n///\n/// `Async.fork` lifts a function into an IO monad, forks it, and then runs the IO monad returning\n/// a `ForkIO` object.  The forked operation continues to run in parallel.  The `ForkIO` object\n/// contains two properties: `Await` and `Cancel` that be used to either await the result or\n/// cancel the operation.\n///\n/// These two functions remove the need for methods that are 'tainted' with `Task` or `async` /\n/// `await` mechanics and assume that the thing we will do the most with asynchronous code is to\n/// await it.\n///\n/// This module shouldn't be needed too much, as the IO monad is where most of the asynchrony\n/// should be. But, when converting from existing async/await code, or if you're coming from\n/// language-ext v4, or earlier, where there was lots of `*Async` methods in the key types, then\n/// this module will help ease the transition.\n/// </summary>\npublic static class Async\n{\n    /// <summary>\n    /// Simple awaiter that yields the thread whilst waiting.  Allows for the `Task` to\n    /// be used with synchronous code without blocking any threads for concurrent\n    /// processing.\n    /// </summary>\n    /// <param name=\"operation\">Task to await</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Result of the task, `OperationCanceledException`, or any exception raised by the task</returns>\n    /// <exception cref=\"OperationCanceledException\"></exception>\n    public static A await<A>(Task<A> operation)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            if (operation.IsCanceled)\n            {\n                throw new OperationCanceledException();\n            }\n            else if (operation.IsFaulted)\n            {\n                operation.Exception.Rethrow();\n            }\n            else if (operation.IsCompleted)\n            {\n                return operation.Result;\n            }\n            sw.SpinOnce();\n        }\n    }\n\n    /// <summary>\n    /// `Async.fork` lifts a function into an IO monad, forks it, and then runs the IO monad returning\n    /// the `ForkIO` object.  The forked operation continues to run in parallel.  The `ForkIO` object\n    /// contains two properties: `Await` and `Cancel` that be used to either await the result or\n    /// cancel the operation.\n    /// </summary>\n    /// <param name=\"operation\">Operation to fork</param>\n    /// <param name=\"timeout\">Optional timeout</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>The `ForkIO` object contains two properties: `Await` and `Cancel` that be used to either\n    /// await the result or cancel the operation.</returns>\n    public static ForkIO<A> fork<A>(Func<A> operation, TimeSpan timeout = default) =>\n        IO.lift(operation).ForkIO(timeout).Run();\n\n    /// <summary>\n    /// `Async.fork` lifts a function into an IO monad, forks it, and then runs the IO monad returning\n    /// the `ForkIO` object.  The forked operation continues to run in parallel.  The `ForkIO` object\n    /// contains two properties: `Await` and `Cancel` that be used to either await the result or\n    /// cancel the operation.\n    /// </summary>\n    /// <param name=\"operation\">Operation to fork</param>\n    /// <param name=\"timeout\">Optional timeout</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>The `ForkIO` object contains two properties: `Await` and `Cancel` that be used to either\n    /// await the result or cancel the operation.</returns>\n    public static ForkIO<A> fork<A>(Func<Task<A>> operation, TimeSpan timeout = default) =>\n        IO.liftAsync(operation).ForkIO(timeout).Run();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Async/AsyncEnumerable/AsyncEnumberable.Extensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\npublic static class AsyncEnumerableExtensions\n{\n    /*\n    public static StreamT<M, A> AsStream<M, A>(this IAsyncEnumerable<A> ma) \n        where M : Monad<M> =>\n        StreamT.lift<M, A>(ma);\n    \n    */\n    public static async IAsyncEnumerable<B> MapAsync<A, B>(this IAsyncEnumerable<A> ma, Func<A, B> f)\n    {\n        await foreach (var a in ma)\n        {\n            yield return f(a);\n        }\n    }\n    \n    public static async IAsyncEnumerable<B> ApplyAsync<A, B>(this IAsyncEnumerable<Func<A, B>> ff, IAsyncEnumerable<A> fa)\n    {\n        await foreach (var f in ff)\n        {\n            // ReSharper disable once PossibleMultipleEnumeration\n            await foreach (var a in fa)\n            {\n                yield return f(a);\n            }\n        }\n    }\n    \n    public static async IAsyncEnumerable<B> BindAsync<A, B>(this IAsyncEnumerable<A> ma, Func<A, IAsyncEnumerable<B>> f)\n    {\n        await foreach (var a in ma)\n        {\n            await foreach (var b in f(a))\n            {\n                yield return b;\n            }\n        }\n    }\n    \n    public static async IAsyncEnumerable<A> FilterAsync<A>(\n        this IAsyncEnumerable<A> ma, \n        Func<A, bool> f)\n    {\n        await foreach (var a in ma)\n        {\n            if(f(a)) yield return a;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Async/AsyncEnumerable/AsyncEnumberable.LINQ.Extensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Async.Linq;\n\npublic static class AsyncEnumerableExtensions\n{\n    extension<A>(IAsyncEnumerable<A> ma)\n    {\n        public async IAsyncEnumerable<B> Select<B>(Func<A, ValueTask<B>> f)\n        {\n            await foreach (var a in ma)\n            {\n                yield return await f(a);\n            }\n        }\n\n        public async IAsyncEnumerable<B> SelectMany<B>(Func<A, IAsyncEnumerable<B>> f)\n        {\n            await foreach (var a in ma)\n            {\n                await foreach (var b in f(a))\n                {\n                    yield return b;\n                }\n            }\n        }\n\n        public async IAsyncEnumerable<C> SelectMany<B, C>(Func<A, IAsyncEnumerable<B>> bind,\n                                                          Func<A, B, C> project)\n        {\n            await foreach (var a in ma)\n            {\n                await foreach (var b in bind(a))\n                {\n                    yield return project(a, b);\n                }\n            }\n        }\n\n        public async IAsyncEnumerable<A> Where(Func<A, bool> f)\n        {\n            await foreach (var a in ma)\n            {\n                if(f(a)) yield return a;\n            }\n        }\n\n        public async IAsyncEnumerable<A> Skip(int amount)\n        {\n            await foreach (var a in ma)\n            {\n                if (amount == 0)\n                    yield return a;\n                else\n                    amount--;\n            }\n        }\n\n        public async IAsyncEnumerable<A> Take(int amount)\n        {\n            await foreach (var a in ma)\n            {\n                if (amount > 0) \n                    yield return a;\n                else\n                    amount--;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Atom/Atom.Metadata.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Atoms provide a way to manage shared, synchronous, independent state without \n/// locks. \n/// </summary>\n/// <remarks>\n/// The intended use of atom is to hold an immutable data structure. You change \n/// the value by applying a function to the old value. This is done in an atomic \n/// manner by `Swap`.  \n/// \n/// Internally, `Swap` reads the current value, applies the function to it, and \n/// attempts to `CompareExchange` it in. Since another thread may have changed the \n/// value in the intervening time, it may have to retry, and does so in a spin loop. \n/// \n/// The net effect is that the value will always be the result of the application \n/// of the supplied function to a current value, atomically. However, because the \n/// function might be called multiple times, it must be free of side effects.\n/// \n/// Atoms are an efficient way to represent some state that will never need to be \n/// coordinated with any other, and for which you wish to make synchronous changes.\n/// </remarks>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic sealed class Atom<M, A>\n{\n    volatile object value;\n    Func<A, bool> validator;\n    readonly M metadata;\n\n    public event AtomChangedEvent<A>? Change;\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    Atom(M metadata, A value, Func<A, bool>? validator)\n    {\n        this.value     = Box<A>.New(value);\n        this.metadata  = metadata;\n        this.validator = validator ?? True;\n    }\n\n    /// <summary>\n    /// Internal constructor function that runs the validator on the value\n    /// before returning the Atom so that the Atom can never be in an invalid\n    /// state.  The validator is then used for all state transitions going \n    /// forward.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static Option<Atom<M, A>> New(M metadata, A value, Func<A, bool> validator)\n    {\n        var atom = new Atom<M, A>(metadata, value, validator ?? throw new ArgumentNullException(nameof(validator)));\n        return validator(value)\n                   ? Some(atom)\n                   : None;\n    }\n\n    /// <summary>\n    /// Internal constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static Atom<M, A> New(M metadata, A value) =>\n        new (metadata, value, True);\n\n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// If the swap operation fails (which can only happen due to its validator returning false),\n    /// then a snapshot of the current value within the Atom is returned.\n    /// If there is no validator for the Atom then the return value is always the snapshot of\n    /// the successful `f` function. \n    /// </returns>\n    public A Swap(Func<M, A, A> f)\n    {\n        f = f ?? throw new ArgumentNullException(nameof(f));\n\n        SpinWait sw = default;\n        while (true)\n        {\n            var current   = value;\n            var currentV  = Box<A>.GetValue(current);\n            var newValueA = f(metadata, currentV);\n            var newValue  = Box<A>.New(newValueA);\n            if (!validator(newValueA))\n            {\n                return currentV;\n            }\n            if(Interlocked.CompareExchange(ref value, newValue, current) == current)\n            {\n                Change?.Invoke(newValueA);\n                return newValueA;\n            }\n            sw.SpinOnce();\n        }\n    }\n    \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// * If `f` returns `None` then no update occurs and the result of the call\n    ///   to `Swap` will be the latest (unchanged) value of `A`.\n    /// * If the swap operation fails, due to its validator returning false, then a snapshot of\n    ///   the current value within the Atom is returned.\n    /// * If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// * If there is no validator for the Atom then the return value is always the snapshot of\n    ///   the successful `f` function. \n    /// </returns>\n    public A Swap(Func<M, A, Option<A>> f)\n    {\n        f = f ?? throw new ArgumentNullException(nameof(f));\n\n        SpinWait sw = default;\n        while (true)\n        {\n            var current           = value;\n            var currentV          = Box<A>.GetValue(current);\n            var optionalNewValueA = f(metadata, currentV);\n            if (optionalNewValueA.IsNone) return currentV;\n            var newValueA = (A)optionalNewValueA;\n            var newValue  = Box<A>.New(newValueA);\n            if (!validator(newValueA))\n            {\n                return currentV;\n            }\n            if(Interlocked.CompareExchange(ref value, newValue, current) == current)\n            {\n                Change?.Invoke(newValueA);\n                return newValueA;\n            }\n            sw.SpinOnce();\n        }\n    }\n\n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"x\">Additional value to pass to `f`</param>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// If the swap operation fails (which can only happen due to its validator returning false),\n    /// then a snapshot of the current value within the Atom is returned.\n    /// If there is no validator for the Atom then the return value is always the snapshot of\n    /// the successful `f` function. \n    /// </returns>\n    public IO<A> SwapIO(Func<M, A, A> f) =>\n        IO.lift(_ => Swap(f));\n\n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// * If `f` returns `None` then no update occurs and the result of the call\n    ///   to `Swap` will be the latest (unchanged) value of `A`.\n    /// * If the swap operation fails, due to its validator returning false, then a snapshot of\n    ///   the current value within the Atom is returned.\n    /// * If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// * If there is no validator for the Atom then the return value is always the snapshot of\n    ///   the successful `f` function. \n    /// </returns>\n    public IO<A> SwapIO(Func<M, A, Option<A>> f) =>\n        IO.lift(_ => Swap(f));\n\n    /// <summary>\n    /// Value accessor (read and write)\n    /// </summary>\n    /// <remarks>\n    /// \n    /// * Gets will return a freshly constructed `IO` monad that can be repeatedly\n    /// evaluated to get the latest state of the `Atom`.\n    /// \n    /// * Sets pass an `IO` monad that will be mapped to an operation that will set\n    /// the value of the `Atom` each time it's evaluated.\n    /// \n    /// </remarks>\n    public IO<A> ValueIO\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => IO.lift(_ => Value);\n        set => value.Bind(v => SwapIO((_, _) => v));\n    }\n\n    /// <summary>\n    /// Current state\n    /// </summary>\n    public A Value\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Box<A>.GetValue(value);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        Value?.ToString() ?? \"[null]\";\n\n    /// <summary>\n    /// Implicit conversion to `A`\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator A(Atom<M, A> atom) =>\n        atom.Value;\n\n    /// <summary>\n    /// Helper for validator\n    /// </summary>\n    /// <param name=\"_\"></param>\n    /// <returns></returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static bool True(A _) => true;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Atom/Atom.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Atoms provide a way to manage shared, synchronous, independent state without \n/// locks. \n/// </summary>\n/// <remarks>\n/// The intended use of atom is to hold an immutable data structure. You change \n/// the value by applying a function to the old value. This is done in an atomic \n/// manner by `Swap`.  \n/// \n/// Internally, `Swap` reads the current value, applies the function to it, and \n/// attempts to `CompareExchange` it in. Since another thread may have changed the \n/// value in the intervening time, it may have to retry, and does so in a spin loop. \n/// \n/// The net effect is that the value will always be the result of the application \n/// of the supplied function to a current value, atomically. However, because the \n/// function might be called multiple times, it must be free of side effects.\n/// \n/// Atoms are an efficient way to represent some state that will never need to be \n/// coordinated with any other, and for which you wish to make synchronous changes.\n/// </remarks>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic sealed class Atom<A>\n{\n    volatile object value;\n    readonly Func<A, bool> validator;\n\n    public event AtomChangedEvent<A>? Change;\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    Atom(A value, Func<A, bool>? validator)\n    {\n        this.value     = Box<A>.New(value);\n        this.validator = validator ?? True;\n    }\n\n    /// <summary>\n    /// Internal constructor function that runs the validator on the value\n    /// before returning the Atom so that the Atom can never be in an invalid\n    /// state.  The validator is then used for all state transitions going \n    /// forward.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static Option<Atom<A>> New(A value, Func<A, bool> validator)\n    {\n        var atom = new Atom<A>(value, validator ?? throw new ArgumentNullException(nameof(validator)));\n        return validator(value)\n                   ? Some(atom)\n                   : None;\n    }\n\n    /// <summary>\n    /// Internal constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static Atom<A> New(A value) =>\n        new (value, True);\n\n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// If the swap operation fails (which can only happen due to its validator returning false),\n    /// then a snapshot of the current value within the Atom is returned.\n    /// If there is no validator for the Atom then the return value is always the snapshot of\n    /// the successful `f` function. \n    /// </returns>\n    public A Swap(Func<A, A> f)\n    {\n        f = f ?? throw new ArgumentNullException(nameof(f));\n\n        SpinWait sw = default;\n        while (true)\n        {\n            var current   = value;\n            var currentV  = Box<A>.GetValue(current);\n            var newValueA = f(currentV);\n            var newValue  = Box<A>.New(newValueA);\n            if (!validator(newValueA))\n            {\n                return currentV;\n            }\n            if(Interlocked.CompareExchange(ref value, newValue, current) == current)\n            {\n                Change?.Invoke(newValueA);\n                return newValueA;\n            }\n            sw.SpinOnce();\n        }\n    }\n\n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// * If `f` returns `None` then no update occurs and the result of the call\n    ///   to `Swap` will be the latest (unchanged) value of `A`.\n    /// * If the swap operation fails, due to its validator returning false, then a snapshot of\n    ///   the current value within the Atom is returned.\n    /// * If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// * If there is no validator for the Atom then the return value is always the snapshot of\n    ///   the successful `f` function. \n    /// </returns>\n    public A SwapMaybe(Func<A, Option<A>> f)\n    {\n        f = f ?? throw new ArgumentNullException(nameof(f));\n\n        SpinWait sw = default;\n        while (true)\n        {\n            var current           = value;\n            var currentV          = Box<A>.GetValue(current);\n            var optionalNewValueA = f(currentV);\n            if (optionalNewValueA.IsNone) return currentV;\n            var newValueA = (A)optionalNewValueA;\n            var newValue  = Box<A>.New(newValueA);\n            if (!validator(newValueA))\n            {\n                return currentV;\n            }\n            if(Interlocked.CompareExchange(ref value, newValue, current) == current)\n            {\n                Change?.Invoke(newValueA);\n                return newValueA;\n            }\n            sw.SpinOnce();\n        }\n    }\n        \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// If the swap operation fails (which can only happen due to its validator returning false),\n    /// then a snapshot of the current value within the Atom is returned.\n    /// If there is no validator for the Atom then the return value is always the snapshot of\n    /// the successful `f` function. \n    /// </returns>\n    public IO<A> SwapIO(Func<A, A> f) =>\n        IO.lift(_ => Swap(f));\n        \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// * If `f` returns `None` then no update occurs and the result of the call\n    ///   to `Swap` will be the latest (unchanged) value of `A`.\n    /// * If the swap operation fails, due to its validator returning false, then a snapshot of\n    ///   the current value within the Atom is returned.\n    /// * If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// * If there is no validator for the Atom then the return value is always the snapshot of\n    ///   the successful `f` function. \n    /// </returns>\n    public IO<A> SwapMaybeIO(Func<A, Option<A>> f) =>\n        IO.lift(_ => SwapMaybe(f));\n\n    /// <summary>\n    /// Value accessor (read and write)\n    /// </summary>\n    /// <remarks>\n    /// \n    /// * Gets will return a freshly constructed `IO` monad that can be repeatedly\n    /// evaluated to get the latest state of the `Atom`.\n    /// \n    /// * Sets pass an `IO` monad that will be mapped to an operation that will set\n    /// the value of the `Atom` each time it's evaluated.\n    /// \n    /// </remarks>\n    public IO<A> ValueIO\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => IO.lift(_ => Value);\n        set => value.Bind(v => SwapIO(_ => v));\n    }\n        \n    /// <summary>\n    /// Current state\n    /// </summary>\n    public A Value\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Box<A>.GetValue(value);\n    }\n\n    /// <summary>\n    /// Implicit conversion to `A`\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator A(Atom<A> atom) =>\n        atom.Value;\n\n    /// <summary>\n    /// Helper for validator\n    /// </summary>\n    /// <param name=\"_\"></param>\n    /// <returns></returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static bool True(A _) => true;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        Value?.ToString() ?? \"[null]\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Atom/AtomChangedEvent.cs",
    "content": "﻿namespace LanguageExt;\n\n/// <summary>\n/// Announces Atom change events\n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic delegate void AtomChangedEvent<in A>(A value);\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Atom/README.md",
    "content": "Atoms provide a way to manage shared, synchronous, independent state without locks.  You can use them to wrap up immutable data structures\nand then atomically update them using the various `Swap` methods, or read them by calling the `Value` property.  \n\nIf a conflict is encountered during a `Swap` operation, the operation is re-run using the latest state, and so you should minimise the time \nspent in the `Swap` function, as well as make sure there are no side-effects, otherwise all bets are off.\n\nSee the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n\n### Usage\n\n    record Person(string Name, string Surname);\n\n    // Create a new atom\n    var person = Atom(new Person(\"Paul\", \"Louth\"));\n\n    // Modify it atomically\n    person.Swap(p => p with { Surname = $\"{p.Name}y\" });\n\n    // Take a snapshot of the state of the atom \n    var snapshot = p.Value;"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomHashMap/AtomHashMap.Eq.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Atoms provide a way to manage shared, synchronous, independent state without \n/// locks.  `AtomHashMap` wraps the language-ext `HashMap`, and makes sure all operations are atomic and thread-safe\n/// without resorting to locking\n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic class AtomHashMap<EqK, K, V> :\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<HashMap<EqK, K, V>>,\n    IEquatable<AtomHashMap<EqK, K, V>>,\n    IReadOnlyDictionary<K, V>\n    where EqK : Eq<K>\n{\n    internal volatile TrieMap<EqK, K, V> Items;\n    public event AtomHashMapChangeEvent<EqK, K, V>? Change;\n\n    /// <summary>\n    /// Creates a new atom-hashmap\n    /// </summary>\n    public static AtomHashMap<EqK, K, V> Empty => new AtomHashMap<EqK, K, V>(TrieMap<EqK, K, V>.Empty);\n        \n    /// <summary>\n    /// Constructor\n    /// </summary>\n    /// <param name=\"items\">Trie map</param>\n    AtomHashMap(TrieMap<EqK, K, V> items) =>\n        this.Items = items;\n        \n    /// <summary>\n    /// Constructor\n    /// </summary>\n    /// <param name=\"items\">Hash map</param>\n    internal AtomHashMap(HashMap<EqK, K, V> items) =>\n        this.Items = items.Value;\n        \n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public V this[K key] =>\n        Items[key];\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.IsEmpty;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Count;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Count;\n    }\n\n    /// <summary>\n    /// Atomically swap the underlying hash-map.  Allows for multiple operations on the hash-map in an entirely\n    /// transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of the AtomHashMap to a new state</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    /// <remarks>\n    /// NOTE: The change-tracking only works if you transform the `TrackingHashMap` provided to the `Func`.  If you\n    ///       build a fresh one then it won't have any tracking.  You can call `map.Clear()` to get to an empty\n    ///       map, which will also track the removals.\n    /// </remarks>\n    public Unit Swap(Func<TrackingHashMap<EqK, K, V>, TrackingHashMap<EqK, K, V>> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var nitems = swap(new TrackingHashMap<EqK, K, V>(oitems));\n            if(ReferenceEquals(oitems, nitems.Value))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems.Value, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems.Value, nitems.Changes.Value);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Internal version of `Swap` that doesn't do any change tracking\n    /// </summary>\n    internal Unit SwapInternal(Func<TrieMap<EqK, K, V>, TrieMap<EqK, K, V>> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var nitems = swap(oitems);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Atomically swap a key in the hash-map, if it exists.  If it doesn't exist, nothing changes.\n    /// Allows for multiple operations on the hash-map value in an entirely transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of a value in the AtomHashMap to a new value</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit SwapKey(K key, Func<V, V> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var ovalue = oitems.Find(key);\n            if (ovalue.IsNone) return unit;\n            var nvalue   = swap((V)ovalue);\n            var onChange = Change;\n            var (nitems, change) = onChange == null \n                                       ? (oitems.SetItem(key, nvalue), Change<V>.None) \n                                       : oitems.SetItemWithLog(key, nvalue);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically swap a key in the hash-map:\n    /// \n    /// * If the key doesn't exist, then `None` is passed to `swap`\n    /// * If the key does exist, then `Some(x)` is passed to `swap`\n    /// \n    /// The operation performed on the hash-map depends on the value going in and out of `swap`:\n    /// \n    ///   In        | Out       | Operation       \n    ///   --------- | --------- | --------------- \n    ///   `Some(x)` | `Some(y)` | `SetItem(key, y)` \n    ///   `Some(x)` | `None`    | `Remove(key)`     \n    ///   `None`    | `Some(y)` | `Add(key, y)`     \n    ///   `None`    | `None`    | `no-op`           \n    ///  \n    /// Allows for multiple operations on the hash-map value in an entirely transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of a value in the AtomHashMap to a new value</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit SwapKey(K key, Func<Option<V>, Option<V>> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var ovalue = oitems.Find(key);\n            var nvalue = swap(ovalue);\n\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (ovalue.IsSome, nvalue.IsSome) switch\n                                         {\n                                             (true, true)   => (oitems.SetItem(key, (V)nvalue), Change<V>.None),\n                                             (true, false)  => (oitems.Remove(key), Change<V>.None),\n                                             (false, true)  => (oitems.Add(key, (V)nvalue), Change<V>.None),\n                                             (false, false) => (oitems, Change<V>.None)\n                                         }\n                                       : (ovalue.IsSome, nvalue.IsSome) switch\n                                         {\n                                             (true, true)   => oitems.SetItemWithLog(key, (V)nvalue),\n                                             (true, false)  => oitems.RemoveWithLog(key),\n                                             (false, true)  => oitems.AddWithLog(key, (V)nvalue),\n                                             (false, false) => (oitems, Change<V>.None)\n                                         };\n                \n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public AtomHashMap<EqK, K, V> Filter(Func<V, bool> pred) =>\n        new(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit FilterInPlace(Func<V, bool> pred)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Filter(pred), null)\n                                        : oitems.FilterWithLog(pred);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    [Pure]\n    public AtomHashMap<EqK, K, V> Filter(Func<K, V, bool> pred) =>\n        new(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit FilterInPlace(Func<K, V, bool> pred)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Filter(pred), null)\n                                        : oitems.FilterWithLog(pred);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit MapInPlace(Func<V, V> f) \n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Map(f), null)\n                                        : oitems.MapWithLog(f);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    public AtomHashMap<EqK, K, U> Map<U>(Func<K, V, U> f) =>\n        new (Items.Map(f));\n        \n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    public Unit Add(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.Add(key, value), null)\n                                       : oitems.AddWithLog(key, value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    public Unit TryAdd(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.TryAdd(key, value), null)\n                                       : oitems.TryAddWithLog(key, value);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    public Unit AddOrUpdate(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.AddOrUpdate(key, value), null)\n                                       : oitems.AddOrUpdateWithLog(key, value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit AddOrUpdate(K key, Func<V, V> Some, Func<V> None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.AddOrUpdate(key, Some, None), null)\n                                       : oitems.AddOrUpdateWithLog(key, Some, None);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit AddOrUpdate(K key, Func<V, V> Some, V None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.AddOrUpdate(key, Some, None), null)\n                                       : oitems.AddOrUpdateWithLog(key, Some, None);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    public Unit AddRange(IEnumerable<(K Key, V Value)> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.AddRange(srange), null)\n                                        : oitems.AddRangeWithLog(srange);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    public Unit TryAddRange(IEnumerable<(K Key, V Value)> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TryAddRange(srange), null)\n                                        : oitems.TryAddRangeWithLog(srange);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    public Unit TryAddRange(IEnumerable<KeyValuePair<K, V>> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TryAddRange(srange), null)\n                                        : oitems.TryAddRangeWithLog(srange);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    public Unit AddOrUpdateRange(IEnumerable<(K Key, V Value)> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.AddOrUpdateRange(srange), null)\n                                        : oitems.AddOrUpdateRangeWithLog(srange);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    public Unit AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.AddOrUpdateRange(srange), null)\n                                        : oitems.AddOrUpdateRangeWithLog(srange);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    public Unit Remove(K key)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.Remove(key), null)\n                                       : oitems.RemoveWithLog(key);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Option<V> Find(K value) =>\n        Items.Find(value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Seq<V> FindSeq(K key) =>\n        Items.FindAll(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) =>\n        Items.Find(key, Some, None);\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Added value</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public V FindOrAdd(K key, Func<V> None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var (nitems, value, change) = Items.FindOrAddWithLog(key, None);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return value;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return value;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Added value</returns>\n    public V FindOrAdd(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var (nitems, nvalue, change) = Items.FindOrAddWithLog(key, value);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return nvalue;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return nvalue;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }           \n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Added value</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Option<V> FindOrMaybeAdd(K key, Func<Option<V>> None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var (nitems, nvalue, change) = Items.FindOrMaybeAddWithLog(key, None);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return nvalue;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return nvalue;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }  \n        \n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Added value</returns>\n    public Option<V> FindOrMaybeAdd(K key, Option<V> None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var (nitems, nvalue, change) = Items.FindOrMaybeAddWithLog(key, None);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return nvalue;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return nvalue;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }  \n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    public Unit SetItem(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.SetItem(key, value), null)\n                                       : oitems.SetItemWithLog(key, value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }  \n        \n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit SetItem(K key, Func<V, V> Some)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var(nitems, change) = onChange == null\n                                      ? (oitems.SetItem(key, Some), null)\n                                      : oitems.SetItemWithLog(key, Some);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    public Unit TrySetItem(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.TrySetItem(key, value), null)\n                                       : oitems.TrySetItemWithLog(key, value);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit TrySetItem(K key, Func<V, V> Some)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.TrySetItem(key, Some), null)\n                                       : oitems.TrySetItemWithLog(key, Some);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool ContainsKey(K key) =>\n        Items.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains(K key, V value) =>\n        Items.Contains(key, value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    public bool Contains(V value) =>\n        Items.Contains(value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    public bool Contains<EqV>(V value) where EqV : Eq<V> =>\n        Items.Contains<EqV>(value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains<EqV>(K key, V value) where EqV : Eq<V> =>\n        Items.Contains<EqV>(key, value);\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    public Unit Clear()\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Clear(), null)\n                                        : oitems.ClearWithLog();\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically adds a range of items to the map\n    /// </summary>\n    /// <param name=\"pairs\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    public Unit AddRange(IEnumerable<KeyValuePair<K, V>> pairs)\n    {\n        SpinWait sw     = default;\n        var      spairs = toSeq(pairs);\n        if (spairs.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.AddRange(spairs), null)\n                                        : oitems.AddRangeWithLog(spairs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    public Unit SetItems(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        SpinWait sw     = default;\n        var      sitems = toSeq(items);\n        if (sitems.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.SetItems(sitems), null)\n                                        : oitems.SetItemsWithLog(sitems);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    public Unit SetItems(IEnumerable<(K Key, V Value)> items)\n    {\n        SpinWait sw     = default;\n        var      sitems = toSeq(items);\n        if (sitems.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.SetItems(sitems), null)\n                                        : oitems.SetItemsWithLog(sitems);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    public Unit TrySetItems(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        SpinWait sw     = default;\n        var      sitems = toSeq(items);\n        if (sitems.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TrySetItems(sitems), null)\n                                        : oitems.TrySetItemsWithLog(sitems);\n            if (ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    public Unit TrySetItems(IEnumerable<(K Key, V Value)> items)\n    {\n        SpinWait sw     = default;\n        var      sitems = toSeq(items);\n        if (sitems.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TrySetItems(sitems), null)\n                                        : oitems.TrySetItemsWithLog(sitems);\n            if (ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit TrySetItems(IEnumerable<K> keys, Func<V, V> Some)\n    {\n        SpinWait sw    = default;\n        var      skeys = toSeq(keys);\n        if (skeys.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TrySetItems(skeys, Some), null)\n                                        : oitems.TrySetItemsWithLog(skeys, Some);\n            if (ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    public Unit RemoveRange(IEnumerable<K> keys)\n    {\n        SpinWait sw    = default;\n        var      skeys = toSeq(keys);\n        if (skeys.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.RemoveRange(skeys), null)\n                                        : oitems.RemoveRangeWithLog(skeys);\n            if (ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    public bool Contains(KeyValuePair<K, V> pair) =>\n        Items.Contains(pair.Key, pair.Value);\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys =>\n        Items.Keys;\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values =>\n        Items.Values;\n\n    /// <summary>\n    /// Convert to a HashMap\n    /// </summary>\n    /// <remarks>This is effectively a zero cost operation, not even a single allocation</remarks>\n    [Pure]\n    public HashMap<EqK, K, V> ToHashMap() =>\n        new (Items);\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Items.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Items.GetEnumerator();\n\n    [Pure]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        toSeq(AsIterable());\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    public Iterable<(K Key, V Value)> AsIterable() =>\n        IterableExtensions.AsIterable(Items);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator AtomHashMap<EqK, K, V>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator ==(AtomHashMap<EqK, K, V> lhs, AtomHashMap<EqK, K, V> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator ==(AtomHashMap<EqK, K, V> lhs, HashMap<EqK, K, V> rhs) =>\n        lhs?.Items.Equals(rhs.Value) ?? false;\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator ==(HashMap<EqK, K, V> lhs, AtomHashMap<EqK, K, V> rhs) =>\n        lhs.Value.Equals(rhs.Items);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator !=(AtomHashMap<EqK, K, V> lhs, AtomHashMap<EqK, K, V> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator !=(AtomHashMap<EqK, K, V> lhs, HashMap<EqK, K, V> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator !=(HashMap<EqK, K, V> lhs, AtomHashMap<EqK, K, V> rhs) =>\n        !(lhs == rhs);\n\n    public Unit Append(AtomHashMap<EqK, K, V> rhs)\n    {\n        if (rhs.IsEmpty) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Append(rhs.Items), null)\n                                        : oitems.AppendWithLog(rhs.Items);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    public Unit Append(HashMap<EqK, K, V> rhs)\n    {\n        if (rhs.IsEmpty) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Append(rhs.Value), null)\n                                        : oitems.AppendWithLog(rhs.Value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    public Unit Subtract(AtomHashMap<EqK, K, V> rhs) \n    {\n        if (rhs.IsEmpty) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Subtract(rhs.Items), null)\n                                        : oitems.SubtractWithLog(rhs.Items);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }         \n\n    public Unit Subtract(HashMap<EqK, K, V> rhs) \n    {\n        if (rhs.IsEmpty) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Subtract(rhs.Value), null)\n                                        : oitems.SubtractWithLog(rhs.Value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }         \n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<K> other) =>\n        Items.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<K> other) =>\n        Items.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<K> other) =>\n        Items.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(HashMap<EqK, K, V> other) =>\n        Items.IsSubsetOf(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<K> rhs) =>\n        Items.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(IEnumerable<K> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Intersect(srhs), null)\n                                        : oitems.IntersectWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(IEnumerable<(K Key, V Value)> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = new TrieMap<EqK, K, V>(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Intersect(srhs), null)\n                                        : oitems.IntersectWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n        \n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(IEnumerable<(K Key, V Value)> rhs, WhenMatched<K, V, V, V> Merge)\n    {\n        SpinWait sw   = default;\n        var      srhs = new TrieMap<EqK, K, V>(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Intersect(srhs, Merge), null)\n                                        : oitems.IntersectWithLog(srhs, Merge);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(HashMap<EqK, K, V> rhs, WhenMatched<K, V, V, V> Merge)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Intersect(rhs.Value, Merge), null)\n                                        : oitems.IntersectWithLog(rhs.Value, Merge);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }         \n        \n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        Items.Overlaps(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<K> other) =>\n        Items.Overlaps(other);\n\n    /// <summary>\n    /// Returns this - rhs.  Only the items in this that are not in \n    /// rhs will be returned.\n    /// </summary>\n    public Unit Except(IEnumerable<K> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Except(srhs), null)\n                                        : oitems.ExceptWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    public Unit Except(IEnumerable<(K Key, V Value)> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Except(srhs), null)\n                                        : oitems.ExceptWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public Unit SymmetricExcept(HashMap<EqK, K, V> rhs)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.SymmetricExcept(rhs), null)\n                                        : oitems.SymmetricExceptWithLog(rhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public Unit SymmetricExcept(IEnumerable<(K Key, V Value)> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.SymmetricExcept(srhs), null)\n                                        : oitems.SymmetricExceptWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    public Unit Union(IEnumerable<(K, V)> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);\n        if (srhs.IsEmpty) return unit;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Union(srhs), null)\n                                        : oitems.UnionWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    public Unit Union(IEnumerable<(K Key, V Value)> rhs, WhenMatched<K, V, V, V> Merge)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);\n        if (srhs.IsEmpty) return unit;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Union(srhs, Merge), null)\n                                        : oitems.UnionWithLog(srhs, Merge);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the right-hand side, but not the left-hand-side.\n    /// This allows the `V2` value-type to be mapped to the target `V` value-type. \n    /// </remarks>\n    public Unit Union<W>(IEnumerable<(K Key, W Value)> rhs, WhenMissing<K, W, V> MapRight, WhenMatched<K, V, W, V> Merge)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);\n        if (srhs.IsEmpty) return unit;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Union(srhs, MapRight, Merge), null)\n                                        : oitems.UnionWithLog(srhs, MapRight, Merge);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }            \n    }\n        \n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is AtomHashMap<K, V> hm && Equals(hm);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals(AtomHashMap<EqK, K, V>? other) =>\n        other is not null && Items.Equals(other.Items);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals(HashMap<EqK, K, V> other) =>\n        Items.Equals(other.Value);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    public bool EqualsKeys(AtomHashMap<EqK, K, V> other) =>\n        Items.Equals<EqTrue<V>>(other.Items);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    public bool EqualsKeys(HashMap<EqK, K, V> other) =>\n        Items.Equals<EqTrue<V>>(other.Value);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Items.GetHashCode();\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public AtomHashMap<EqK, K, U> Select<U>(Func<V, U> f) =>\n        new AtomHashMap<EqK, K, U>(Items.Map(f));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public AtomHashMap<EqK, K, U> Select<U>(Func<K, V, U> f) =>\n        new AtomHashMap<EqK, K, U>(Items.Map(f));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public AtomHashMap<EqK, K, V> Where(Func<V, bool> pred) =>\n        new AtomHashMap<EqK, K, V>(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public AtomHashMap<EqK, K, V> Where(Func<K, V, bool> pred) =>\n        new AtomHashMap<EqK, K, V>(Items.Filter(pred));\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<K, V, bool> pred)\n    {\n        foreach (var (key, value) in AsIterable())\n        {\n            if (!pred(key, value)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        AsIterable().Map(kv => (Key: kv.Key, Value: kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<V, bool> pred) =>\n        Values.ForAll(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    public bool Exists(Func<K, V, bool> pred)\n    {\n        foreach (var (key, value) in AsIterable())\n        {\n            if (pred(key, value)) return true;\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<(K Key, V Value), bool> pred) =>\n        AsIterable().Map(kv => (kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<V, bool> pred) =>\n        Values.Exists(pred);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<K, V> action)\n    {\n        foreach (var (key, value) in this)\n        {\n            action(key, value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<(K Key, V Value)> action)\n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<KeyValuePair<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new KeyValuePair<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        AsIterable().Fold(state, (s, x) => folder(s, x.Key, x.Value));\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, V, S> folder) =>\n        Values.Fold(state, folder);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    void AnnounceChange(TrieMap<EqK, K, V> prev, TrieMap<EqK, K, V> current, K key, Change<V>? change)\n    {\n        if (change?.HasChanged ?? false)\n        {\n            Change?.Invoke(new HashMapPatch<EqK, K, V>(prev, current, key, change));\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    void AnnounceChanges(TrieMap<EqK, K, V> prev, TrieMap<EqK, K, V> current,\n                         TrieMap<EqK, K, Change<V>>? changes)\n    {\n        if (changes is not null)\n        {\n            Change?.Invoke(new HashMapPatch<EqK, K, V>(prev, current, changes));\n        }\n    }\n    \n    /////////////////////////////////////////////////////////////////////////////////////////////\n    //  \n    // IReadOnlyDictionary\n\n    [Pure]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(\n        Func<(K Key, V Value), KR> keySelector, \n        Func<(K Key, V Value), VR> valueSelector) \n        where KR : notnull =>\n        AsIterable().ToDictionary(keySelector, valueSelector);\n \n    [Pure]\n    public bool TryGetValue(K key, out V value)\n    {\n        var v = Find(key);\n        if (v.IsSome)\n        {\n            value = (V)v;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n        \n    [Pure]\n    IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() =>\n        AsIterable()\n           .Select(p => new KeyValuePair<K, V>(p.Key, p.Value))\n           .GetEnumerator() ;\n    \n    [Pure]\n    IEnumerable<K> IReadOnlyDictionary<K, V>.Keys => Keys;\n\n    [Pure]\n    IEnumerable<V> IReadOnlyDictionary<K, V>.Values => Values;\n\n    [Pure]\n    public IReadOnlyDictionary<K, V> ToReadOnlyDictionary() =>\n        this;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomHashMap/AtomHashMap.Module.Eq.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks.  `AtomHashMap` wraps the language-ext `HashMap`, and makes sure all operations are atomic and thread-safe\n    /// without resorting to locking\n    /// </summary>\n    /// <remarks>\n    /// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n    /// </remarks>\n    public static partial class AtomHashMap\n    {\n        public static AtomHashMap<EqK, K, V> ToAtom<EqK, K, V>(this HashMap<EqK, K, V> self) where EqK : Eq<K> =>\n            new AtomHashMap<EqK, K, V>(self);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomHashMap/AtomHashMap.Module.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks.  `AtomHashMap` wraps the language-ext `HashMap`, and makes sure all operations are atomic and thread-safe\n    /// without resorting to locking\n    /// </summary>\n    /// <remarks>\n    /// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n    /// </remarks>\n    public static partial class AtomHashMap\n    {\n        public static AtomHashMap<K, V> ToAtom<K, V>(this HashMap<K, V> self) =>\n            new AtomHashMap<K, V>(self);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomHashMap/AtomHashMap.cs",
    "content": "#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Atoms provide a way to manage shared, synchronous, independent state without \n/// locks.  `AtomHashMap` wraps the language-ext `HashMap`, and makes sure all operations are atomic and thread-safe\n/// without resorting to locking\n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic class AtomHashMap<K, V> :\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<HashMap<K, V>>,\n    IEquatable<AtomHashMap<K, V>>,\n    IReadOnlyDictionary<K, V>\n{\n    volatile TrieMap<EqDefault<K>, K, V> Items;\n    public event AtomHashMapChangeEvent<K, V>? Change;\n\n    /// <summary>\n    /// Creates a new atom-hashmap\n    /// </summary>\n    public static AtomHashMap<K, V> Empty => new AtomHashMap<K, V>(TrieMap<EqDefault<K>, K, V>.Empty);\n        \n    /// <summary>\n    /// Constructor\n    /// </summary>\n    /// <param name=\"items\">Trie map</param>\n    AtomHashMap(TrieMap<EqDefault<K>, K, V> items) =>\n        this.Items = items;\n        \n    /// <summary>\n    /// Constructor\n    /// </summary>\n    /// <param name=\"items\">Hash map</param>\n    internal AtomHashMap(HashMap<K, V> items) =>\n        this.Items = items.Value;\n    \n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public V this[K key] =>\n        Items[key];\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.IsEmpty;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Count;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Count;\n    }\n\n    /// <summary>\n    /// Atomically swap the underlying hash-map.  Allows for multiple operations on the hash-map in an entirely\n    /// transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of the AtomHashMap to a new state</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    /// <remarks>\n    /// NOTE: The change-tracking only works if you transform the `TrackingHashMap` provided to the `Func`.  If you\n    ///       build a fresh one then it won't have any tracking.  You can call `map.Clear()` to get to an empty\n    ///       map, which will also track the removals.\n    /// </remarks>\n    public Unit Swap(Func<TrackingHashMap<K, V>, TrackingHashMap<K, V>> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var nitems = swap(new TrackingHashMap<K, V>(oitems));\n            if(ReferenceEquals(oitems, nitems.Value))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems.Value, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems.Value, nitems.Changes.Value);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically swap a key in the hash-map, if it exists.  If it doesn't exist, nothing changes.\n    /// Allows for multiple operations on the hash-map value in an entirely transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of a value in the AtomHashMap to a new value</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit SwapKey(K key, Func<V, V> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var ovalue = oitems.Find(key);\n            if (ovalue.IsNone) return unit;\n            var nvalue   = swap((V)ovalue);\n            var onChange = Change;\n            var (nitems, change) = onChange == null \n                                       ? (oitems.SetItem(key, nvalue), Change<V>.None) \n                                       : oitems.SetItemWithLog(key, nvalue);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically swap a key in the hash-map:\n    /// \n    /// * If the key doesn't exist, then `None` is passed to `swap`\n    /// * If the key does exist, then `Some(x)` is passed to `swap`\n    /// \n    /// The operation performed on the hash-map depends on the value going in and out of `swap`:\n    /// \n    ///   In        | Out       | Operation       \n    ///   --------- | --------- | --------------- \n    ///   `Some(x)` | `Some(y)` | `SetItem(key, y)` \n    ///   `Some(x)` | `None`    | `Remove(key)`     \n    ///   `None`    | `Some(y)` | `Add(key, y)`     \n    ///   `None`    | `None`    | `no-op`           \n    ///  \n    /// Allows for multiple operations on the hash-map value in an entirely transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of a value in the AtomHashMap to a new value</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit SwapKey(K key, Func<Option<V>, Option<V>> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var ovalue = oitems.Find(key);\n            var nvalue = swap(ovalue);\n\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (ovalue.IsSome, nvalue.IsSome) switch\n                                         {\n                                             (true, true)   => (oitems.SetItem(key, (V)nvalue), Change<V>.None),\n                                             (true, false)  => (oitems.Remove(key), Change<V>.None),\n                                             (false, true)  => (oitems.Add(key, (V)nvalue), Change<V>.None),\n                                             (false, false) => (oitems, Change<V>.None)\n                                         }\n                                       : (ovalue.IsSome, nvalue.IsSome) switch\n                                         {\n                                             (true, true)   => oitems.SetItemWithLog(key, (V)nvalue),\n                                             (true, false)  => oitems.RemoveWithLog(key),\n                                             (false, true)  => oitems.AddWithLog(key, (V)nvalue),\n                                             (false, false) => (oitems, Change<V>.None)\n                                         };\n                \n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public AtomHashMap<K, V> Filter(Func<V, bool> pred) =>\n        new(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit FilterInPlace(Func<V, bool> pred)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Filter(pred), null)\n                                        : oitems.FilterWithLog(pred);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    [Pure]\n    public AtomHashMap<K, V> Filter(Func<K, V, bool> pred) =>\n        new(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit FilterInPlace(Func<K, V, bool> pred)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Filter(pred), null)\n                                        : oitems.FilterWithLog(pred);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit MapInPlace(Func<V, V> f) \n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Map(f), null)\n                                        : oitems.MapWithLog(f);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    public AtomHashMap<K, U> Map<U>(Func<K, V, U> f) =>\n        new AtomHashMap<K, U>(Items.Map(f));\n        \n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    public Unit Add(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.Add(key, value), null)\n                                       : oitems.AddWithLog(key, value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    public Unit TryAdd(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.TryAdd(key, value), null)\n                                       : oitems.TryAddWithLog(key, value);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    public Unit AddOrUpdate(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.AddOrUpdate(key, value), null)\n                                       : oitems.AddOrUpdateWithLog(key, value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit AddOrUpdate(K key, Func<V, V> Some, Func<V> None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.AddOrUpdate(key, Some, None), null)\n                                       : oitems.AddOrUpdateWithLog(key, Some, None);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit AddOrUpdate(K key, Func<V, V> Some, V None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.AddOrUpdate(key, Some, None), null)\n                                       : oitems.AddOrUpdateWithLog(key, Some, None);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    public Unit AddRange(IEnumerable<(K Key, V Value)> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.AddRange(srange), null)\n                                        : oitems.AddRangeWithLog(srange);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    public Unit TryAddRange(IEnumerable<(K Key, V Value)> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TryAddRange(srange), null)\n                                        : oitems.TryAddRangeWithLog(srange);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    public Unit TryAddRange(IEnumerable<KeyValuePair<K, V>> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TryAddRange(srange), null)\n                                        : oitems.TryAddRangeWithLog(srange);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    public Unit AddOrUpdateRange(IEnumerable<(K Key, V Value)> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.AddOrUpdateRange(srange), null)\n                                        : oitems.AddOrUpdateRangeWithLog(srange);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    public Unit AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range)\n    {\n        SpinWait sw     = default;\n        var      srange = toSeq(range);\n        if (srange.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.AddOrUpdateRange(srange), null)\n                                        : oitems.AddOrUpdateRangeWithLog(srange);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    public Unit Remove(K key)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.Remove(key), null)\n                                       : oitems.RemoveWithLog(key);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Option<V> Find(K value) =>\n        Items.Find(value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Seq<V> FindSeq(K key) =>\n        Items.FindAll(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) =>\n        Items.Find(key, Some, None);\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Added value</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public V FindOrAdd(K key, Func<V> None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var (nitems, value, change) = Items.FindOrAddWithLog(key, None);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return value;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return value;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Added value</returns>\n    public V FindOrAdd(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var (nitems, nvalue, change) = Items.FindOrAddWithLog(key, value);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return nvalue;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return nvalue;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }           \n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Added value</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Option<V> FindOrMaybeAdd(K key, Func<Option<V>> None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var (nitems, nvalue, change) = Items.FindOrMaybeAddWithLog(key, None);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return nvalue;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return nvalue;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }  \n        \n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Added value</returns>\n    public Option<V> FindOrMaybeAdd(K key, Option<V> None)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var (nitems, nvalue, change) = Items.FindOrMaybeAddWithLog(key, None);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return nvalue;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return nvalue;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }  \n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    public Unit SetItem(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.SetItem(key, value), null)\n                                       : oitems.SetItemWithLog(key, value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }  \n        \n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit SetItem(K key, Func<V, V> Some)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var(nitems, change) = onChange == null\n                                      ? (oitems.SetItem(key, Some), null)\n                                      : oitems.SetItemWithLog(key, Some);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    public Unit TrySetItem(K key, V value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.TrySetItem(key, value), null)\n                                       : oitems.TrySetItemWithLog(key, value);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit TrySetItem(K key, Func<V, V> Some)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, change) = onChange == null\n                                       ? (oitems.TrySetItem(key, Some), null)\n                                       : oitems.TrySetItemWithLog(key, Some);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChange(oitems, nitems, key, change);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool ContainsKey(K key) =>\n        Items.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains(K key, V value) =>\n        Items.Contains(key, value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    public bool Contains(V value) =>\n        Items.Contains(value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    public bool Contains<EqV>(V value) where EqV : Eq<V> =>\n        Items.Contains<EqV>(value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains<EqV>(K key, V value) where EqV : Eq<V> =>\n        Items.Contains<EqV>(key, value);\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    public Unit Clear()\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Clear(), null)\n                                        : oitems.ClearWithLog();\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically adds a range of items to the map\n    /// </summary>\n    /// <param name=\"pairs\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    public Unit AddRange(IEnumerable<KeyValuePair<K, V>> pairs)\n    {\n        SpinWait sw     = default;\n        var      spairs = toSeq(pairs);\n        if (spairs.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.AddRange(spairs), null)\n                                        : oitems.AddRangeWithLog(spairs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    public Unit SetItems(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        SpinWait sw     = default;\n        var      sitems = toSeq(items);\n        if (sitems.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.SetItems(sitems), null)\n                                        : oitems.SetItemsWithLog(sitems);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    public Unit SetItems(IEnumerable<(K Key, V Value)> items)\n    {\n        SpinWait sw     = default;\n        var      sitems = toSeq(items);\n        if (sitems.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.SetItems(sitems), null)\n                                        : oitems.SetItemsWithLog(sitems);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    public Unit TrySetItems(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        SpinWait sw     = default;\n        var      sitems = toSeq(items);\n        if (sitems.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TrySetItems(sitems), null)\n                                        : oitems.TrySetItemsWithLog(sitems);\n            if (ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    public Unit TrySetItems(IEnumerable<(K Key, V Value)> items)\n    {\n        SpinWait sw     = default;\n        var      sitems = toSeq(items);\n        if (sitems.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TrySetItems(sitems), null)\n                                        : oitems.TrySetItemsWithLog(sitems);\n            if (ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit TrySetItems(IEnumerable<K> keys, Func<V, V> Some)\n    {\n        SpinWait sw    = default;\n        var      skeys = toSeq(keys);\n        if (skeys.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.TrySetItems(skeys, Some), null)\n                                        : oitems.TrySetItemsWithLog(skeys, Some);\n            if (ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    public Unit RemoveRange(IEnumerable<K> keys)\n    {\n        SpinWait sw    = default;\n        var      skeys = toSeq(keys);\n        if (skeys.IsEmpty) return default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.RemoveRange(skeys), null)\n                                        : oitems.RemoveRangeWithLog(skeys);\n            if (ReferenceEquals(oitems, nitems))\n            {\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    public bool Contains(KeyValuePair<K, V> pair) =>\n        Items.Contains(pair.Key, pair.Value);\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys =>\n        Items.Keys;\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values =>\n        Items.Values;\n\n    /// <summary>\n    /// Convert the map to an IDictionary\n    /// </summary>\n    /// <remarks>This is effectively a zero cost operation, not even a single allocation</remarks>\n    [Pure]\n    public IReadOnlyDictionary<K, V> ToDictionary() =>\n        this;\n\n    /// <summary>\n    /// Convert to a HashMap\n    /// </summary>\n    /// <remarks>This is effectively a zero cost operation, not even a single allocation</remarks>\n    [Pure]\n    public HashMap<K, V> ToHashMap() =>\n        new (Items);\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Items.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Items.GetEnumerator();\n\n    [Pure]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        toSeq(AsIterable());\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    public Iterable<(K Key, V Value)> AsIterable() =>\n        IterableExtensions.AsIterable(Items);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator AtomHashMap<K, V>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator ==(AtomHashMap<K, V> lhs, AtomHashMap<K, V> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator ==(AtomHashMap<K, V> lhs, HashMap<K, V> rhs) =>\n        lhs?.Items.Equals(rhs.Value) ?? false;\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator ==(HashMap<K, V> lhs, AtomHashMap<K, V> rhs) =>\n        lhs.Value.Equals(rhs.Items);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator !=(AtomHashMap<K, V> lhs, AtomHashMap<K, V> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator !=(AtomHashMap<K, V> lhs, HashMap<K, V> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator !=(HashMap<K, V> lhs, AtomHashMap<K, V> rhs) =>\n        !(lhs == rhs);\n\n    public Unit Append(AtomHashMap<K, V> rhs)\n    {\n        if (rhs.IsEmpty) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Append(rhs.Items), null)\n                                        : oitems.AppendWithLog(rhs.Items);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    public Unit Append(HashMap<K, V> rhs)\n    {\n        if (rhs.IsEmpty) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Append(rhs.Value), null)\n                                        : oitems.AppendWithLog(rhs.Value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    public Unit Subtract(AtomHashMap<K, V> rhs) \n    {\n        if (rhs.IsEmpty) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Subtract(rhs.Items), null)\n                                        : oitems.SubtractWithLog(rhs.Items);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }         \n\n    public Unit Subtract(HashMap<K, V> rhs) \n    {\n        if (rhs.IsEmpty) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Subtract(rhs.Value), null)\n                                        : oitems.SubtractWithLog(rhs.Value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }         \n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<K> other) =>\n        Items.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<K> other) =>\n        Items.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<K> other) =>\n        Items.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(HashMap<K, V> other) =>\n        Items.IsSubsetOf(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<K> rhs) =>\n        Items.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(IEnumerable<K> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Intersect(srhs), null)\n                                        : oitems.IntersectWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(IEnumerable<(K Key, V Value)> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = new TrieMap<EqDefault<K>, K, V>(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Intersect(srhs), null)\n                                        : oitems.IntersectWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(IEnumerable<(K Key, V Value)> rhs, WhenMatched<K, V, V, V> Merge)\n    {\n        SpinWait sw   = default;\n        var      srhs = new TrieMap<EqDefault<K>, K, V>(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Intersect(srhs, Merge), null)\n                                        : oitems.IntersectWithLog(srhs, Merge);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(HashMap<K, V> rhs, WhenMatched<K, V, V, V> Merge)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Intersect(rhs.Value, Merge), null)\n                                        : oitems.IntersectWithLog(rhs.Value, Merge);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        Items.Overlaps(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<K> other) =>\n        Items.Overlaps(other);\n\n    /// <summary>\n    /// Returns this - rhs.  Only the items in this that are not in \n    /// rhs will be returned.\n    /// </summary>\n    public Unit Except(IEnumerable<K> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Except(srhs), null)\n                                        : oitems.ExceptWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    public Unit Except(IEnumerable<(K Key, V Value)> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);            \n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Except(srhs), null)\n                                        : oitems.ExceptWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public Unit SymmetricExcept(HashMap<K, V> rhs)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.SymmetricExcept(rhs), null)\n                                        : oitems.SymmetricExceptWithLog(rhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public Unit SymmetricExcept(IEnumerable<(K Key, V Value)> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.SymmetricExcept(srhs), null)\n                                        : oitems.SymmetricExceptWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    public Unit Union(IEnumerable<(K, V)> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);\n        if (srhs.IsEmpty) return unit;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Union(srhs), null)\n                                        : oitems.UnionWithLog(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    public Unit Union(IEnumerable<(K Key, V Value)> rhs, WhenMatched<K, V, V, V> Merge)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);\n        if (srhs.IsEmpty) return unit;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Union(srhs, Merge), null)\n                                        : oitems.UnionWithLog(srhs, Merge);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the right-hand side, but not the left-hand-side.\n    /// This allows the `V2` value-type to be mapped to the target `V` value-type. \n    /// </remarks>\n    public Unit Union<W>(IEnumerable<(K Key, W Value)> rhs, WhenMissing<K, W, V> MapRight, WhenMatched<K, V, W, V> Merge)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);\n        if (srhs.IsEmpty) return unit;\n        while (true)\n        {\n            var oitems   = this.Items;\n            var onChange = Change;\n            var (nitems, changes) = onChange == null\n                                        ? (oitems.Union(srhs, MapRight, Merge), null)\n                                        : oitems.UnionWithLog(srhs, MapRight, Merge);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                AnnounceChanges(oitems, nitems, changes);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }            \n    }\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is AtomHashMap<K, V> hm && Equals(hm);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals(AtomHashMap<K, V>? other) =>\n        other is not null && Items.Equals(other.Items);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals(HashMap<K, V> other) =>\n        Items.Equals(other.Value);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    public bool EqualsKeys(AtomHashMap<K, V> other) =>\n        Items.Equals<EqTrue<V>>(other.Items);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    public bool EqualsKeys(HashMap<K, V> other) =>\n        Items.Equals<EqTrue<V>>(other.Value);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Items.GetHashCode();\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public AtomHashMap<K, U> Select<U>(Func<V, U> f) =>\n        new (Items.Map(f));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public AtomHashMap<K, U> Select<U>(Func<K, V, U> f) =>\n        new (Items.Map(f));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public AtomHashMap<K, V> Where(Func<V, bool> pred) =>\n        new (Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public AtomHashMap<K, V> Where(Func<K, V, bool> pred) =>\n        new (Items.Filter(pred));\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<K, V, bool> pred)\n    {\n        foreach (var (key, value) in AsIterable())\n        {\n            if (!pred(key, value)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        AsIterable().Map(kv => (kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<V, bool> pred) =>\n        Values.ForAll(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    public bool Exists(Func<K, V, bool> pred)\n    {\n        foreach (var (key, value) in AsIterable())\n        {\n            if (pred(key, value)) return true;\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<(K Key, V Value), bool> pred) =>\n        AsIterable().Map(kv => (kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<KeyValuePair<K, V>, bool> pred) =>\n        AsIterable().Map(kv => new KeyValuePair<K, V>(kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<V, bool> pred) =>\n        Values.Exists(pred);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<K, V> action)\n    {\n        foreach (var (key, value) in this)\n        {\n            action(key, value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<(K Key, V Value)> action)\n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<KeyValuePair<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new KeyValuePair<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        AsIterable().Fold(state, (s, x) => folder(s, x.Key, x.Value));\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, V, S> folder) =>\n        Values.Fold(state, folder);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    void AnnounceChange(TrieMap<EqDefault<K>, K, V> prev, TrieMap<EqDefault<K>, K, V> current, K key, Change<V>? change)\n    {\n        if (change?.HasChanged ?? false)\n        {\n            Change?.Invoke(new HashMapPatch<K, V>(prev, current, key, change));\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    void AnnounceChanges(TrieMap<EqDefault<K>, K, V> prev, TrieMap<EqDefault<K>, K, V> current, TrieMap<EqDefault<K>, K, Change<V>>? changes)\n    {\n        if (changes is not null)\n        {\n            Change?.Invoke(new HashMapPatch<K, V>(prev, current, changes));\n        }\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////////////////\n    //  \n    // IReadOnlyDictionary\n \n    [Pure]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(\n        Func<(K Key, V Value), KR> keySelector, \n        Func<(K Key, V Value), VR> valueSelector) \n        where KR : notnull =>\n        AsIterable().ToDictionary(keySelector, valueSelector);\n    \n    [Pure]\n    public bool TryGetValue(K key, out V value)\n    {\n        var v = Find(key);\n        if (v.IsSome)\n        {\n            value = (V)v;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n        \n    [Pure]\n    IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() =>\n        AsIterable()\n           .Select(p => new KeyValuePair<K, V>(p.Key, p.Value))\n            // ReSharper disable once NotDisposedResourceIsReturned\n           .GetEnumerator() ;\n    \n    [Pure]\n    IEnumerable<K> IReadOnlyDictionary<K, V>.Keys => Keys;\n\n    [Pure]\n    IEnumerable<V> IReadOnlyDictionary<K, V>.Values => Values;\n\n    [Pure]\n    public IReadOnlyDictionary<K, V> ToReadOnlyDictionary() =>\n        this;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomHashMap/Events.cs",
    "content": "﻿using LanguageExt.Traits;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Event sent from the `AtomHashMap` type whenever an operation successfully modifies the underlying data \n    /// </summary>\n    /// <typeparam name=\"K\">Key type</typeparam>\n    /// <typeparam name=\"V\">Value type</typeparam>\n    public delegate void AtomHashMapChangeEvent<K, V>(HashMapPatch<K, V> Patch);\n\n    /// <summary>\n    /// Event sent from the `AtomHashMap` type whenever an operation successfully modifies the underlying data \n    /// </summary>\n    /// <typeparam name=\"K\">Key type</typeparam>\n    /// <typeparam name=\"V\">Value type</typeparam>\n    public delegate void AtomHashMapChangeEvent<EqK, K, V>(HashMapPatch<EqK, K, V> Patch) where EqK : Eq<K>;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomQue/AtomQue.Extensions.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Collections;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class AtomQueExtensions\n{\n    public static AtomQue<A> As<A>(this K<AtomQue, A> ma) =>\n        (AtomQue<A>)ma;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomQue/AtomQue.Trait.Implementation.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class AtomQue : Foldable<AtomQue>\n{\n    static S Foldable<AtomQue>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S state,\n        K<AtomQue, A> ta)\n    {\n        foreach (var item in ta.As())\n        {\n            if (predicate((state, item))) return state;\n            state = f(item)(state);\n        }\n        return state;\n    }\n    \n    static S Foldable<AtomQue>.FoldBackWhile<A, S>(Func<S, Func<A, S>> f, Func<(S State, A Value), bool> predicate, S state, K<AtomQue, A> ta)\n    {\n        foreach (var item in ta.As().Reverse())\n        {\n            if (predicate((state, item))) return state;\n            state = f(state)(item);\n        }\n        return state;\n    }\n    \n    static Fold<A, S> Foldable<AtomQue>.FoldStep<A, S>(K<AtomQue, A> ta, S initialState)\n    {\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n    \n    static Fold<A, S> Foldable<AtomQue>.FoldStepBack<A, S>(K<AtomQue, A> ta, S initialState) \n    {\n        var iter = ta.As().Reverse().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomQue/AtomQue.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Collections;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Event thrown when an item is dequeued from an `AtomQue`\n/// </summary>\n/// <typeparam name=\"A\">Item that was dequeued</typeparam>\npublic delegate void AtomDequeuedEvent<in A>(A value);\n\n/// <summary>\n/// Event thrown when an item is enqueued to an `AtomQue`\n/// </summary>\n/// <typeparam name=\"A\">Item that was enqueued</typeparam>\npublic delegate void AtomEnqueuedEvent<in A>(A value);\n\n/// <summary>\n/// Atoms provide a way to manage shared, synchronous, independent state without \n/// locks.  `AtomQue` wraps the language-ext `Que`, and makes sure all operations are atomic and thread-safe\n/// without resorting to locking.\n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\n/// <typeparam name=\"A\">Item value type</typeparam>\npublic class AtomQue<A> : \n    IEquatable<AtomQue<A>>, \n    IEquatable<Que<A>>,\n    IEnumerable<A>,\n    K<AtomQue, A>\n{\n    QueInternal<A> items;\n    public event AtomDequeuedEvent<A>? Dequeued;\n    public event AtomEnqueuedEvent<A>? Enqueued;\n\n    internal AtomQue() =>\n        items = QueInternal<A>.Empty;\n\n    internal AtomQue(IEnumerable<A> items) =>\n        this.items = new QueInternal<A>(items);\n\n    internal AtomQue(Que<A> items) =>\n        this.items = new QueInternal<A>(items);\n\n    /// <summary>\n    /// Impure iteration of the bound value in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Unit Do(Action<A> f)\n    {\n        this.Iter(f);\n        return default;\n    }\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = null\n    ///     Singleton collection = A\n    ///     More                 = (A, Seq〈A〉)   -- head and tail\n    ///\n    ///     var res = list.Case switch\n    ///     {\n    ///       \n    ///        (var x, var xs) => ...,\n    ///        A value         => ...,\n    ///        _               => ...\n    ///     }\n    /// \n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty\n            ? null\n            : toSeq(items).Case;\n\n    /// <summary>\n    /// Is the queue empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items.IsEmpty;\n    }\n\n    /// <summary>\n    /// Number of items in the queue\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items.Count;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items.Count;\n    }\n\n    /// <summary>\n    /// Clears the queue atomically\n    /// </summary>\n    public Unit Clear()\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            if (oitems.IsEmpty) return default;\n            var nitems = new QueInternal<A>();\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                if (Dequeued != null)\n                {\n                    foreach (var x in oitems)\n                    {\n                        Dequeued?.Invoke(x);\n                    }\n                }\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Look at the item at the front of the queue, if it exists.  \n    /// </summary>\n    /// <returns>The item at the front of the queue, if it exists.  `None` otherwise.</returns>\n    [Pure]\n    public Option<A> Peek()\n    {\n        var xs = items;\n        return xs.IsEmpty\n            ? None\n            : xs.Peek();\n    }\n\n    /// <summary>\n    /// Removes the item from the front of the queue atomically\n    /// </summary>\n    /// <returns>The item that was at the front of the queue (if it existed, `None` otherwise)</returns>\n    public Option<A> Dequeue()\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            if (oitems.IsEmpty) return default;\n            var top = oitems.Peek();\n            var nitems = oitems.Dequeue();\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                Dequeued?.Invoke(top);\n                return top;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Removes the item from the front of the queue atomically\n    /// </summary>\n    /// <exception cref=\"ExpectedException\">If the queue is empty</exception>\n    /// <returns>The item that was at the front of the queue, or an `InvalidOperationException` exception</returns>\n    public A DequeueUnsafe()\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            if (oitems.IsEmpty) throw Exceptions.SequenceEmpty;\n            var top = oitems.Peek();\n            var nitems = oitems.Dequeue();\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                Dequeued?.Invoke(top);\n                return top;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Add an item to the end of the queue atomically\n    /// </summary>\n    /// <param name=\"value\">Value to add to the queue</param>\n    public Unit Enqueue(A value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = oitems.Enqueue(value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                Enqueued?.Invoke(value);\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n    \n    [Pure]\n    public Seq<A> ToSeq() =>\n        items.ToSeq();\n\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        items.AsIterable();\n\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsIterable().GetEnumerator();\n\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsIterable().GetEnumerator();\n\n    [Pure]\n    public Unit Append(Que<A> rhs)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = oitems.Combine(rhs.Value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                if (Enqueued != null)\n                {\n                    foreach (var item in rhs.Value)\n                    {\n                        Enqueued?.Invoke(item);\n                    }\n                }\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    [Pure]\n    public Unit Append(AtomQue<A> rhs)\n    {\n        var ritems = rhs.items;\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = oitems.Combine(ritems);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                if (Enqueued != null)\n                {\n                    foreach (var item in ritems)\n                    {\n                        Enqueued?.Invoke(item);\n                    }\n                }\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    [Pure]\n    public static bool operator ==(AtomQue<A> lhs, AtomQue<A> rhs) =>\n        lhs.Equals(rhs);\n\n    [Pure]\n    public static bool operator ==(AtomQue<A> lhs, Que<A> rhs) =>\n        lhs.Equals(rhs);\n\n    [Pure]\n    public static bool operator ==(Que<A> lhs, AtomQue<A> rhs) =>\n        rhs.Equals(lhs);\n\n    [Pure]\n    public static bool operator !=(AtomQue<A> lhs, AtomQue<A> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public static bool operator !=(Que<A> lhs, AtomQue<A> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public static bool operator !=(AtomQue<A> lhs, Que<A> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public override int GetHashCode() =>\n        items.GetHashCode();\n\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj switch\n        {\n            AtomQue<A> q => this == q,\n            Que<A> q     => this == q,\n            _            => false\n        };\n\n    [Pure]\n    public bool Equals(AtomQue<A>? other) =>\n        other is not null &&\n        GetHashCode() == other.GetHashCode() &&\n        EqEnumerable<A>.Equals(items, other.items);\n\n    [Pure]\n    public bool Equals(Que<A> other) =>\n        GetHashCode() == other.GetHashCode() &&\n        EqEnumerable<A>.Equals(items, other.Value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/AtomSeq/AtomSeq.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Atoms provide a way to manage shared, synchronous, independent state without \n/// locks.  `AtomSeq` wraps the language-ext `Seq`, and makes sure all operations are atomic and thread-safe\n/// without resorting to locking\n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\n/// <typeparam name=\"A\">Item value type</typeparam>\npublic class AtomSeq<A> : \n    IComparable<AtomSeq<A>>, \n    IEquatable<AtomSeq<A>>, \n    IComparable<Seq<A>>, \n    IEquatable<Seq<A>>,\n    IEnumerable<A>,\n    IComparable\n{\n    /// <summary>\n    /// Empty sequence\n    /// </summary>\n    public static AtomSeq<A> Empty => new (SeqEmptyInternal<A>.Default);\n\n    /// <summary>\n    /// Internal representation of the sequence (SeqStrict|SeqLazy|SeqEmptyInternal)\n    /// </summary>\n    volatile ISeqInternal<A> items;\n\n    /// <summary>\n    /// Constructor from lazy sequence\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public AtomSeq(IEnumerable<A> ma) : this(new SeqLazy<A>(ma)) { }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal AtomSeq(ISeqInternal<A> items) =>\n        this.items = items;\n\n    /// <summary>\n    /// Convert to an immutable sequence\n    /// </summary>\n    /// <remarks>This is effectively a zero cost operation, not even a single allocation</remarks>\n    [Pure]\n    public Seq<A> ToSeq() =>\n        new (items);\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    [Pure]\n    public object? Case\n    {\n        get\n        {\n            var xs = items;\n            return xs.IsEmpty\n                       ? null\n                       : xs.Tail.IsEmpty\n                           ? xs.Head\n                           : (xs.Head, xs.Tail);\n        }\n    }\n\n    public void Deconstruct(out A head, out Seq<A> tail)\n    {\n        var xs = items;\n        head = xs.Head;\n        tail = new Seq<A>(xs.Tail);\n    }\n        \n    /// <summary>\n    /// Indexer\n    /// </summary>\n    public A this[int index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items[index];\n    }\n        \n    /// <summary>\n    /// Atomically swap the underlying Seq.  Allows for multiple operations on the Seq in an entirely\n    /// transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of the AtomSeq to a new state</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public IO<Unit> SwapIO(Func<Seq<A>, Seq<A>> swap) =>\n        IO.lift(_ => Swap(swap));\n        \n    /// <summary>\n    /// Atomically swap the underlying Seq.  Allows for multiple operations on the Seq in an entirely\n    /// transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of the AtomSeq to a new state</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit Swap(Func<Seq<A>, Seq<A>> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = swap(new Seq<A>(oitems)).Value;\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Atomically swap the underlying Seq.  Allows for multiple operations on the Seq in an entirely\n    /// transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of the AtomSeq to a new state</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    internal Unit SwapInternal(Func<ISeqInternal<A>, ISeqInternal<A>> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = swap(oitems);\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Add an item to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the item \n    /// can be appended\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Add(A value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = oitems.Add(value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Concat(IEnumerable<A> items) => items switch\n                                                {\n                                                    Lst<A> lst              => Concat(lst),\n                                                    Set<A> set              => Concat(set),\n                                                    HashSet<A> hset         => Concat(hset),\n                                                    Arr<A> arr              => Concat(arr),\n                                                    Stck<A> stck            => Concat(stck),\n                                                    IReadOnlyList<A> rolist => Concat(rolist),\n                                                    _                       => Concat(toSeq(items))\n                                                };\n                           \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Concat(Lst<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return default;\n        }\n        var arr = items.Value.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n        \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Concat(Set<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return default;\n        }\n        var arr = items.Value.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n                \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Concat(HashSet<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return default;\n        }\n        var arr = items.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n        \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Concat(Stck<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return default;\n        }\n        var arr = items.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Concat(IReadOnlyCollection<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return default;\n        }\n\n        var arr = items.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n        \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    public Unit Concat(Seq<A> rhs)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n\n            var nitems = oitems.Type switch\n                         {\n                             SeqType.Empty =>\n\n                                 // lhs is empty, so just return rhs\n                                 rhs.Value,\n\n                             SeqType.Lazy =>\n                                 rhs.Value.Type switch\n                                 {\n                                     // lhs lazy, rhs empty\n                                     // return lhs\n                                     SeqType.Empty => oitems,\n\n                                     // lhs lazy, rhs lazy\n                                     // return SeqConcat\n                                     SeqType.Lazy => new SeqConcat<A>(Seq(oitems, rhs.Value)),\n\n                                     // lhs lazy, rhs strict\n                                     // force lhs to be strict and concat the two \n                                     SeqType.Strict =>\n                                         ((SeqStrict<A>)oitems.Strict()).Append((SeqStrict<A>)rhs.Value),\n\n                                     // lhs lazy, rhs concat\n                                     // prepend rhs with lhs\n                                     SeqType.Concat =>\n                                         ((SeqConcat<A>)rhs.Value).ConsSeq(oitems),\n\n                                     _ => throw new NotSupportedException()\n                                 },\n\n                             SeqType.Strict =>\n                                 rhs.Value.Type switch\n                                 {\n                                     // lhs strict, rhs empty\n                                     // return lhs\n                                     SeqType.Empty => oitems,\n\n                                     // lhs strict, rhs lazy\n                                     // return SeqConcat\n                                     SeqType.Lazy =>\n                                         new SeqConcat<A>(Seq(oitems, rhs.Value)),\n\n                                     // lhs strict, rhs strict\n                                     // append the two\n                                     SeqType.Strict =>\n                                         ((SeqStrict<A>)oitems).Append((SeqStrict<A>)rhs.Value),\n\n                                     // lhs strict, rhs concat\n                                     // prepend rhs with lhs\n                                     SeqType.Concat =>\n                                         ((SeqConcat<A>)rhs.Value).ConsSeq(oitems),\n\n                                     _ => throw new NotSupportedException()\n                                 },\n\n                             SeqType.Concat =>\n                                 rhs.Value.Type switch\n                                 {\n                                     // lhs concat, rhs empty\n                                     // return lhs\n                                     SeqType.Empty =>\n                                         oitems,\n\n                                     // lhs concat, rhs lazy || lhs concat, rhs strict\n                                     // add rhs to concat\n                                     SeqType.Lazy =>\n                                         ((SeqConcat<A>)oitems).AddSeq(rhs.Value),\n\n                                     SeqType.Strict =>\n                                         ((SeqConcat<A>)oitems).AddSeq(rhs.Value),\n\n                                     // lhs concat, rhs concat\n                                     // add rhs to concat\n                                     SeqType.Concat =>\n                                         ((SeqConcat<A>)oitems).AddSeqRange(((SeqConcat<A>)rhs.Value).ms),\n\n                                     _ => throw new NotSupportedException()\n                                 },\n\n                             _ => throw new NotSupportedException()\n                         };\n\n            if (ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Prepend an item to the sequence\n    /// </summary>\n    internal Unit Cons(A value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = oitems.Cons(value);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Head item in the sequence.  NOTE:  If `IsEmpty` is true then Head \n    /// is undefined.  Call HeadOrNone() if for maximum safety.\n    /// </summary>\n    public A Head\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items.Head;\n    }\n\n    /// <summary>\n    /// Tail of the sequence\n    /// </summary>\n    public Seq<A> Tail\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new Seq<A>(items.Tail);\n    }\n\n    /// <summary>\n    /// Get all items except the last one\n    /// </summary>\n    public Seq<A> Init\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new Seq<A>(items.Init);\n    }\n\n    /// <summary>\n    /// Head of the sequence if this node isn't the empty node\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<A> HeadOrNone()\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? None\n                   : Some(xs.Head);\n    }\n\n    /// <summary>\n    /// Last item in sequence.  Throws if no items in sequence\n    /// </summary>\n    public A Last\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items.Last;\n    }\n\n    /// <summary>\n    /// Last item in sequence.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<A> LastOrNone()\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? None\n                   : Some(xs.Last);\n    }\n\n    /// <summary>\n    /// Last item in sequence.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Either<L, A> LastOrLeft<L>(L Left)\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? Either.Left<L, A>(Left)\n                   : Either.Right<L, A>(xs.Last);\n    }\n\n    /// <summary>\n    /// Last item in sequence.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Either<L, A> LastOrLeft<L>(Func<L> Left)\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? Either.Left<L, A>(Left())\n                   : Either.Right<L, A>(xs.Last);\n    }\n\n    /// <summary>\n    /// Head of the sequence if this node isn't the empty node or left\n    /// </summary>\n    /// <typeparam name=\"L\"></typeparam>\n    /// <param name=\"left\">Left case</param>\n    /// <returns>Head of the sequence or left</returns>\n    [Pure]\n    public Either<L, A> HeadOrLeft<L>(L left)\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? Left<L, A>(left)\n                   : Right<L, A>(xs.Head);\n    }\n\n    /// <summary>\n    /// Head of the sequence if this node isn't the empty node\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Either<L, A> HeadOrLeft<L>(Func<L> Left)\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? Left<L, A>(Left())\n                   : Right<L, A>(xs.Head);\n    }\n\n    /// <summary>\n    /// Returns true if the sequence is empty\n    /// </summary>\n    /// <remarks>\n    /// For lazy streams this will have to peek at the first \n    /// item.  So, the first item will be consumed.\n    /// </remarks>\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items.IsEmpty;\n    }\n\n    /// <summary>\n    /// Returns the number of items in the sequence\n    /// </summary>\n    /// <returns>Number of items in the sequence</returns>\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items.Count;\n    }\n        \n    /// <summary>\n    /// Alias of `Count`\n    /// </summary>\n    /// <returns>Number of items in the sequence</returns>\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => items.Count;\n    }\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> AsIterable() => \n        items.AsIterable();\n\n    /// <summary>\n    /// Match empty sequence, or multi-item sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"Tail\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(Func<B> Empty, Func<A, Seq<A>, B> Tail)\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? Empty()\n                   : Tail(xs.Head, new Seq<A>(xs.Tail));\n    }\n\n    /// <summary>\n    /// Match empty sequence, or one item sequence, or multi-item sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"Tail\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(\n        Func<B> Empty,\n        Func<A, B> Head,\n        Func<A, Seq<A>, B> Tail)\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? Empty()\n                   : xs.Tail.IsEmpty\n                       ? Head(xs.Head)\n                       : Tail(xs.Head, new Seq<A>(xs.Tail));\n    }\n\n    /// <summary>\n    /// Match empty sequence, or multi-item sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"Sequence\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(\n        Func<B> Empty,\n        Func<Seq<A>, B> Seq)\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? Empty()\n                   : Seq(new Seq<A>(xs));\n    }\n\n    /// <summary>\n    /// Match empty sequence, or one item sequence, or multi-item sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"Tail\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(\n        Func<B> Empty,\n        Func<A, B> Head,\n        Func<Seq<A>, B> Tail)\n    {\n        var xs = items;\n        return xs.IsEmpty\n                   ? Empty()\n                   : xs.Tail.IsEmpty\n                       ? Head(xs.Head)\n                       : Tail(new Seq<A>(xs.Tail));\n    }\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<A> f) =>\n        items.Iter(f);\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public Seq<B> Map<B>(Func<A, B> f)\n    {\n        return new Seq<B>(new SeqLazy<B>(Yield(items)));\n        IEnumerable<B> Yield(ISeqInternal<A> items)\n        {\n            foreach (var item in items)\n            {\n                yield return f(item);\n            }\n        }\n    }\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    [Pure]\n    public Unit MapInPlace(Func<A, A> f)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = new SeqLazy<A>(oitems.Select(f));\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }        \n        \n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Flatmapped sequence</returns>\n    [Pure]\n    public Seq<B> Bind<B>(Func<A, Seq<B>> f)\n    {\n        static IEnumerable<B> Yield(ISeqInternal<A> ma, Func<A, Seq<B>> bnd)\n        {\n            foreach (var a in ma)\n            {\n                foreach (var b in bnd(a))\n                {\n                    yield return b;\n                }\n            }\n        }\n        return new Seq<B>(Yield(items, f));\n    }\n        \n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit BindInPlace<B>(Func<A, Seq<A>> f)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = new Seq<A>(oitems).Bind(f);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems.Value, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"bind\">Bind function</param>\n    /// <returns>Flatmapped sequence</returns>\n    [Pure]\n    public Seq<C> SelectMany<B, C>(Func<A, Seq<B>> bind, Func<A, B, C> project)\n    {\n        static IEnumerable<C> Yield(ISeqInternal<A> ma, Func<A, Seq<B>> bnd, Func<A, B, C> prj)\n        {\n            foreach (var a in ma)\n            {\n                foreach (var b in bnd(a))\n                {\n                    yield return prj(a, b);\n                }\n            }\n        }\n        return new Seq<C>(Yield(items, bind, project));\n    }\n\n    /// <summary>\n    /// Filter the items in the sequence\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply to the items</param>\n    /// <returns>Filtered sequence</returns>\n    [Pure]\n    public Seq<A> Filter(Func<A, bool> f)\n    {\n        return new Seq<A>(new SeqLazy<A>(Yield(items, f)));\n        static IEnumerable<A> Yield(ISeqInternal<A> items, Func<A, bool> f)\n        {\n            foreach (var item in items)\n            {\n                if (f(item))\n                {\n                    yield return item;\n                }\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Filter the items in the sequence\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply to the items</param>\n    /// <returns>Filtered sequence</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit FilterInPlace(Func<A, bool> f)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = new SeqLazy<A>(oitems.Where(f));\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Filter the items in the sequence\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply to the items</param>\n    /// <returns>Filtered sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Where(Func<A, bool> f) =>\n        Filter(f);\n\n    /// <summary>\n    /// Fold the sequence from the first item to the last\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"f\">Fold function</param>\n    /// <returns>Aggregated state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, A, S> f) =>\n        items.Fold(state, f);\n\n    /// <summary>\n    /// Fold the sequence from the last item to the first.  For \n    /// sequences that are not lazy and are less than 5000 items\n    /// long, FoldBackRec is called instead, because it is faster.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"f\">Fold function</param>\n    /// <returns>Aggregated state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S FoldBack<S>(S state, Func<S, A, S> f) =>\n        items.FoldBack(state, f);\n\n    /// <summary>\n    /// Returns true if the supplied predicate returns true for any\n    /// item in the sequence.  False otherwise.\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply</param>\n    /// <returns>True if the supplied predicate returns true for any\n    /// item in the sequence.  False otherwise.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<A, bool> f) =>\n        items.Exists(f);\n\n    /// <summary>\n    /// Returns true if the supplied predicate returns true for all\n    /// items in the sequence.  False otherwise.  If there is an \n    /// empty sequence then true is returned.\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply</param>\n    /// <returns>True if the supplied predicate returns true for all\n    /// items in the sequence.  False otherwise.  If there is an \n    /// empty sequence then true is returned.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<A, bool> f) =>\n        items.ForAll(f);\n\n    /// <summary>\n    /// Returns true if the sequence has items in it\n    /// </summary>\n    /// <returns>True if the sequence has items in it</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Any() =>\n        !IsEmpty;\n\n    /// <summary>\n    /// Inject a value in between each item in the sequence \n    /// </summary>\n    /// <param name=\"ma\">Sequence to inject values into</param>\n    /// <param name=\"value\">Item to inject</param>\n    /// <typeparam name=\"A\">Bound type</typeparam>\n    /// <returns>A sequence with the values injected</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Intersperse(A value)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = new SeqLazy<A>(oitems.Intersperse(value));\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Get the hash code for all of the items in the sequence, or 0 if empty\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        items.GetHashCode();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(object? obj) => obj switch \n                                         {\n                                             AtomSeq<A>     s => CompareTo(s),\n                                             Seq<A>         s => CompareTo(s),\n                                             IEnumerable<A> e => CompareTo(toSeq(e)),\n                                             _                => 1\n                                         };\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        items is SeqLazy<A> lz\n            ? CollectionFormat.ToShortArrayString(lz)\n            : CollectionFormat.ToShortArrayString(items, Count);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(items, separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(items, separator);\n\n    /// <summary>\n    /// Ordering operator\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >(AtomSeq<A> x, AtomSeq<A> y) =>\n        x.CompareTo(y) > 0;\n\n    /// <summary>\n    /// Ordering operator\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >=(AtomSeq<A> x, AtomSeq<A> y) =>\n        x.CompareTo(y) >= 0;\n\n    /// <summary>\n    /// Ordering  operator\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <(AtomSeq<A> x, AtomSeq<A> y) =>\n        x.CompareTo(y) < 0;\n\n    /// <summary>\n    /// Ordering  operator\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <=(AtomSeq<A> x, AtomSeq<A> y) =>\n        x.CompareTo(y) <= 0;\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(AtomSeq<A> x, AtomSeq<A> y) =>\n        x.Equals(y);\n\n    /// <summary>\n    /// Non-equality operator\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(AtomSeq<A> x, AtomSeq<A> y) =>\n        !(x == y);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) => obj switch \n                                                {\n                                                    AtomSeq<A>     s => Equals(s),\n                                                    Seq<A>         s => Equals(s),\n                                                    IEnumerable<A> e => Equals(toSeq(e)),\n                                                    _                => false\n                                                };\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(Seq<A> rhs) =>\n        Equals<EqDefault<A>>(rhs);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(AtomSeq<A>? rhs) =>\n        rhs is not null && Equals<EqDefault<A>>(rhs);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public bool Equals<EqA>(Seq<A> rhs) where EqA : Eq<A>\n    {\n        var lhs = items;\n            \n        // Differing lengths?\n        if(lhs.Count != rhs.Count) return false;\n\n        // If the hash code has been calculated on both sides then \n        // check for differences\n        if (lhs.GetHashCode() != rhs.GetHashCode())\n        {\n            return false;\n        }\n\n        // Iterate through both sides\n        using var iterA = lhs.GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            if (!EqA.Equals(iterA.Current, iterB.Current))\n            {\n                return false;\n            }\n        }\n\n        return true;\n    }\n        \n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public bool Equals<EqA>(AtomSeq<A> rhs) where EqA : Eq<A>\n    {\n        var lhs = items;\n            \n        // Differing lengths?\n        if(lhs.Count != rhs.Count) return false;\n\n        // If the hash code has been calculated on both sides then \n        // check for differences\n        if (lhs.GetHashCode() != rhs.GetHashCode())\n        {\n            return false;\n        }\n\n        // Iterate through both sides\n        using var iterA = lhs.GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            if (!EqA.Equals(iterA.Current, iterB.Current))\n            {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /// <summary>\n    /// Skip count items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Skip(int amount)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = new SeqLazy<A>(oitems.Skip(amount));\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Take count items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Take(int amount)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = new SeqLazy<A>(oitems.Take(amount));\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate \n    /// provided, and stopping as soon as one doesn't\n    /// </summary>\n    /// <returns>A new sequence with the first items that match the \n    /// predicate</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit TakeWhile(Func<A, bool> pred)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = new SeqLazy<A>(oitems.TakeWhile(pred));\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate \n    /// provided, and stopping as soon as one doesn't.  An index value is \n    /// also provided to the predicate function.\n    /// </summary>\n    /// <returns>A new sequence with the first items that match the \n    /// predicate</returns>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit TakeWhile(Func<A, int, bool> pred)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = items;\n            var nitems = new SeqLazy<A>(oitems.TakeWhile(pred));\n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Returns all initial segments of the sequence, shortest first\n    /// </summary>\n    /// <remarks>\n    /// Including the empty sequence\n    /// </remarks>\n    /// <example>\n    ///\n    ///      Seq(\"a\", \"b\", \"c\").Inits\n    ///\n    ///      > Seq(Seq(), Seq(\"a\"), Seq(\"a\", \"b\"), Seq(\"a\", \"b\", \"c\"))  \n    ///     \n    /// </example>\n    /// <returns>Initial segments of the sequence</returns>\n    public Seq<Seq<A>> Inits =>\n        [Seq<A>()] + NonEmptyInits;\n\n    /// <summary>\n    /// Returns all initial segments of the sequence, shortest first.\n    /// </summary>\n    /// <remarks>\n    /// Not including the empty sequence\n    /// </remarks>\n    /// <example>\n    ///\n    ///      Seq(\"a\", \"b\", \"c\").Inits\n    ///\n    ///      > Seq(Seq(\"a\"), Seq(\"a\", \"b\"), Seq(\"a\", \"b\", \"c\"))  \n    ///     \n    /// </example>\n    /// <returns>Initial segments of the sequence</returns>\n    public Seq<Seq<A>> NonEmptyInits =>\n        ToSeq().NonEmptyInits;\n\n    /// <summary>\n    /// Returns all final segments of the argument, longest first.\n    /// </summary>\n    /// <remarks>\n    /// Including the empty sequence\n    /// </remarks>\n    /// <example>\n    ///\n    ///      Seq(\"a\", \"b\", \"c\").Tails\n    ///\n    ///      > Seq(Seq(\"a\", \"b\", \"c\"), Seq(\"a\", \"b\"), Seq(\"a\"), Seq())  \n    ///     \n    /// </example>\n    /// <returns>Initial segments of the sequence</returns>\n    public Seq<Seq<A>> Tails =>\n        ToSeq().Tails;\n\n    /// <summary>\n    /// Returns all final segments of the argument, longest first.\n    /// </summary>\n    /// <remarks>\n    /// Not including the empty sequence\n    /// </remarks>\n    /// <example>\n    ///\n    ///      Seq(\"a\", \"b\", \"c\").Tails\n    ///\n    ///      > Seq(Seq(\"a\", \"b\", \"c\"), Seq(\"a\", \"b\"), Seq(\"a\"))  \n    ///     \n    /// </example>\n    /// <returns>Initial segments of the sequence</returns>\n    public Seq<Seq<A>> NonEmptyTails =>\n        ToSeq().NonEmptyTails;\n\n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public int CompareTo(Seq<A> rhs) =>\n        CompareTo<OrdDefault<A>>(rhs);\n\n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public int CompareTo(AtomSeq<A>? rhs) =>\n        rhs is null \n            ? 1\n            : CompareTo<OrdDefault<A>>(rhs);\n\n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public int CompareTo<OrdA>(Seq<A> rhs) where OrdA : Ord<A>\n    {\n        var lhs = items;\n            \n        // Differing lengths?\n        var cmp = lhs.Count.CompareTo(rhs.Count);\n        if (cmp != 0) return cmp;\n\n        // Iterate through both sides\n        using var iterA = lhs.GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            cmp = OrdA.Compare(iterA.Current, iterB.Current);\n            if (cmp != 0) return cmp;\n        }\n\n        return 0;\n    }\n        \n        \n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public int CompareTo<OrdA>(AtomSeq<A> rhs) where OrdA : Ord<A>\n    {\n        var lhs = items;\n            \n        // Differing lengths?\n        var cmp = lhs.Count.CompareTo(rhs.Count);\n        if (cmp != 0) return cmp;\n\n        // Iterate through both sides\n        using var iterA = lhs.GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            cmp = OrdA.Compare(iterA.Current, iterB.Current);\n            if (cmp != 0) return cmp;\n        }\n\n        return 0;\n    }\n\n    /// <summary>\n    /// Force all items lazy to stream\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Strict() => \n        ignore(items.Strict());\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerator<A> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        items.GetEnumerator();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        items.GetEnumerator();\n\n    [Pure]\n    public Seq<B> Cast<B>() =>\n        ToSeq().Cast<B>();\n}\n\npublic static class AtomSeqExtensions\n{\n    /// <summary>\n    /// Last item in sequence.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Validation<F, A> LastOrInvalid<F, A>(this AtomSeq<A> ma, F Fail)\n        where F : Monoid<F>\n    {\n        var xs = ma.ToSeq();\n        return xs.IsEmpty\n                   ? Validation.Fail<F, A>(Fail)\n                   : Validation.Success<F, A>((A)xs.Last);\n    }\n\n    /// <summary>\n    /// Head of the sequence if this node isn't the empty node or fail\n    /// </summary>\n    /// <returns>Head of the sequence or fail</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Validation<F, A> HeadOrInvalid<F, A>(this AtomSeq<A> ma, F Fail)\n        where F : Monoid<F>\n    {\n        var xs = ma.ToSeq();\n        return xs.IsEmpty\n                   ? Validation.Fail<F, A>(Fail)\n                   : Pure((A)xs.Head);\n    }\n    \n    /// <summary>\n    /// Last item in sequence.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Validation<F, A> LastOrInvalid<F, A>(this AtomSeq<A> ma, Func<F> Fail)\n        where F : Monoid<F>\n    {\n        var xs = ma.ToSeq();\n        return xs.IsEmpty\n                   ? Validation.Fail<F, A>(Fail())\n                   : Pure((A)xs.Last);\n    }\n\n    /// <summary>\n    /// Head of the sequence if this node isn't the empty node or fail\n    /// </summary>\n    /// <returns>Head of the sequence or fail</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Validation<F, A> HeadOrInvalid<F, A>(this AtomSeq<A> ma, Func<F> Fail)\n        where F : Monoid<F>\n    {\n        var xs = ma.ToSeq();\n        return xs.IsEmpty\n                   ? Validation.Fail<F, A>(Fail())\n                   : Pure((A)xs.Head);\n    }\n    \n    /// <summary>\n    /// Last item in sequence.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Validation<F, A> LastOrInvalid<F, A>(this AtomSeq<A> ma)\n        where F : Monoid<F>\n    {\n        var xs = ma.ToSeq();\n        return xs.IsEmpty\n                   ? Fail(F.Empty)\n                   : Pure((A)xs.Last);\n    }\n\n    /// <summary>\n    /// Head of the sequence if this node isn't the empty node or fail\n    /// </summary>\n    /// <returns>Head of the sequence or fail</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Validation<F, A> HeadOrInvalid<F, A>(this AtomSeq<A> ma)\n        where F : Monoid<F>\n    {\n        var xs = ma.ToSeq();\n        return xs.IsEmpty\n                   ? Fail(F.Empty)\n                   : Pure((A)xs.Head);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Conflict.cs",
    "content": "namespace LanguageExt;\n\n/// <summary>\n/// Trait that defines how to deal with a conflict between two values\n/// </summary>\n/// <typeparam name=\"V\">Value type</typeparam>\npublic interface Conflict<V>\n{\n    public static abstract (long TimeStamp, Option<V> Value) Resolve((long TimeStamp, Option<V> Value) Current,\n                                                                     (long TimeStamp, Option<V> Value) Proposed);\n}\n\n/// <summary>\n/// Last-write-wins conflict resolver\n/// </summary>\npublic struct LastWriteWins<V> : Conflict<V>\n{\n    public static (long TimeStamp, Option<V> Value) Resolve((long TimeStamp, Option<V> Value) Current,\n                                                            (long TimeStamp, Option<V> Value) Proposed) =>\n        Proposed.TimeStamp >= Current.TimeStamp\n            ? Proposed\n            : Current;\n}\n\n/// <summary>\n/// First-write-wins conflict resolver\n/// </summary>\npublic struct FirstWriteWins<V> : Conflict<V>\n{\n    public static (long TimeStamp, Option<V> Value) Resolve((long TimeStamp, Option<V> Value) Current,\n                                                            (long TimeStamp, Option<V> Value) Proposed) =>\n        Current.TimeStamp <= Proposed.TimeStamp\n            ? Current\n            : Proposed;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Prelude.Concurrency.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Generates a new reference that can be used within a `sync` transaction\n    /// \n    /// `Refs` ensure safe shared use of mutable storage locations via a software transactional \n    /// memory (STM) system. `Refs` are bound to a single storage location for their lifetime, \n    /// and only allow mutation of that location to occur within a transaction.\n    /// </summary>\n    /// <remarks>\n    /// \n    /// Transactions (within a `sync(() => ...)`) should be easy to understand if you’ve ever used database \n    /// transactions - they ensure that all actions on Refs are atomic, consistent, and isolated. \n    /// \n    ///  * **Atomic** - means that every change to Refs made within a transaction occurs or none do. \n    ///  * **Consistent** - means that each new value can be checked with a validator function before allowing \n    /// the transaction to commit. \n    ///  * **Isolated** - means that no transaction sees the effects of any other transaction while it is \n    /// running. \n    /// \n    /// Another feature common to STMs is that, should a transaction have a conflict while running, \n    /// it is automatically retried.  The language-ext STM uses multi-version concurrency control for \n    /// snapshot and serialisable isolation.\n    /// \n    /// In practice, this means:\n    ///\n    /// All reads of Refs will see a consistent snapshot of the _Ref world_ as of the starting point \n    /// of the transaction (its 'read point'). The transaction will see any changes it has made. \n    /// This is called the in-transaction-value.\n    ///\n    /// All changes made to Refs during a transaction will appear to occur at a single point in the \n    /// _Ref world_ timeline (its 'write point').\n    ///\n    /// No changes will have been made by any other transactions to any Refs that have been modified \n    /// by this transaction.\n    ///\n    ///  * Readers will never block writers, or other readers.\n    ///\n    ///  * Writers will never block readers.\n    ///\n    /// I/O and other activities with side-effects should be avoided in transactions, since transactions \n    /// will be retried. \n    ///\n    /// If a constraint on the validity of a value of a Ref that is being changed depends upon the \n    /// simultaneous value of a Ref that is not being changed, that second Ref can be protected from \n    /// modification by running the `sync` transaction with `Isolation.Serialisable`.\n    ///\n    /// The language-ext STM is designed to work with the persistent collections (`Map`, `HashMap`, \n    /// `Seq`, `Lst`, `Set, `HashSet` etc.), and it is strongly recommended that you use the language-ext \n    /// collections as the values of your Refs. Since all work done in an STM transaction is speculative, \n    /// it is imperative that there be a low cost to making copies and modifications. Persistent collections \n    /// have free copies (just use the original, it can’t be changed), and 'modifications' share structure \n    /// efficiently. In any case:\n    ///\n    /// The values placed in Refs must be, or be considered, **immutable**. Otherwise, this library can’t help you.\n    /// </remarks>\n    /// <remarks>\n    /// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n    /// </remarks>\n    /// <param name=\"value\">Initial value of the ref</param>\n    /// <param name=\"validator\">Validator that is called on the ref value just\n    /// before any transaction is committed (within a `sync`)</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Ref<A> Ref<A>(A value, Func<A, bool>? validator = null) =>\n        STM.NewRef(value, validator);\n        \n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does read from or written to the values used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the strictest form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would *not* cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static R atomic<R>(Func<R> op, Isolation isolation = Isolation.Snapshot) =>\n        STM.DoTransaction(op, isolation);\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does read from or written to the values used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the strictest form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would *not* cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit atomic(Action op, Isolation isolation = Isolation.Snapshot) =>\n        STM.DoTransaction(() => { op(); return unit; }, isolation);\n        \n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static R snapshot<R>(Func<R> op) =>\n        STM.DoTransaction(op, Isolation.Snapshot);\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit snapshot(Action op) =>\n        STM.DoTransaction(() => { op(); return unit; }, Isolation.Snapshot);        \n        \n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does read from or written to the values used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the strictest form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would *not* cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static R serial<R>(Func<R> op) =>\n        STM.DoTransaction(op, Isolation.Snapshot);\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does read from or written to the values used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the strictest form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would *not* cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit serial(Action op) =>\n        STM.DoTransaction(() => { op(); return unit; }, Isolation.Snapshot);        \n    \n    /// <summary>\n    /// Swap the old value for the new returned by `f`\n    /// Must be run within a `sync` transaction\n    /// </summary>\n    /// <param name=\"r\">`Ref` to process</param>\n    /// <param name=\"f\">Function to update the `Ref`</param>\n    /// <returns>The value returned from `f`</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static A swap<A>(Ref<A> r, Func<A, A> f) =>\n        r.Swap(f);\n\n    /// <summary>\n    /// Must be called in a transaction. Sets the in-transaction-value of\n    /// ref to:  \n    /// \n    ///     `f(in-transaction-value-of-ref)`\n    ///     \n    /// and returns the in-transaction-value when complete.\n    /// \n    /// At the commit point of the transaction, `f` is run *AGAIN* with the\n    /// most recently committed value:\n    /// \n    ///     `f(most-recently-committed-value-of-ref)`\n    /// \n    /// Thus `f` should be commutative, or, failing that, you must accept\n    /// last-one-in-wins behavior.\n    /// \n    /// Commute allows for more concurrency than just setting the Ref's value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static A commute<A>(Ref<A> r, Func<A, A> f) =>\n        r.Commute(f);\n\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks. \n    /// </summary>\n    /// <param name=\"value\">Initial value of the atom</param>\n    /// <returns>The constructed Atom</returns>\n    /// <remarks>\n    /// The intended use of atom is to hold one an immutable data structure. You change \n    /// the value by applying a function to the old value. This is done in an atomic \n    /// manner by `Swap`.  \n    /// \n    /// Internally, `Swap` reads the current value, applies the function to it, and \n    /// attempts to `CompareExchange` it in. Since another thread may have changed the \n    /// value in the intervening time, it may have to retry, and does so in a spin loop. \n    /// \n    /// The net effect is that the value will always be the result of the application \n    /// of the supplied function to a current value, atomically. However, because the \n    /// function might be called multiple times, it must be free of side effects.\n    /// \n    /// Atoms are an efficient way to represent some state that will never need to be \n    /// coordinated with any other, and for which you wish to make synchronous changes.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Atom<A> Atom<A>(A value) =>\n        LanguageExt.Atom<A>.New(value);\n\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks. \n    /// </summary>\n    /// <param name=\"value\">Initial value of the atom</param>\n    /// <param name=\"validator\">Function to run on the value after each state change.  \n    /// \n    /// If the function returns false for any proposed new state, then the `swap` \n    /// function will return `false`, else it will return `true` on successful setting \n    /// of the atom's state\n    /// </param>\n    /// <returns>The constructed Atom or None if the validation faled for the initial \n    /// `value` </returns>\n    /// <remarks>\n    /// The intended use of atom is to hold one an immutable data structure. You change \n    /// the value by applying a function to the old value. This is done in an atomic \n    /// manner by `Swap`.  \n    /// \n    /// Internally, `Swap` reads the current value, applies the function to it, and \n    /// attempts to `CompareExchange` it in. Since another thread may have changed the \n    /// value in the intervening time, it may have to retry, and does so in a spin loop. \n    /// \n    /// The net effect is that the value will always be the result of the application \n    /// of the supplied function to a current value, atomically. However, because the \n    /// function might be called multiple times, it must be free of side effects.\n    /// \n    /// Atoms are an efficient way to represent some state that will never need to be \n    /// coordinated with any other, and for which you wish to make synchronous changes.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<Atom<A>> Atom<A>(A value, Func<A, bool> validator) =>\n        LanguageExt.Atom<A>.New(value, validator);\n\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks. \n    /// </summary>\n    /// <param name=\"metadata\">Metadata to be passed to the validation function</param>\n    /// <param name=\"value\">Initial value of the atom</param>\n    /// <returns>The constructed Atom</returns>\n    /// <remarks>\n    /// The intended use of atom is to hold one an immutable data structure. You change \n    /// the value by applying a function to the old value. This is done in an atomic \n    /// manner by `Swap`.  \n    /// \n    /// Internally, `Swap` reads the current value, applies the function to it, and \n    /// attempts to `CompareExchange` it in. Since another thread may have changed the \n    /// value in the intervening time, it may have to retry, and does so in a spin loop. \n    /// \n    /// The net effect is that the value will always be the result of the application \n    /// of the supplied function to a current value, atomically. However, because the \n    /// function might be called multiple times, it must be free of side effects.\n    /// \n    /// Atoms are an efficient way to represent some state that will never need to be \n    /// coordinated with any other, and for which you wish to make synchronous changes.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Atom<M, A> Atom<M, A>(M metadata, A value) =>\n        LanguageExt.Atom<M, A>.New(metadata, value);\n\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks. \n    /// </summary>\n    /// <param name=\"metadata\">Metadata to be passed to the validation function</param>\n    /// <param name=\"value\">Initial value of the atom</param>\n    /// <param name=\"validator\">Function to run on the value after each state change.  \n    /// \n    /// If the function returns false for any proposed new state, then the `swap` \n    /// function will return `false`, else it will return `true` on successful setting \n    /// of the atom's state\n    /// </param>\n    /// <returns>The constructed Atom or None if the validation faled for the initial \n    /// `value` </returns>\n    /// <remarks>\n    /// The intended use of atom is to hold one an immutable data structure. You change \n    /// the value by applying a function to the old value. This is done in an atomic \n    /// manner by `Swap`.  \n    /// \n    /// Internally, `Swap` reads the current value, applies the function to it, and \n    /// attempts to `CompareExchange` it in. Since another thread may have changed the \n    /// value in the intervening time, it may have to retry, and does so in a spin loop. \n    /// \n    /// The net effect is that the value will always be the result of the application \n    /// of the supplied function to a current value, atomically. However, because the \n    /// function might be called multiple times, it must be free of side effects.\n    /// \n    /// Atoms are an efficient way to represent some state that will never need to be \n    /// coordinated with any other, and for which you wish to make synchronous changes.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<Atom<M, A>> Atom<M, A>(M metadata, A value, Func<A, bool> validator) =>\n        LanguageExt.Atom<M, A>.New(metadata, value, validator);\n\n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// If the swap operation fails (which can only happen due to its validator returning false),\n    /// then a snapshot of the current value within the Atom is returned.\n    /// If there is no validator for the Atom then the return value is always the snapshot of\n    /// the successful `f` function. \n    /// </returns>\n    public static A swap<A>(Atom<A> ma, Func<A, A> f) =>\n        ma.Swap(f);\n    \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// * If `f` returns `None` then no update occurs and the result of the call\n    ///   to `Swap` will be the latest (unchanged) value of `A`.\n    /// * If the swap operation fails, due to its validator returning false, then a snapshot of\n    ///   the current value within the Atom is returned.\n    /// * If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// * If there is no validator for the Atom then the return value is always the snapshot of\n    ///   the successful `f` function. \n    /// </returns>\n    public static A swap<A>(Atom<A> ma, Func<A, Option<A>> f) =>\n        ma.SwapMaybe(f);\n    \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// If the swap operation fails (which can only happen due to its validator returning false),\n    /// then a snapshot of the current value within the Atom is returned.\n    /// If there is no validator for the Atom then the return value is always the snapshot of\n    /// the successful `f` function. \n    /// </returns>\n    public static A swap<M, A>(Atom<M, A> ma, Func<M, A, A> f) =>\n        ma.Swap(f);\n    \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// * If `f` returns `None` then no update occurs and the result of the call\n    ///   to `Swap` will be the latest (unchanged) value of `A`.\n    /// * If the swap operation fails, due to its validator returning false, then a snapshot of\n    ///   the current value within the Atom is returned.\n    /// * If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// * If there is no validator for the Atom then the return value is always the snapshot of\n    ///   the successful `f` function. \n    /// </returns>\n    public static A swap<M, A>(Atom<M, A> ma, Func<M, A, Option<A>> f) =>\n        ma.Swap(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/README.md",
    "content": "We prefer to work with immutable types in functional-programming.  However, it's not always possible, and sometimes we\nneed some shared mutable state.  With the immutable types in this library you'd need to protect the updates with locks:\n\n    // Some global\n    HashSet<int> set = HashSet(1, 2, 3);\n    object sync = new();\n\n    lock(sync)\n    {\n        set = set.Add(4);\n    }\n\nThis in unsatisfactory, and so this module is all about lock-free atomic operations.  `Atom` allows you to protect any\nvalue.  `AtomHashMap` and `AtomSeq` are `HashMap` and `Seq` wrapped up into a lock-free mutable structure.  Snapshots\nof those are free!  The above code can be written:\n\n    AtomHashSet<int> set = AtomHashSet(1, 2, 3);\n    set.Add(4);\n\nFinally, there's the Software Transactional Memory (STM) system.  Which allows for transactional changes to multiple \n`Ref` values.  `Ref` just wrap up access to a value, and allows the state changes to be tracked by the `STM`.\n\n See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/STM/CommuteRef.cs",
    "content": "﻿using System;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A proxy for `Ref`, returned by `commute`.  This allows the transaction system to know that the\n/// result is a commutative and therefore give you a result based on the live state rather than\n/// the transaction.  \n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic readonly struct CommuteRef<A>\n{\n    internal CommuteRef(Ref<A> r) => Ref = r;\n    internal readonly Ref<A> Ref;\n    public A Value\n    {\n        get => Ref.Value;\n        set => Ref.Value = value;\n    }\n    public static implicit operator A(CommuteRef<A> r) => r.Value;\n    public override string ToString() => Value?.ToString()    ?? \"[null]\";\n    public override int GetHashCode() => Value?.GetHashCode() ?? 0;\n    public override bool Equals(object? obj) => obj is A val && Equals(val);\n    public bool Equals(A other) => EqDefault<A>.Equals(other, Value);\n    public A Swap(Func<A, A> f) => Ref.Swap(f);\n    public IO<A> SwapIO(Func<A, A> f) => Ref.SwapIO(f);\n    public CommuteRef<A> Commute(Func<A, A> f) => Ref.Commute(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/STM/Isolation.cs",
    "content": "﻿namespace LanguageExt;\n\n/// <summary>\n/// `sync` transaction isolation level.  Used to enforce ACI properties\n/// of ACID on `Ref`s.\n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic enum Isolation\n{\n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside of the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    Snapshot,\n\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside of the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does write to the values that are used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the most strict form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would not cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    Serialisable\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/STM/Ref.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Refs ensure safe shared use of mutable storage locations via a software transactional \n/// memory (STM) system. Refs are bound to a single storage location for their lifetime, and \n/// only allow mutation of that location to occur within a transaction.\n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic sealed class Ref<A> : IEquatable<A>\n{\n    internal readonly long Id;\n    public event AtomChangedEvent<A>? Change; \n\n    /// <summary>\n    /// Internal ctor\n    /// </summary>\n    internal Ref(long id) =>\n        Id = id;\n\n    /// <summary>\n    /// Destructor\n    /// </summary>\n    ~Ref() => STM.Finalise(Id);\n\n    /// <summary>\n    /// Change handler\n    /// </summary>\n    internal void OnChange(A value) =>\n        Change?.Invoke(value);\n\n    /// <summary>\n    /// Value accessor (read and write)\n    /// </summary>\n    public A Value\n    {\n        get => (A)STM.Read(Id);\n        set => STM.Write(Id, value!);\n    }\n\n    /// <summary>\n    /// Value accessor (read and write)\n    /// </summary>\n    /// <remarks>\n    /// \n    /// * Gets will return a freshly constructed `IO` monad that can be repeatedly\n    /// evaluated to get the latest state of the `Ref`.\n    /// \n    /// * Sets pass an `IO` monad that will be mapped to an operation that will set\n    /// the value of the `Ref` each time it's evaluated.\n    /// \n    /// </remarks>\n    public IO<A> ValueIO\n    {\n        get => IO.lift(_ => (A)STM.Read(Id));\n        set => value.Map(v =>\n                         {\n                             STM.Write(Id, v!);\n                             return unit;\n                         });\n    }\n\n    /// <summary>\n    /// Implicit conversion operator\n    /// </summary>\n    /// <param name=\"value\"></param>\n    public static implicit operator A(Ref<A> value) =>\n        value.Value;\n\n    /// <summary>\n    /// ToString for the bound value\n    /// </summary>\n    public override string ToString() =>\n        Value?.ToString() ?? \"[null]\";\n\n    /// <summary>\n    /// Hash code of the bound value\n    /// </summary>\n    public override int GetHashCode() =>\n        Value?.GetHashCode() ?? 0;\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    public override bool Equals(object? obj) =>\n        obj is A val && Equals(val);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    public bool Equals(A? other) =>\n        EqDefault<A?>.Equals(other, Value);\n\n    /// <summary>\n    /// Swap the old value for the new returned by `f`\n    /// Must be run within a `sync` transaction\n    /// </summary>\n    /// <param name=\"f\">Swap function</param>\n    /// <returns>The value returned from `f`</returns>\n    public A Swap(Func<A, A> f)\n    {\n        var v = f(Value);\n        Value = v;\n        return v;\n    }\n\n    /// <summary>\n    /// Swap the old value for the new returned by `f`\n    /// Must be run within a `sync` transaction\n    /// </summary>\n    /// <param name=\"f\">Swap function</param>\n    /// <returns>The value returned from `f`</returns>\n    public IO<A> SwapIO(Func<A, A> f) =>\n        IO.lift(_ =>\n        {\n            var fv = f(Value);\n            Value = fv;\n            return fv;\n        });\n\n    /// <summary>\n    /// Must be called in a transaction. Sets the in-transaction-value of\n    /// ref to:  \n    /// \n    ///     `f(in-transaction-value-of-ref)`\n    ///     \n    /// and returns the in-transaction-value when complete.\n    /// \n    /// At the commit point of the transaction, `f` is run *AGAIN* with the\n    /// most recently committed value:\n    /// \n    ///     `f(most-recently-committed-value-of-ref)`\n    /// \n    /// Thus `f` should be commutative, or, failing that, you must accept\n    /// last-one-in-wins behavior.\n    /// \n    /// Commute allows for more concurrency than just setting the Ref's value\n    /// </summary>\n    public CommuteRef<A> Commute(Func<A, A> f)\n    {\n        STM.Commute(Id, f);\n        return new CommuteRef<A>(this);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/STM/STM.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n// ReSharper disable MemberHidesStaticFromOuterClass\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Software transactional memory using Multi-Version Concurrency Control (MVCC)\n/// </summary>\n/// <remarks>\n/// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n/// </remarks>\npublic static class STM\n{\n    static long refIdNext;\n    static readonly AtomHashMap<EqLong, long, RefState> state;\n    static readonly AsyncLocal<Transaction?> transaction;\n\n    static STM()\n    {\n        state       = AtomHashMap<EqLong, long, RefState>();\n        transaction = new AsyncLocal<Transaction?>();\n    }\n\n    static void OnChange(TrieMap<EqLong, long, Change<RefState>> patch) \n    {\n        foreach (var change in patch)\n        {\n            if (change.Value is EntryMappedTo<RefState> update)\n            {\n                update.To.OnChange(update.To.UntypedValue);\n            }\n        }\n    }\n\n    /// <summary>\n    /// Generates a new reference that can be used within a sync transaction\n    /// </summary>\n    internal static Ref<A> NewRef<A>(A value, Func<A, bool>? validator = null)\n    {\n        var id = Interlocked.Increment(ref refIdNext);\n        var r = new Ref<A>(id);\n        var v = new RefState<A>(0, value, validator, r);\n        state.Add(id, v);\n        return r;\n    }\n        \n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    internal static R DoTransaction<R>(Func<R> op, Isolation isolation) =>\n        transaction.Value == null\n            ? RunTransaction(op, isolation)\n            : op();\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    internal static ValueTask<R> DoTransaction<R>(Func<ValueTask<R>> op, Isolation isolation) =>\n        transaction.Value == null\n            ? RunTransaction(op, isolation)\n            : op();\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    internal static Eff<R> DoTransaction<R>(Eff<R> op, Isolation isolation) =>\n        transaction.Value == null\n            ? RunTransaction(op, isolation)\n            : op;\n        \n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    internal static Eff<RT, R> DoTransaction<RT, R>(Eff<RT, R> op, Isolation isolation) =>\n        transaction.Value == null\n            ? RunTransaction(op, isolation)\n            : op;\n        \n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    internal static R DoTransaction<R>(Func<CommuteRef<R>> op, Isolation isolation) =>\n        transaction.Value == null\n            ? RunTransaction(op, isolation)\n            : op().Value;\n\n    /// <summary>\n    /// Runs the transaction\n    /// </summary>\n    static R RunTransaction<R>(Func<R> op, Isolation isolation)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            // Create a new transaction with a snapshot of the current state\n            var t = new Transaction(state.Items);\n            transaction.Value = t;\n            try\n            {\n                // Try to do the operations of the transaction\n                return ValidateAndCommit(t, isolation, op(), long.MinValue);\n            }\n            catch (ConflictException)\n            {\n                // Conflict found, so retry\n            }\n            finally\n            {\n                // Clear the current transaction on the way out\n                transaction.Value = null!;\n                    \n                // Announce changes\n                OnChange(t.changes);\n            }\n            // Wait one tick before trying again\n            sw.SpinOnce();\n        }\n    }\n\n    /// <summary>\n    /// Runs the transaction\n    /// </summary>\n    static Eff<RT, R> RunTransaction<RT, R>(Eff<RT, R> op, Isolation isolation) =>\n        getState<RT>().Bind(\n            sta =>\n                Eff<RT, R>.Lift(\n                    env =>\n                    {\n                        SpinWait sw = default;\n                        while (true)\n                        {\n                            // Create a new transaction with a snapshot of the current state\n                            var t = new Transaction(state.Items);\n                            transaction.Value = t;\n                            try\n                            {\n                                // Try to do the operations of the transaction\n                                var res = op.Run(env, sta.EnvIO);\n                                return res.IsFail\n                                           ? res\n                                           : ValidateAndCommit(t, isolation, res.SuccValue, Int64.MinValue);\n                            }\n                            catch (ConflictException)\n                            {\n                                // Conflict found, so retry\n                            }\n                            finally\n                            {\n                                // Clear the current transaction on the way out\n                                transaction.Value = null;\n\n                                // Announce changes\n                                OnChange(t.changes);\n                            }\n\n                            // Wait one tick before trying again\n                            sw.SpinOnce();\n                        }\n                    }));\n\n    /// <summary>\n    /// Runs the transaction\n    /// </summary>\n    static Eff<R> RunTransaction<R>(Eff<R> op, Isolation isolation) =>\n        lift(() =>\n        {\n            SpinWait sw = default;\n            while (true)\n            {\n                // Create a new transaction with a snapshot of the current state\n                var t = new Transaction(state.Items);\n                transaction.Value = t;\n                try\n                {\n                    // Try to do the operations of the transaction\n                    var res = op.Run();\n                    return res.IsFail \n                               ? res \n                               : ValidateAndCommit(t, isolation, res.SuccValue, Int64.MinValue);\n                }\n                catch (ConflictException)\n                {\n                    // Conflict found, so retry\n                }\n                finally\n                {\n                    // Clear the current transaction on the way out\n                    transaction.Value = null;\n                    \n                    // Announce changes\n                    OnChange(t.changes);\n                }\n\n                // Wait one tick before trying again\n                sw.SpinOnce();\n            }\n        });\n        \n    /// <summary>\n    /// Runs the transaction\n    /// </summary>\n    static async ValueTask<R> RunTransaction<R>(Func<ValueTask<R>> op, Isolation isolation)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            // Create a new transaction with a snapshot of the current state\n            var t = new Transaction(state.Items);\n            transaction.Value = t;\n            try\n            {\n                // Try to do the operations of the transaction\n                return ValidateAndCommit(t, isolation, await op().ConfigureAwait(false), long.MinValue);\n            }\n            catch (ConflictException)\n            {\n                // Conflict found, so retry\n            }\n            finally\n            {\n                // Clear the current transaction on the way out\n                transaction.Value = Transaction.None;\n                    \n                // Announce changes\n                OnChange(t.changes);\n            }\n            // Wait one tick before trying again\n            sw.SpinOnce();\n        }\n    }\n\n    /// <summary>\n    /// Runs the transaction\n    /// </summary>\n    static R RunTransaction<R>(Func<CommuteRef<R>> op, Isolation isolation)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            // Create a new transaction with a snapshot of the current state\n            var t = new Transaction(state.Items);\n            transaction.Value = t;\n            try\n            {\n                var cref = op();\n\n                // Try to do the operations of the transaction\n                return ValidateAndCommit(t, isolation, (R)t.state[cref.Ref.Id].UntypedValue, cref.Ref.Id);\n            }\n            catch (ConflictException)\n            {\n                // Conflict found, so retry\n            }\n            finally\n            {\n                // Clear the current transaction on the way out\n                transaction.Value = Transaction.None;\n                    \n                // Announce changes\n                OnChange(t.changes);\n            }\n            // Spin, backing off, then yield the thread to avoid deadlock \n            sw.SpinOnce();\n        }\n    }\n\n    static R ValidateAndCommit<R>(Transaction t, Isolation isolation, R result, long returnRefId)\n    {\n        // No writing, so no validation or commit needed\n        var writes = t.writes.Count;\n        var commutes = t.commutes.Count;\n\n        var anyWrites = writes     > 0;\n        var anyCommutes = commutes > 0;\n            \n        if (!anyWrites && !anyCommutes)\n        {\n            return result;\n        }\n\n        // Attempt to apply the changes atomically\n        state.SwapInternal(s =>\n        {\n            if (isolation == Isolation.Serialisable)\n            {\n                ValidateReads(t, s);\n            }\n\n            s = anyWrites\n                    ? CommitWrites(t, s)\n                    : s;\n            (s, result) = anyCommutes ? CommitCommutes(t, s, returnRefId, result) : (s, result);\n            return s;\n        });\n\n        // Changes applied successfully\n        return result;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static void ValidateReads(Transaction t, TrieMap<EqLong, long, RefState> s)\n    {\n        var tlocal = t;\n        var slocal = tlocal.state;\n \n        // Check if something else wrote to what we were reading\n        foreach (var read in tlocal.reads)\n        {\n            if (s[read].Version != slocal[read].Version)\n            {\n                throw new ConflictException();\n            }\n        }\n    }\n\n    static TrieMap<EqLong, long, RefState> CommitWrites(Transaction t, TrieMap<EqLong, long, RefState> s)\n    {\n        // Check if something else wrote to what we were writing\n        var tlocal = t;\n        var slocal = tlocal.state;\n            \n        foreach (var write in tlocal.writes)\n        {\n            var newState = slocal[write];\n\n            if (!newState.Validate(newState))\n            {\n                throw new RefValidationFailedException();\n            }\n\n            if (s[write].Version == newState.Version)\n            {\n                s = s.SetItem(write, newState.Inc());\n            }\n            else\n            {\n                throw new ConflictException();\n            }\n        }\n\n        return s;\n    }\n\n    static (TrieMap<EqLong, long, RefState>, R) CommitCommutes<R>(Transaction t, TrieMap<EqLong, long, RefState> s, long returnRefId, R result)\n    {\n        // Run the commutative operations\n        foreach (var commute in t.commutes)\n        {\n            var exist = s[commute.Id];\n\n            // Re-run the commute function with what's live now\n            var nver = exist.MapAndInc(commute.Fun);\n\n            // Validate the result\n            if (!nver.Validate(nver))\n            {\n                throw new RefValidationFailedException();\n            }\n\n            // Save to live state\n            s = s.SetItem(commute.Id, nver);\n\n            // If it matches our return type, then make it the result\n            if (returnRefId == commute.Id)\n            {\n                result = (R)nver.UntypedValue;\n            }\n        }\n\n        return (s, result);\n    }\n\n    /// <summary>\n    /// Read the value for the reference ID provided\n    /// If within a transaction then the in-transaction value is returned, otherwise it's\n    /// the current latest value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static object Read(long id) =>\n        transaction.Value == null\n            ? state.Items[id].UntypedValue\n            : transaction.Value.ReadValue(id);\n\n    /// <summary>\n    /// Write the value for the reference ID provided\n    /// Must be run within a transaction\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static void Write(long id, object value)\n    {\n        if (transaction.Value == null)\n        {\n            throw new InvalidOperationException(\"Refs can only be written to from within a `sync` transaction\");\n        }\n        transaction.Value.WriteValue(id, value);\n    }\n\n    /// <summary>\n    /// Must be called in a transaction. Sets the in-transaction-value of\n    /// ref to:  \n    /// \n    ///     `f(in-transaction-value-of-ref)`\n    ///     \n    /// and returns the in-transaction-value when complete.\n    /// \n    /// At the commit point of the transaction, `f` is run *AGAIN* with the\n    /// most recently committed value:\n    /// \n    ///     `f(most-recently-committed-value-of-ref)`\n    /// \n    /// Thus `f` should be commutative, or, failing that, you must accept\n    /// last-one-in-wins behavior.\n    /// \n    /// Commute allows for more concurrency than just setting the items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static A Commute<A>(long id, Func<A, A> f)\n    {\n        if (transaction.Value == null)\n        {\n            throw new InvalidOperationException(\"Refs can only commute from within a transaction\");\n        }\n        return (A)transaction.Value.Commute(id, CastCommute(f));\n    }\n\n    /// <summary>\n    /// Must be called in a transaction. Sets the in-transaction-value of\n    /// ref to:  \n    /// \n    ///     `f(in-transaction-value-of-ref)`\n    ///     \n    /// and returns the in-transaction-value when complete.\n    /// \n    /// At the commit point of the transaction, `f` is run *AGAIN* with the\n    /// most recently committed value:\n    /// \n    ///     `f(most-recently-committed-value-of-ref)`\n    /// \n    /// Thus `f` should be commutative, or, failing that, you must accept\n    /// last-one-in-wins behavior.\n    /// \n    /// Commute allows for more concurrency than just setting the items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static A Commute<X, A>(long id, X x, Func<X, A, A> f) =>\n        Commute<A>(id, (a => f(x, a)));\n\n    /// <summary>\n    /// Must be called in a transaction. Sets the in-transaction-value of\n    /// ref to:  \n    /// \n    ///     `f(in-transaction-value-of-ref)`\n    ///     \n    /// and returns the in-transaction-value when complete.\n    /// \n    /// At the commit point of the transaction, `f` is run *AGAIN* with the\n    /// most recently committed value:\n    /// \n    ///     `f(most-recently-committed-value-of-ref)`\n    /// \n    /// Thus `f` should be commutative, or, failing that, you must accept\n    /// last-one-in-wins behavior.\n    /// \n    /// Commute allows for more concurrency than just setting the items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static A Commute<X, Y, A>(long id, X x, Y y, Func<X, Y, A, A> f) =>\n        Commute<A>(id, (a => f(x, y, a)));\n\n    /// <summary>\n    /// Make sure Refs are cleaned up\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static void Finalise(long id) =>\n        state.Remove(id);\n\n    /// <summary>\n    /// Conflict exception for internal use\n    /// </summary>\n    class ConflictException : Exception;\n\n    /// <summary>\n    /// Wraps a (A -> A) predicate as (object -> object)\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static Func<object, object> CastCommute<A>(Func<A, A> f) =>\n        obj => f((A)obj)!;\n\n    /// <summary>\n    /// Get the currently running TransactionId\n    /// </summary>\n    public static long TransactionId\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => transaction.Value?.transactionId ?? throw new InvalidOperationException(\"Transaction not running\");\n    }\n\n    /// <summary>\n    /// Transaction snapshot\n    /// </summary>\n    class Transaction\n    {\n        static long transactionIdNext;\n        public readonly long transactionId;\n        public TrieMap<EqLong, long, RefState> state;\n        public TrieMap<EqLong, long, Change<RefState>> changes;\n        public readonly System.Collections.Generic.HashSet<long> reads = new();\n        public readonly System.Collections.Generic.HashSet<long> writes = new();\n        public readonly System.Collections.Generic.List<(long Id, Func<object, object> Fun)> commutes = new();\n\n        public static readonly Transaction None = new (TrieMap<EqLong, long, RefState>.Empty);\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Transaction(TrieMap<EqLong, long, RefState> state)\n        {\n            this.state    = state;\n            changes       = TrieMap<EqLong, long, Change<RefState>>.EmptyForMutating;\n            transactionId = Interlocked.Increment(ref transactionIdNext);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public object ReadValue(long id)\n        {\n            reads.Add(id);\n            return state[id].UntypedValue;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public void WriteValue(long id, object value)\n        {\n            var oldState = state[id];\n            var newState = oldState.SetValue(value);\n            state = state.SetItem(id, newState);\n            writes.Add(id);\n            var change = changes.Find(id);\n            if (change.IsSome)\n            {\n                var last = (EntryMapped<RefState, RefState>)change.Value!;\n                changes = changes.AddOrUpdateInPlace(id, Change<RefState>.Mapped(last.From, newState));\n            }\n            else\n            {\n                changes = changes.AddOrUpdateInPlace(id, Change<RefState>.Mapped(oldState, newState));\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public object Commute(long id, Func<object, object> f)\n        {\n            var oldState = state[id];\n            var newState = oldState.Map(f);\n            state = state.SetItem(id, newState);\n            commutes.Add((id, f));\n            return newState.UntypedValue;\n        }\n    }\n\n    /// <summary>\n    /// The state of a Ref\n    /// Includes the value and the version\n    /// </summary>\n    abstract record RefState(long Version)\n    {\n        public abstract bool Validate(RefState refState);\n        public abstract RefState SetValue(object value);\n        public abstract RefState SetValueAndInc(object value);\n        public abstract RefState Inc();\n        public abstract RefState Map(Func<object, object> f);\n        public abstract RefState MapAndInc(Func<object, object> f);\n        public abstract void OnChange(object value);\n        public abstract object UntypedValue { get; }\n    }\n\n    record RefState<A>(long Version, A Value, Func<A, bool>? Validator, Ref<A> Ref) : RefState(Version)\n    {\n        public override bool Validate(RefState refState) =>\n            Validator?.Invoke(((RefState<A>)refState).Value) ?? true;\n\n        public override RefState SetValue(object value) =>\n            this with {Value = (A)value};\n\n        public override RefState SetValueAndInc(object value) =>\n            this with {Version = Version + 1,Value = (A)value};\n\n        public override RefState Inc() =>\n            this with {Version = Version + 1};\n\n        public override RefState Map(Func<object, object> f) =>\n            this with {Value = (A)f(Value!)};\n\n        public override RefState MapAndInc(Func<object, object> f) =>\n            this with {Version = Version + 1, Value = (A)f(Value!)};\n\n        public override void OnChange(object value) =>\n            Ref.OnChange((A)value);\n            \n        public override object UntypedValue =>\n            Value!;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Signals/CountdownSignal.cs",
    "content": "using System;\nusing System.Threading;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// IO signalling, usually used to signal for cross-thread synchronisation.\n/// </summary>\npublic class CountdownSignal<M>(CountdownEvent handle) : IDisposable\n    where M : Monad<M>\n{\n    /// <summary>\n    /// The initial value of the counter\n    /// </summary>\n    public int Initial =>\n        handle.InitialCount;\n    \n    /// <summary>\n    /// The current value of the counter\n    /// </summary>\n    public K<M, int> Count =>\n        M.LiftIOMaybe(IO.lift(() => handle.CurrentCount));\n\n    /// <summary>\n    /// True if the counter has complete its countdown\n    /// </summary>\n    public K<M, bool> Complete =>\n        M.LiftIOMaybe(IO.lift(() => handle.IsSet));\n\n    /// <summary>\n    /// Triggers a single countdown of the counter in the signal\n    /// </summary>\n    /// <returns>True if the counter reached zero.</returns>\n    public K<M, bool> Trigger() =>\n        M.LiftIOMaybe(IO.lift(handle.Signal));\n\n    /// <summary>\n    /// Triggers a single countdown of the counter in the signal\n    /// </summary>\n    /// <returns>True if the counter reached zero.</returns>\n    public bool TriggerUnsafe() =>\n        handle.Signal();\n\n    /// <summary>\n    /// Triggers `n` signals to the counter in the signal\n    /// </summary>\n    /// <remarks>\n    /// This is marked unsafe because it's not in an `IO` operation and therefore is impure.\n    /// </remarks>\n    /// <returns>True if the counter reached zero.</returns>\n    public K<M, bool> Trigger(int count) =>\n        M.LiftIOMaybe(IO.lift(handle.Signal));\n\n    /// <summary>\n    /// Triggers `n` signals to the counter in the signal\n    /// </summary>\n    /// <remarks>\n    /// This is marked unsafe because it's not in an `IO` operation and therefore is impure.\n    /// </remarks>\n    /// <returns>True if the counter reached zero.</returns>\n    public bool TriggerUnsafe(int count) =>\n        handle.Signal();\n\n    /// <summary>\n    /// Wait for signal to signal\n    /// </summary>\n    /// <returns>Monad `M` with the `Wait` operation lifted into it via `liftIO`</returns>\n    public K<M, Unit> Wait() =>\n        M.LiftIOMaybe(IO.lift(e =>\n                         {\n                             handle.Wait(e.Token);\n                             return unit;\n                         }));\n\n    public void Dispose() => \n        handle.Dispose();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Signals/Signal.Module.cs",
    "content": "using System.Threading;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// IO signalling constructors\n/// </summary>\npublic static class Signal\n{\n    /// <summary>Represents a thread synchronisation event that, when signaled, resets automatically after releasing a\n    /// single waiting thread.</summary>\n    /// <remarks>\n    /// The internal `EventWaitHandle` is wrapped with a `use` operator so that its handle is tracked by the `IO`\n    /// resource-management system and auto-cleaned up if not done manually with `release` or using `bracket`.\n    /// </remarks>\n    /// <param name=\"signaled\">\n    /// <see langword=\"true\" /> to set the initial state to signaled;\n    /// <see langword=\"false\" /> to set the initial state to non-signaled.\n    /// </param>\n    public static K<M, Signal<M>> autoReset<M>(bool signaled = false)\n        where M : Monad<M> =>\n        M.LiftIOMaybe(use(() => new Signal<M>(new AutoResetEvent(false))));\n\n    /// <summary>Represents a thread synchronisation event that, when signaled, must be reset manually. </summary>\n    /// <remarks>\n    /// The internal `EventWaitHandle` is wrapped with a `use` operator so that its handle is tracked by the `IO`\n    /// resource-management system and auto-cleaned up if not done manually with `release` or using `bracket`.\n    /// </remarks>\n    /// <param name=\"signaled\">\n    /// <see langword=\"true\" /> to set the initial state signaled;\n    /// <see langword=\"false\" /> to set the initial state to non-signaled.\n    /// </param>\n    public static K<M, Signal<M>> manualReset<M>(bool signaled = false) \n        where M : Monad<M> =>\n        M.LiftIOMaybe(use(() => new Signal<M>(new ManualResetEvent(false))));\n\n    /// <summary>Represents a synchronisation primitive that is signaled when its count reaches zero.</summary>\n    /// <remarks>\n    /// The internal `EventWaitHandle` is wrapped with a `use` operator so that its handle is tracked by the `IO`\n    /// resource-management system and auto-cleaned up if not done manually with `release` or using `bracket`.\n    /// </remarks>\n    public static K<M, CountdownSignal<M>> countdown<M>(int count) \n        where M : Monad<M> =>\n        M.LiftIOMaybe(use(() => new CountdownSignal<M>(new CountdownEvent(count))));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Signals/Signal.cs",
    "content": "using System;\nusing System.Threading;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// IO signalling, usually used to signal for cross-thread synchronisation.\n/// </summary>\npublic class Signal<M>(EventWaitHandle handle) : IDisposable\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Set the signal\n    /// </summary>\n    /// <returns>\n    /// True if the operation succeeds\n    /// </returns>\n    public K<M, bool> Trigger() =>\n        M.LiftIOMaybe(IO.lift(_ => handle.Set()));\n    \n    /// <summary>\n    /// Set the signal\n    /// </summary>\n    /// <remarks>\n    /// This is marked unsafe because it's not in an `IO` operation and therefore is impure.\n    /// </remarks>\n    /// <returns>\n    /// True if the operation succeeds\n    /// </returns>\n    public bool TriggerUnsafe() =>\n        handle.Set();\n    \n    /// <summary>\n    /// Wait for signal to signal\n    /// </summary>\n    /// <returns></returns>\n    public K<M, bool> Wait() =>\n        M.LiftIOMaybe(IO.liftAsync(e => handle.WaitOneAsync(e.Token)));\n    \n    /// <summary>\n    /// Wait for signal to signal\n    /// </summary>\n    /// <returns></returns>\n    public K<M, bool> Wait(TimeSpan timeout) =>\n        M.LiftIOMaybe(IO.liftAsync(e => handle.WaitOneAsync(timeout, e.Token)));\n    \n    /// <summary>\n    /// Wait for signal to signal\n    /// </summary>\n    /// <returns></returns>\n    public K<M, bool> Wait(int timeoutMilliseconds) =>\n        M.LiftIOMaybe(IO.liftAsync(e => handle.WaitOneAsync(timeoutMilliseconds, e.Token)));\n    \n    public void Dispose() => \n        handle.Dispose();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Task/Task.Extensions.cs",
    "content": "﻿using LanguageExt.ClassInstances;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class TaskExtensions\n{\n    public static bool CompletedSuccessfully<A>(this Task<A> ma) =>\n        ma is { IsCompleted: true, IsFaulted: false, IsCanceled: false };\n\n    [Pure]\n    public static Task<A> AsFailedTask<A>(this Exception ex)\n    {\n        var tcs = new TaskCompletionSource<A>();\n        tcs.SetException(ex);\n        return tcs.Task;\n    }\n\n    /// <summary>\n    /// Convert a value to a Task that completes immediately\n    /// </summary>\n    [Pure]\n    public static Task<A> AsTask<A>(this A self) =>\n        Task.FromResult(self);\n\n    /// <summary>\n    /// Convert a ValueTask to a Task \n    /// </summary>\n    [Pure]\n    public static Task<A> ToRef<A>(this ValueTask<A> self) =>\n        self.AsTask();\n        \n    /// <summary>\n    /// Flatten the nested Task type\n    /// </summary>\n    [Pure]\n    public static async Task<A> Flatten<A>(this Task<Task<A>> self)\n    {\n        var t = await self.ConfigureAwait(false);\n        var u = await t.ConfigureAwait(false);\n        return u;\n    }\n\n    /// <summary>\n    /// Flatten the nested Task type\n    /// </summary>\n    [Pure]\n    public static async Task<A> Flatten<A>(this Task<Task<Task<A>>> self)\n    {\n        var t = await self.ConfigureAwait(false);\n        var u = await t.ConfigureAwait(false);\n        var v = await u.ConfigureAwait(false);\n        return v;\n    }\n\n    /// <summary>\n    /// Standard LINQ Select implementation for Task\n    /// </summary>\n    [Pure]\n    public static async Task<U> Select<T, U>(this Task<T> self, Func<T, U> map) =>\n        map(await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Standard LINQ Where implementation for Task\n    /// </summary>\n    [Pure]\n    public static async Task<T> Where<T>(this Task<T> self, Func<T, bool> pred)\n    {\n        var resT = await self.ConfigureAwait(false);\n        var res = pred(resT);\n        if (!res)\n        {\n            throw new OperationCanceledException();\n        }\n\n        return resT;\n    }\n\n    /// <summary>\n    /// Standard LINQ SelectMany implementation for Task\n    /// </summary>\n    [Pure]\n    public async static Task<U> SelectMany<T, U>(this Task<T> self,\n        Func<T, Task<U>> bind) =>\n        await bind(await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    /// <summary>\n    /// Standard LINQ SelectMany implementation for Task\n    /// </summary>\n    [Pure]\n    public static async Task<V> SelectMany<T, U, V>(this Task<T> self,\n        Func<T, Task<U>> bind,\n        Func<T, U, V> project)\n    {\n        var resT = await self.ConfigureAwait(false);\n        var resU = await bind(resT).ConfigureAwait(false);\n        return project(resT, resU);\n    }\n\n    /// <summary>\n    /// Get the Count of a Task T.  Returns either 1 or 0 if cancelled or faulted.\n    /// </summary>\n    [Pure]\n    public static async Task<int> Count<T>(this Task<T> self)\n    {\n        try\n        {\n            await self.ConfigureAwait(false);\n            return 1;\n        }\n        catch (Exception)\n        {\n            return 0;\n        }\n    }\n\n    /// <summary>\n    /// Monadic bind operation for Task\n    /// </summary>\n    [Pure]\n    public static Task<U> Bind<T, U>(this Task<T> self, Func<T, Task<U>> bind) =>\n        self.SelectMany(bind);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static async Task<bool> Exists<T>(this Task<T> self, Func<T, bool> pred) =>\n        pred(await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static async Task<bool> ExistsAsync<T>(this Task<T> self, Func<T, Task<bool>> pred) =>\n        await pred(await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static async Task<bool> ForAll<T>(this Task<T> self, Func<T, bool> pred) =>\n        pred(await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static async Task<bool> ForAllAsync<T>(this Task<T> self, Func<T, Task<bool>> pred) =>\n        await pred(await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    /// <summary>\n    /// Filters the task.  This throws a BottomException when pred(Result)\n    /// returns false\n    /// </summary>\n    [Pure]\n    public static Task<T> Filter<T>(this Task<T> self, Func<T, bool> pred) =>\n        self.Where(pred);\n\n    /// <summary>\n    /// Folds the Task.  Returns folder(state,Result) if not faulted or\n    /// cancelled.  Returns state otherwise.\n    /// </summary>\n    [Pure]\n    public static async Task<S> Fold<T, S>(this Task<T> self, S state, Func<S, T, S> folder) =>\n        folder(state, await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Folds the Task.  Returns folder(state,Result) if not faulted or\n    /// cancelled.  Returns state otherwise.\n    /// </summary>\n    [Pure]\n    public static async Task<S> FoldAsync<T, S>(this Task<T> self, S state, Func<S, T, Task<S>> folder) =>\n        await folder(state, await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    /// <summary>\n    /// Iterates the Task.  Invokes f(Result) if not faulted or cancelled\n    /// </summary>\n    public static async Task<Unit> Iter<T>(this Task<T> self, Action<T> f)\n    {\n        f(await self.ConfigureAwait(false));\n        return unit;\n    }\n\n    /// <summary>\n    /// Impure iteration of the bound value in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public static Task<A> Do<A>(this Task<A> ma, Action<A> f) =>\n        ma.Map(x => {\n            f(x);\n            return x;\n        });\n\n    /// <summary>\n    /// Returns map(Result) if not faulted or cancelled.\n    /// </summary>\n    [Pure]\n    public static async Task<U> Map<T, U>(this Task<T> self, Func<T, U> map) =>\n        map(await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Returns map(Result) if not faulted or cancelled.\n    /// </summary>\n    [Pure]\n    public static async Task<U> MapAsync<T, U>(this Task<T> self, Func<T, Task<U>> map) =>\n        await map(await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    [Pure]\n    public static async Task<V> Join<T, U, K, V>(this Task<T> source,\n        Task<U> inner,\n        Func<T, K> outerKeyMap,\n        Func<U, K> innerKeyMap,\n        Func<T, U, V> project)\n    {\n        await Task.WhenAll(source, inner).ConfigureAwait(false);\n        if (!EqDefault<K>.Equals(outerKeyMap(source.Result), innerKeyMap(inner.Result)))\n        {\n            throw new OperationCanceledException();\n        }\n\n        return project(source.Result, inner.Result);\n    }\n\n    [Pure]\n    public static async Task<V> GroupJoin<T, U, K, V>(this Task<T> source,\n        Task<U> inner,\n        Func<T, K> outerKeyMap,\n        Func<U, K> innerKeyMap,\n        Func<T, Task<U>, V> project)\n    {\n        T t = await source.ConfigureAwait(false);\n        return project(t, inner.Where(u => EqDefault<K>.Equals(outerKeyMap(t), innerKeyMap(u))));\n    }\n\n    [Pure]\n    public static async Task<A> Plus<A>(this Task<A> ma, Task<A> mb)\n    {\n        try\n        {\n            return await ma.ConfigureAwait(false);\n        }\n        catch\n        {\n            return await mb.ConfigureAwait(false);\n        }\n    }\n\n    [Pure]\n    public static async Task<A> PlusFirst<A>(this Task<A> ma, Task<A> mb) =>\n        await (await Task.WhenAny(ma, mb).ConfigureAwait(false)).ConfigureAwait(false);\n\n    public static async Task<A> Cast<A>(this Task source)\n    {\n        if (source == null) throw new ArgumentNullException(nameof(source));\n        await source.ConfigureAwait(false);\n            \n        return source.GetType() switch\n               {\n                   var taskTy when taskTy.IsGenericType                    && \n                                   taskTy.GenericTypeArguments.Length == 1 &&\n                                   taskTy.GenericTypeArguments[0]     == typeof(A) => (A)((dynamic)source).Result,\n                   _ => default!\n               };            \n    }\n\n    public static async Task<Unit> ToUnit(this Task source)\n    {\n        await source.ConfigureAwait(false);\n        return unit;\n    }\n\n    /// <summary>\n    /// Tasks a lazy sequence of tasks and iterates them in a 'measured way'.  A default window size of\n    /// `Sys.DefaultAsyncSequenceConcurrency` tasks is used, which means there are `Environment.ProcessorCount / 2`\n    /// 'await streams' (by default).  An await stream essentially awaits one task from the sequence, and on\n    /// completion goes and gets the next task from the lazy sequence and awaits that too.  This continues until the\n    /// end of the lazy sequence, or forever for infinite streams.\n    /// </summary>\n    internal static Task<IList<B>> WindowMap<A, B>(this IEnumerable<Task<A>> ma, Func<A, B> f, CancellationToken token) =>\n        WindowMap(ma, SysInfo.DefaultAsyncSequenceParallelism, f, token);\n\n    /// <summary>\n    /// Tasks a lazy sequence of tasks and maps them in a 'measured way'.  A default window size of\n    /// `windowSize` tasks is used, which means there are `windowSize` 'await streams'.  An await stream \n    /// essentially awaits one task from the sequence, and on completion goes and gets the next task from \n    /// the lazy sequence and awaits that too.  This continues until the end of the lazy sequence, or forever \n    /// for infinite streams.  Therefore there are at most `windowSize` tasks running concurrently.\n    /// </summary>\n    internal static async Task<IList<B>> WindowMap<A, B>(\n        this IEnumerable<Task<A>> ma, \n        int windowSize, \n        Func<A, B> f,\n        CancellationToken token)\n    {\n        var sync = new object();\n        using var wait = new CountdownEvent(windowSize);\n        using var iter = ma.GetEnumerator();\n\n        var index = -1;\n        var results = new List<B>();\n        var errors = new List<Exception>();\n\n        for (var i = 0; i < windowSize; i++)\n        {\n            #pragma warning disable CS4014 // call is not awaited\n            Task.Run(go, token);\n            #pragma warning restore CS4014\n        }\n\n        Option<(int Index, Task<B>)> next()\n        {\n            lock (sync)\n            {\n                index++;\n                try\n                {\n                    if (iter.MoveNext())\n                    {\n                        results.Add(default!);\n                        return Some((index, iter.Current.Map(f)));\n                    }\n                    else\n                    {\n                        return default;\n                    }\n                }\n                catch (Exception e)\n                {\n                    errors.Add(e);\n                    return default;\n                }\n            }\n        }\n        \n        void go()\n        {\n            try\n            {\n                while (!token.IsCancellationRequested)\n                {\n                    var otask = next();\n                    if (otask.IsNone) return;\n                    var (ix, task) = ((int, Task<B>))otask;\n\n                    SpinWait sw = default;\n                    while (!task.IsCompleted && !token.IsCancellationRequested)\n                    {\n                        sw.SpinOnce();\n                    }\n                    \n                    lock (sync)\n                    {\n                        \n                        if (token.IsCancellationRequested)\n                        {\n                            throw new OperationCanceledException();\n                        }\n                        else if (task.IsCanceled)\n                        {\n                            errors.Add(task.Exception is not null ? task.Exception : new OperationCanceledException());\n                        }\n                        else if (task.IsFaulted)\n                        {\n                            if (task.Exception is not null) errors.Add(task.Exception);\n                        }\n                        else if (task.IsCompleted)\n                        {\n                            results[ix] = task.Result;\n                        }\n                    }\n                }\n            }\n            catch (Exception e)\n            {\n                lock (sync)\n                {\n                    errors.Clear();\n                    errors.Add(e);\n                }\n            }\n            finally\n            {\n                wait.Signal();\n            }\n        }\n\n        await wait.WaitHandle.WaitOneAsync(token).ConfigureAwait(false);\n        \n        if (errors.Count > 0)\n        {\n            var allErrors = errors\n                .SelectMany(e => e is AggregateException ae ? ae.InnerExceptions.ToArray() : new[] { e })\n                .ToArray();\n\n            if (allErrors.Length > 1)\n            {\n                // Throw an aggregate of all exceptions\n                throw new AggregateException(allErrors);\n            }\n            else if (allErrors.Length == 1)\n            {\n                // Throw an aggregate of all exceptions\n                allErrors[0].Rethrow();\n                return default!;\n            }\n        }\n\n        return results;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Task/Task.Prelude.cs",
    "content": "﻿using LanguageExt;\nusing LanguageExt.ClassInstances;\nusing System;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Convert a value to a Task that completes immediately\n    /// </summary>\n    [Pure]\n    public static Task<A> TaskSucc<A>(A self) =>\n        Task.FromResult(self);\n\n    /// <summary>\n    /// Convert a value to a Task that completes immediately\n    /// </summary>\n    [Pure]\n    public static Task<A> TaskFail<A>(Exception ex) =>\n        Task.FromException<A>(ex);\n\n    /// <summary>\n    /// Flatten the nested Task type\n    /// </summary>\n    [Pure]\n    public static Task<A> flatten<A>(Task<Task<A>> self) =>\n        self.Flatten();\n\n    /// <summary>\n    /// Flatten the nested Task type\n    /// </summary>\n    [Pure]\n    public static Task<A> flatten<A>(Task<Task<Task<A>>> self) =>\n        self.Flatten();\n\n    /// <summary>\n    /// Get the Count of a Task T.  Returns either 1 or 0 if cancelled or faulted.\n    /// </summary>\n    [Pure]\n    public static Task<int> count<A>(Task<A> self) =>\n        self.Count();\n\n    /// <summary>\n    /// Monadic bind operation for Task\n    /// </summary>\n    [Pure]\n    public static Task<B> bind<A, B>(Task<A> self, Func<A, Task<B>> bind) =>\n        self.Bind(bind);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static Task<bool> exists<A>(Task<A> self, Func<A, bool> pred) =>\n        self.Exists(pred);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static Task<bool> existsAsync<A>(Task<A> self, Func<A, Task<bool>> pred) =>\n        self.ExistsAsync(pred);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static Task<bool> forall<A>(Task<A> self, Func<A, bool> pred) =>\n        self.ForAll(pred);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static Task<bool> forallAsync<A>(Task<A> self, Func<A, Task<bool>> pred) =>\n        self.ForAllAsync(pred);\n\n    /// <summary>\n    /// Filters the task.  This throws a BottomException when pred(Result)\n    /// returns false\n    /// </summary>\n    [Pure]\n    public static Task<A> filter<A>(Task<A> self, Func<A, bool> pred) =>\n        self.Filter(pred);\n\n    /// <summary>\n    /// Iterates the Task.  Invokes f(Result) if not faulted or cancelled\n    /// </summary>\n    public static Task<Unit> iter<A>(Task<A> self, Action<A> f) =>\n        self.Iter(f);\n\n    /// <summary>\n    /// Returns map(Result) if not faulted or cancelled.\n    /// </summary>\n    [Pure]\n    public static Task<B> map<A, B>(Task<A> self, Func<A, B> map) =>\n        self.Map(map);\n\n    /// <summary>\n    /// Returns map(Result) if not faulted or cancelled.\n    /// </summary>\n    [Pure]\n    public static Task<B> mapAsync<A, B>(Task<A> self, Func<A, Task<B>> map) =>\n        self.MapAsync(map);\n\n    [Pure]\n    public static Task<A> plus<A>(this Task<A> ma, Task<A> mb) =>\n        ma.Plus(mb);\n\n    [Pure]\n    public static Task<A> plusFirst<A>(this Task<A> ma, Task<A> mb) =>\n        ma.PlusFirst(mb);\n\n    /// <summary>\n    /// Returns the first successful computation \n    /// </summary>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <param name=\"ma\">The first computation to run</param>\n    /// <param name=\"tail\">The rest of the computations to run</param>\n    /// <returns>The first computation that succeeds</returns>\n    [Pure]\n    public static Task<A> choice<A>(Task<A> ma, params Task<A>[] tail) =>\n        choice(Cons(ma, tail));\n\n    /// <summary>\n    /// Returns the first successful computation \n    /// </summary>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <param name=\"xs\">Sequence of computations to run</param>\n    /// <returns>The first computation that succeeds</returns>\n    [Pure]\n    public static async Task<A> choice<A>(Seq<Task<A>> xs)\n    {\n        foreach (var x in xs)\n        {\n            try\n            {\n                return await x.ConfigureAwait(false);\n            }\n            catch\n            {\n                // ignore\n            }\n        }\n        throw new BottomException();\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type FB derived from Applicative of B</returns>\n    [Pure]\n    public static async Task<B> apply<A, B>(Task<Func<A, B>> fab, Task<A> fa)\n    {\n        await Task.WhenAll(fab, fa).ConfigureAwait(false);\n        return fab.Result(fa.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type FB derived from Applicative of B</returns>\n    [Pure]\n    public static Task<B> apply<A, B>(Func<A, B> fab, Task<A> fa) =>\n        fa.Map(fab);\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative a to apply</param>\n    /// <param name=\"fb\">Applicative b to apply</param>\n    /// <returns>Applicative of type FC derived from Applicative of C</returns>\n    [Pure]\n    public static async Task<C> apply<A, B, C>(Task<Func<A, B, C>> fabc, Task<A> fa, Task<B> fb)\n    {\n        await Task.WhenAll(fabc, fa, fb).ConfigureAwait(false);\n        return fabc.Result(fa.Result, fb.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative a to apply</param>\n    /// <param name=\"fb\">Applicative b to apply</param>\n    /// <returns>Applicative of type FC derived from Applicative of C</returns>\n    [Pure]\n    public static async Task<C> apply<A, B, C>(Func<A, B, C> fabc, Task<A> fa, Task<B> fb)\n    {\n        await Task.WhenAll(fa, fb).ConfigureAwait(false);\n        return fabc(fa.Result, fb.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type f(b -> c) derived from Applicative of Func〈B, C〉</returns>\n    [Pure]\n    public static async Task<Func<B, C>> apply<A, B, C>(Task<Func<A, B, C>> fabc, Task<A> fa)\n    {\n        await Task.WhenAll(fabc, fa).ConfigureAwait(false);\n        return curry(fabc.Result)(fa.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type f(b -> c) derived from Applicative of Func〈B, C〉</returns>\n    [Pure]\n    public static Task<Func<B, C>> apply<A, B, C>(Func<A, B, C> fabc, Task<A> fa) =>\n        fa.Map(curry(fabc));\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type f(b -> c) derived from Applicative of Func〈B, C〉</returns>\n    [Pure]\n    public static async Task<Func<B, C>> apply<A, B, C>(Task<Func<A, Func<B, C>>> fabc, Task<A> fa)\n    {\n        await Task.WhenAll(fabc, fa).ConfigureAwait(false);\n        return fabc.Result(fa.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type f(b -> c) derived from Applicative of Func〈B, C〉</returns>\n    [Pure]\n    public static Task<Func<B, C>> apply<A, B, C>(Func<A, Func<B, C>> fabc, Task<A> fa) =>\n        fa.Map(fabc);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/Task/Tasks.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\ninternal static class Tasks\n{\n    [Pure]\n    public static async Task<bool> ForAll<A>(IEnumerable<Task<A>> fs, Func<A, bool> pred, CancellationToken token = default)\n    {\n        var ra = await fs.WindowMap(pred, default).ConfigureAwait(false);\n        return ra.AsIterable().ForAll(identity);\n    }\n\n    [Pure]\n    public static async Task<bool> ForAll<A>(IEnumerable<Task<A>> fs, Func<A, bool> pred, int windowSize, CancellationToken token = default)\n    {\n        var ra = await fs.WindowMap(windowSize, pred, default).ConfigureAwait(false);\n        return ra.AsIterable().ForAll(identity);\n    }\n\n    [Pure]\n    public static async Task<bool> Exists<A>(IEnumerable<Task<A>> fs, Func<A, bool> pred, CancellationToken token = default)\n    {\n        var ra = await fs.WindowMap(pred, default).ConfigureAwait(false);\n        return ra.AsIterable().Exists(identity);\n    }\n\n    [Pure]\n    public static async Task<bool> Exists<A>(IEnumerable<Task<A>> fs, Func<A, bool> pred, int windowSize, CancellationToken token = default)\n    {\n        var ra = await fs.WindowMap(windowSize, pred, default).ConfigureAwait(false);\n        return ra.AsIterable().Exists(identity);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/ValueTask/ValueTask.Extensions.cs",
    "content": "﻿using LanguageExt.ClassInstances;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class ValueTaskExtensions\n{\n    public static bool CompletedSuccessfully<A>(this ValueTask<A> ma) =>\n        ma is { IsCompleted: true, IsFaulted: false, IsCanceled: false };\n        \n    [Pure]\n    public static ValueTask<A> AsFailedValueTask<A>(this Exception ex) =>\n        new (ex.AsFailedTask<A>());\n\n    /// <summary>\n    /// Convert a value to a Task that completes immediately\n    /// </summary>\n    [Pure]\n    public static ValueTask<A> AsValueTask<A>(this A self) =>\n        new (self);\n\n    /// <summary>\n    /// Convert a Task to a ValueTask \n    /// </summary>\n    [Pure]\n    public static ValueTask<A> ToValue<A>(this Task<A> self) =>\n        new (self);\n\n    /// <summary>\n    /// Flatten the nested Task type\n    /// </summary>\n    [Pure]\n    public static async ValueTask<A> Flatten<A>(this ValueTask<ValueTask<A>> self)\n    {\n        var t = await self.ConfigureAwait(false);\n        var u = await t.ConfigureAwait(false);\n        return u;\n    }\n\n    /// <summary>\n    /// Flatten the nested Task type\n    /// </summary>\n    [Pure]\n    public static async ValueTask<A> Flatten<A>(this ValueTask<ValueTask<ValueTask<A>>> self)\n    {\n        var t = await self.ConfigureAwait(false);\n        var u = await t.ConfigureAwait(false);\n        var v = await u.ConfigureAwait(false);\n        return v;\n    }\n\n    /// <summary>\n    /// Standard LINQ Select implementation for Task\n    /// </summary>\n    [Pure]\n    public static async ValueTask<U> Select<T, U>(this ValueTask<T> self, Func<T, U> map) =>\n        map(await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Standard LINQ Where implementation for Task\n    /// </summary>\n    [Pure]\n    public static async ValueTask<T> Where<T>(this ValueTask<T> self, Func<T, bool> pred)\n    {\n        var resT = await self.ConfigureAwait(false);\n        var res = pred(resT);\n        if (!res)\n        {\n            throw new OperationCanceledException();\n        }\n\n        return resT;\n    }\n\n    /// <summary>\n    /// Standard LINQ SelectMany implementation for Task\n    /// </summary>\n    [Pure]\n    public async static ValueTask<U> SelectMany<T, U>(this ValueTask<T> self,\n        Func<T, ValueTask<U>> bind) =>\n        await bind(await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    /// <summary>\n    /// Standard LINQ SelectMany implementation for Task\n    /// </summary>\n    [Pure]\n    public static async ValueTask<V> SelectMany<T, U, V>(this ValueTask<T> self,\n        Func<T, ValueTask<U>> bind,\n        Func<T, U, V> project)\n    {\n        var resT = await self.ConfigureAwait(false);\n        var resU = await bind(resT).ConfigureAwait(false);\n        return project(resT, resU);\n    }\n\n    /// <summary>\n    /// Get the Count of a Task T.  Returns either 1 or 0 if cancelled or faulted.\n    /// </summary>\n    [Pure]\n    public static async ValueTask<int> Count<T>(this ValueTask<T> self)\n    {\n        try\n        {\n            await self.ConfigureAwait(false);\n            return 1;\n        }\n        catch (Exception)\n        {\n            return 0;\n        }\n    }\n\n    /// <summary>\n    /// Monadic bind operation for Task\n    /// </summary>\n    [Pure]\n    public static ValueTask<U> Bind<T, U>(this ValueTask<T> self, Func<T, ValueTask<U>> bind) =>\n        self.SelectMany(bind);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static async ValueTask<bool> Exists<T>(this ValueTask<T> self, Func<T, bool> pred) =>\n        pred(await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static async ValueTask<bool> ExistsAsync<T>(this ValueTask<T> self, Func<T, ValueTask<bool>> pred) =>\n        await pred(await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static async ValueTask<bool> ForAll<T>(this ValueTask<T> self, Func<T, bool> pred) =>\n        pred(await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static async ValueTask<bool> ForAllAsync<T>(this ValueTask<T> self, Func<T, ValueTask<bool>> pred) =>\n        await pred(await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    /// <summary>\n    /// Filters the task.  This throws a BottomException when pred(Result)\n    /// returns false\n    /// </summary>\n    [Pure]\n    public static ValueTask<T> Filter<T>(this ValueTask<T> self, Func<T, bool> pred) =>\n        self.Where(pred);\n\n    /// <summary>\n    /// Folds the Task.  Returns folder(state,Result) if not faulted or\n    /// cancelled.  Returns state otherwise.\n    /// </summary>\n    [Pure]\n    public static async ValueTask<S> Fold<T, S>(this ValueTask<T> self, S state, Func<S, T, S> folder) =>\n        folder(state, await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Folds the Task.  Returns folder(state,Result) if not faulted or\n    /// cancelled.  Returns state otherwise.\n    /// </summary>\n    [Pure]\n    public static async ValueTask<S> FoldAsync<T, S>(this ValueTask<T> self, S state, Func<S, T, ValueTask<S>> folder) =>\n        await folder(state, await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    /// <summary>\n    /// Iterates the Task.  Invokes f(Result) if not faulted or cancelled\n    /// </summary>\n    public static async ValueTask<Unit> Iter<T>(this ValueTask<T> self, Action<T> f)\n    {\n        f(await self.ConfigureAwait(false));\n        return unit;\n    }\n\n    /// <summary>\n    /// Impure iteration of the bound value in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public static ValueTask<A> Do<A>(this ValueTask<A> ma, Action<A> f) =>\n        ma.Map(x => {\n            f(x);\n            return x;\n        });\n\n    /// <summary>\n    /// Returns map(Result) if not faulted or cancelled.\n    /// </summary>\n    [Pure]\n    public static async ValueTask<U> Map<T, U>(this ValueTask<T> self, Func<T, U> map) =>\n        map(await self.ConfigureAwait(false));\n\n    /// <summary>\n    /// Returns map(Result) if not faulted or cancelled.\n    /// </summary>\n    [Pure]\n    public static async ValueTask<U> MapAsync<T, U>(this ValueTask<T> self, Func<T, ValueTask<U>> map) =>\n        await map(await self.ConfigureAwait(false)).ConfigureAwait(false);\n\n    [Pure]\n    public static async ValueTask<V> Join<T, U, K, V>(this ValueTask<T> source,\n        ValueTask<U> inner,\n        Func<T, K> outerKeyMap,\n        Func<U, K> innerKeyMap,\n        Func<T, U, V> project)\n    {\n        await Task.WhenAll(source.AsTask(), inner.AsTask()).ConfigureAwait(false);\n        if (!EqDefault<K>.Equals(outerKeyMap(source.Result), innerKeyMap(inner.Result)))\n        {\n            throw new OperationCanceledException();\n        }\n        return project(source.Result, inner.Result);\n    }\n\n    [Pure]\n    public static async ValueTask<V> GroupJoin<T, U, K, V>(this ValueTask<T> source,\n        ValueTask<U> inner,\n        Func<T, K> outerKeyMap,\n        Func<U, K> innerKeyMap,\n        Func<T, ValueTask<U>, V> project)\n    {\n        T t = await source.ConfigureAwait(false);\n        return project(t, inner.Where(u => EqDefault<K>.Equals(outerKeyMap(t), innerKeyMap(u))));\n    }\n\n    [Pure]\n    public static async ValueTask<A> Plus<A>(this ValueTask<A> ma, ValueTask<A> mb)\n    {\n        try\n        {\n            return await ma.ConfigureAwait(false);\n        }\n        catch\n        {\n            return await mb.ConfigureAwait(false);\n        }\n    }\n\n    [Pure]\n    public static async ValueTask<A> PlusFirst<A>(this ValueTask<A> ma, ValueTask<A> mb) =>\n        await ma.AsTask().PlusFirst(mb.AsTask());\n        \n    /// <summary>\n    /// Cast a ValueTask to a ValueTask〈A〉 (may throw if underlying value doesn't exist)\n    /// </summary>\n    public static ValueTask<A> Cast<A>(this ValueTask source) => \n        new(source.AsTask().Cast<A>());\n\n    public static async ValueTask<Unit> ToUnit(this ValueTask source)\n    {\n        await source.ConfigureAwait(false);\n        return unit;\n    }\n\n    /// <summary>\n    /// Tasks a lazy sequence of tasks and iterates them in a 'measured way'.  A default window size of\n    /// `Sys.DefaultAsyncSequenceConcurrency` tasks is used, which by default means there are\n    /// `Sys.DefaultAsyncSequenceConcurrency / 2` 'await streams'.  An await stream essentially awaits one\n    /// task from the sequence, and on completion goes and gets the next task from the lazy sequence and\n    /// awaits that too.  This continues until the end of the lazy sequence, or forever for infinite streams.\n    /// </summary>\n    public static ValueTask<Unit> WindowIter<A>(this IEnumerable<ValueTask<A>> ma, Action<A> f) =>\n        WindowIter(ma, SysInfo.DefaultAsyncSequenceParallelism, f);\n\n    /// <summary>\n    /// Tasks a lazy sequence of tasks and iterates them in a 'measured way'.  A default window size of\n    /// `windowSize` tasks is used, which means there are `windowSize` 'await streams'.  An await stream \n    /// essentially awaits one task from the sequence, and on completion goes and gets the next task from \n    /// the lazy sequence and awaits that too.  This continues until the end of the lazy sequence, or forever \n    /// for infinite streams.  Therefore there are at most `windowSize` tasks running concurrently.\n    /// </summary>\n    public static async ValueTask<Unit> WindowIter<A>(this IEnumerable<ValueTask<A>> ma, int windowSize, Action<A> f)\n    {\n        var       sync = new object();\n        using var iter = ma.GetEnumerator();\n\n        (bool Success, ValueTask<A> Task) GetNext()\n        {\n            lock (sync)\n            {\n                return iter.MoveNext()\n                           ? (true, iter.Current)\n                           : default;\n            }\n        }\n\n        var tasks = new List<ValueTask<Unit>>();\n        for (var i = 0; i < windowSize; i++)\n        {\n            var (s, outerTask) = GetNext();\n            if (!s) break;\n\n            tasks.Add(outerTask.Bind(async oa =>\n                                     {\n                                         f(oa);\n\n                                         while (true)\n                                         {\n                                             var next = GetNext();\n                                             if (!next.Success) return unit;\n                                             var a = await next.Task.ConfigureAwait(false);\n                                             f(a);\n                                         }\n                                     }));\n        }\n\n        await Task.WhenAll(tasks.Select(t => t.AsTask())).ConfigureAwait(false);\n        return unit;\n    }\n\n    /// <summary>\n    /// Tasks a lazy sequence of tasks and iterates them in a 'measured way'.  A default window size of\n    /// `Sys.DefaultAsyncSequenceConcurrency` tasks is used, which means there are `Environment.ProcessorCount / 2`\n    /// 'await streams' (by default).  An await stream essentially awaits one task from the sequence, and on\n    /// completion goes and gets the next task from the lazy sequence and awaits that too.  This continues until the\n    /// end of the lazy sequence, or forever for infinite streams.\n    /// </summary>\n    internal static ValueTask<IList<B>> WindowMap<A, B>(\n        this IEnumerable<ValueTask<A>> ma, \n        Func<A, B> f, \n        CancellationToken token) =>\n        WindowMap(ma, SysInfo.DefaultAsyncSequenceParallelism, f, token);\n\n    /// <summary>\n    /// Tasks a lazy sequence of tasks and maps them in a 'measured way'.  A default window size of\n    /// `windowSize` tasks is used, which means there are `windowSize` 'await streams'.  An await stream \n    /// essentially awaits one task from the sequence, and on completion goes and gets the next task from \n    /// the lazy sequence and awaits that too.  This continues until the end of the lazy sequence, or forever \n    /// for infinite streams.  Therefore there are at most `windowSize` tasks running concurrently.\n    /// </summary>\n    internal static async ValueTask<IList<B>> WindowMap<A, B>(\n        this IEnumerable<ValueTask<A>> ma, \n        int windowSize,\n        Func<A, B> f, CancellationToken token) =>\n        await ma.Select(va => va.AsTask()).WindowMap(windowSize, f, token);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/ValueTask/ValueTask.Prelude.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Convert a value to a Task that completes immediately\n    /// </summary>\n    [Pure]\n    public static ValueTask<A> ValueTaskSucc<A>(A self) =>\n        new (self);\n\n    /// <summary>\n    /// Convert a value to a Task that completes immediately\n    /// </summary>\n    [Pure]\n    public static ValueTask<A> ValueTaskFail<A>(Exception ex) =>\n        Task.FromException<A>(ex).ToValue();\n\n    /// <summary>\n    /// Flatten the nested Task type\n    /// </summary>\n    [Pure]\n    public static ValueTask<A> flatten<A>(ValueTask<ValueTask<A>> self) =>\n        self.Flatten();\n\n    /// <summary>\n    /// Flatten the nested Task type\n    /// </summary>\n    [Pure]\n    public static ValueTask<A> flatten<A>(ValueTask<ValueTask<ValueTask<A>>> self) =>\n        self.Flatten();\n\n    /// <summary>\n    /// Get the Count of a Task T.  Returns either 1 or 0 if cancelled or faulted.\n    /// </summary>\n    [Pure]\n    public static ValueTask<int> count<A>(ValueTask<A> self) =>\n        self.Count();\n\n    /// <summary>\n    /// Monadic bind operation for Task\n    /// </summary>\n    [Pure]\n    public static ValueTask<B> bind<A, B>(ValueTask<A> self, Func<A, ValueTask<B>> bind) =>\n        self.Bind(bind);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static ValueTask<bool> exists<A>(ValueTask<A> self, Func<A, bool> pred) =>\n        self.Exists(pred);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static ValueTask<bool> existsAsync<A>(ValueTask<A> self, Func<A, ValueTask<bool>> pred) =>\n        self.ExistsAsync(pred);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static ValueTask<bool> forall<A>(ValueTask<A> self, Func<A, bool> pred) =>\n        self.ForAll(pred);\n\n    /// <summary>\n    /// Returns false if the Task is cancelled or faulted, otherwise\n    /// it returns the result of pred(Result)\n    /// </summary>\n    [Pure]\n    public static ValueTask<bool> forallAsync<A>(ValueTask<A> self, Func<A, ValueTask<bool>> pred) =>\n        self.ForAllAsync(pred);\n\n    /// <summary>\n    /// Filters the task.  This throws a BottomException when pred(Result)\n    /// returns false\n    /// </summary>\n    [Pure]\n    public static ValueTask<A> filter<A>(ValueTask<A> self, Func<A, bool> pred) =>\n        self.Filter(pred);\n\n    /// <summary>\n    /// Iterates the Task.  Invokes f(Result) if not faulted or cancelled\n    /// </summary>\n    public static ValueTask<Unit> iter<A>(ValueTask<A> self, Action<A> f) =>\n        self.Iter(f);\n\n    /// <summary>\n    /// Returns map(Result) if not faulted or cancelled.\n    /// </summary>\n    [Pure]\n    public static ValueTask<B> map<A, B>(ValueTask<A> self, Func<A, B> map) =>\n        self.Map(map);\n\n    /// <summary>\n    /// Returns map(Result) if not faulted or cancelled.\n    /// </summary>\n    [Pure]\n    public static ValueTask<B> mapAsync<A, B>(ValueTask<A> self, Func<A, ValueTask<B>> map) =>\n        self.MapAsync(map);\n\n    [Pure]\n    public static ValueTask<A> plus<A>(ValueTask<A> ma, ValueTask<A> mb) =>\n        ma.Plus(mb);\n\n    [Pure]\n    public static ValueTask<A> plusFirst<A>(ValueTask<A> ma, ValueTask<A> mb) =>\n        ma.PlusFirst(mb);\n\n    /// <summary>\n    /// Returns the first successful computation \n    /// </summary>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <param name=\"ma\">The first computation to run</param>\n    /// <param name=\"tail\">The rest of the computations to run</param>\n    /// <returns>The first computation that succeeds</returns>\n    [Pure]\n    public static ValueTask<A> choice<A>(ValueTask<A> ma, params ValueTask<A>[] tail) =>\n        choice(Cons(ma, tail));\n\n    /// <summary>\n    /// Returns the first successful computation \n    /// </summary>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <param name=\"xs\">Sequence of computations to run</param>\n    /// <returns>The first computation that succeeds</returns>\n    [Pure]\n    public static async ValueTask<A> choice<A>(Seq<ValueTask<A>> xs)\n    {\n        foreach (var x in xs)\n        {\n            try\n            {\n                return await x.ConfigureAwait(false);\n            }\n            catch\n            {\n                // ignore\n            }\n        }\n        throw new BottomException();\n    }\n                    \n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type FB derived from Applicative of B</returns>\n    [Pure]\n    public static async ValueTask<B> apply<A, B>(ValueTask<Func<A, B>> fab, ValueTask<A> fa)\n    {\n        await Task.WhenAll(fab.AsTask(), fa.AsTask()).ConfigureAwait(false);\n        return fab.Result(fa.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type FB derived from Applicative of B</returns>\n    [Pure]\n    public static ValueTask<B> apply<A, B>(Func<A, B> fab, ValueTask<A> fa) =>\n        fa.Map(fab);\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative a to apply</param>\n    /// <param name=\"fb\">Applicative b to apply</param>\n    /// <returns>Applicative of type FC derived from Applicative of C</returns>\n    [Pure]\n    public static async ValueTask<C> apply<A, B, C>(ValueTask<Func<A, B, C>> fabc, ValueTask<A> fa, ValueTask<B> fb)\n    {\n        await Task.WhenAll(fabc.AsTask(), fa.AsTask(), fb.AsTask()).ConfigureAwait(false);\n        return fabc.Result(fa.Result, fb.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative a to apply</param>\n    /// <param name=\"fb\">Applicative b to apply</param>\n    /// <returns>Applicative of type FC derived from Applicative of C</returns>\n    [Pure]\n    public static async ValueTask<C> apply<A, B, C>(Func<A, B, C> fabc, ValueTask<A> fa, ValueTask<B> fb)\n    {\n        await Task.WhenAll(fa.AsTask(), fb.AsTask()).ConfigureAwait(false);\n        return fabc(fa.Result, fb.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type f(b -> c) derived from Applicative of Func〈B, C〉</returns>\n    [Pure]\n    public static async ValueTask<Func<B, C>> apply<A, B, C>(ValueTask<Func<A, B, C>> fabc, ValueTask<A> fa)\n    {\n        await Task.WhenAll(fabc.AsTask(), fa.AsTask()).ConfigureAwait(false);\n        return curry(fabc.Result)(fa.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type f(b -> c) derived from Applicative of Func〈B, C〉</returns>\n    [Pure]\n    public static ValueTask<Func<B, C>> apply<A, B, C>(Func<A, B, C> fabc, ValueTask<A> fa) =>\n        fa.Map(curry(fabc));\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type f(b -> c) derived from Applicative of Func〈B, C〉</returns>\n    [Pure]\n    public static async ValueTask<Func<B, C>> apply<A, B, C>(ValueTask<Func<A, Func<B, C>>> fabc, ValueTask<A> fa)\n    {\n        await Task.WhenAll(fabc.AsTask(), fa.AsTask()).ConfigureAwait(false);\n        return fabc.Result(fa.Result);\n    }\n\n    /// <summary>\n    /// Apply\n    /// </summary>\n    /// <param name=\"fab\">Function to apply the applicative to</param>\n    /// <param name=\"fa\">Applicative to apply</param>\n    /// <returns>Applicative of type f(b -> c) derived from Applicative of Func〈B, C〉</returns>\n    [Pure]\n    public static ValueTask<Func<B, C>> apply<A, B, C>(Func<A, Func<B, C>> fabc, ValueTask<A> fa) =>\n        fa.Map(fabc);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/ValueTask/ValueTasks.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\ninternal static class ValueTasks\n{\n    [Pure]\n    public static async ValueTask<bool> ForAll<A>(IEnumerable<ValueTask<A>> fs, Func<A, bool> pred, CancellationToken token = default)\n    {\n        var ra = await fs.WindowMap(pred, default).ConfigureAwait(false);\n        return ra.AsIterable().ForAll(identity);\n    }\n\n    [Pure]\n    public static async ValueTask<bool> ForAll<A>(IEnumerable<ValueTask<A>> fs, Func<A, bool> pred, int windowSize, CancellationToken token = default)\n    {\n        var ra = await fs.WindowMap(windowSize, pred, default).ConfigureAwait(false);\n        return ra.AsIterable().ForAll(identity);\n    }\n\n    [Pure]\n    public static async ValueTask<bool> Exists<A>(IEnumerable<ValueTask<A>> fs, Func<A, bool> pred, CancellationToken token = default)\n    {\n        var ra = await fs.WindowMap(pred, default).ConfigureAwait(false);\n        return ra.AsIterable().Exists(identity);\n    }\n\n    [Pure]\n    public static async ValueTask<bool> Exists<A>(IEnumerable<ValueTask<A>> fs, Func<A, bool> pred, int windowSize, CancellationToken token = default)\n    {\n        var ra = await fs.WindowMap(windowSize, pred, default).ConfigureAwait(false);\n        return ra.AsIterable().Exists(identity);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VectorClock/Relation.cs",
    "content": "namespace LanguageExt\n{\n    /// <summary>\n    /// The relations two vector clocks may find themselves in.\n    /// </summary>\n    public enum Relation\n    {\n        Causes,\n        CausedBy,\n        Concurrent\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VectorClock/VectorClock.A.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// <para>\n/// To create a vector clock, start from `Empty` or `Single` and `Insert`\n/// elements into it.  As a shortcut, `fromList` just inserts all the\n/// elements in a list, in order.\n/// </para>\n/// <code>\n///     var vc = VectorClock〈char〉.Empty;\n///     vc = vc.Insert('a', 1);\n///     vc = vc.Insert('b', 2);\n///     vc == VectorClock〈char〉.fromList(Seq(('a', 1), ('b', 2)))\n/// </code>\n/// <para>\n/// Note that, for different keys, the order of insertion does not\n/// matter:\n/// </para>\n/// <code>\n///     fromList(Seq(('a', 1), ('b', 2)) == fromList(Seq(('b', 2), ('a', 1))\n/// </code>\n/// <para>\n/// Once you have a given vector clock, you can 'lookup' its fields,\n/// check that keys are 'member's, or convert it back 'toList' form.\n/// </para>\n/// <code>\n///     vc.Lookup('a') == Some(1)\n///     vc.Lookup('c') == None\n/// </code>\n/// <para>\n/// The main operations that you would do with a vector clock are to\n/// increment the entry corresponding to the current process and to\n/// update the process's vector clock with the 'max' of its and the\n/// received message's clocks.\n/// </para>\n/// <code>\n///     vc.Inc('a') == Some [('a', 2), ('b', 2)]\n///     VectorClock.max( [('a', 1), ('b', 2)], [('c', 3), ('b', 1)] ) == [('a', 1), ('b', 2), ('c' 3)]\n/// </code>\n/// <para>\n/// Finally, upon receiving different messages, you may wish to\n/// discover the relationship, if any, between them.  This\n/// information could be useful in determining the correct order to\n/// process the messages.\n/// </para>\n/// <code>\n///     VectorClock.relation (fromList [('a', 1), ('b', 2)], fromList [('a', 2), ('b', 2)]) == Causes\n///     VectorClock.relation (fromList [('a', 2), ('b', 2)], fromList [('a', 1), ('b', 2)]) == CausedBy\n///     VectorClock.relation (fromList [('a', 2), ('b', 2)], fromList [('a', 1), ('b', 3)]) == Concurrent\n/// </code>\n/// <para>\n/// A vector clock is, conceptually, an associative list sorted by the\n/// value of the key, where each key appears only once.\n/// </para>\n/// </summary>\npublic record VectorClock<A>(Seq<(A, long)> Entries) \n    where A : IComparable<A>\n{\n    public static readonly VectorClock<A> Empty = new(Seq<(A, long)>());\n\n    public virtual bool Equals(VectorClock<A>? rhs) =>\n        rhs is not null                                                                               &&\n        GetHashCode() == rhs.GetHashCode()                                                            &&\n        Count         == rhs.Count                                                                    &&\n        Entries.Zip(rhs.Entries).ForAll(p => equals<OrdDefault<A>, A>(p.First.Item1, p.Second.Item1)) &&\n        Entries.Zip(rhs.Entries).ForAll(p => p.First.Item2 == p.Second.Item2);\n\n    public override int GetHashCode() =>\n        Entries.GetHashCode();\n\n    /// <summary>\n    /// A vector clock with a single element\n    /// </summary>\n    public static VectorClock<A> Single(A x, long y) =>\n        fromList(Seq((x, y)));\n\n    /// <summary>\n    /// Insert each entry in the list one at a time.\n    /// </summary>\n    public static VectorClock<A> fromList(Seq<(A x, long y)> list) =>\n        list.Fold(Empty, (vc, pair) => vc.Insert(pair.x, pair.y));\n\n    /// <summary>\n    /// All the entries in the vector clock.  Note that this is /not/ the inverse of 'fromList'\n    /// </summary>\n    public Seq<(A x, long y)> ToSeq() =>\n        Entries;\n\n    /// <summary>\n    /// Is the vector clock empty?\n    /// </summary>\n    public bool IsEmpty =>\n        Entries.IsEmpty;\n\n    /// <summary>\n    /// The number of entries in the vector clock.\n    /// </summary>\n    public int Count =>\n        Entries.Count;\n\n    /// <summary>\n    /// Lookup the value for a key in the vector clock and remove the corresponding entry\n    /// </summary>\n    public (Option<long> Value, VectorClock<A> Clock) Extract(A index)\n    {\n        Option<long> value = default;\n        return (value, new VectorClock<A>(go(Entries)));\n\n        Seq<(A x, long y)> go(Seq<(A x, long y)> zs)\n        {\n            var res = Seq<(A x, long y)>.Empty;\n            foreach (var z in zs)\n            {\n                if (equals<OrdDefault<A>, A>(z.x, index))\n                {\n                    value = z.y;\n                }\n                else\n                {\n                    res = res.Add(z);\n                }\n            }\n            return res;\n        }\n    }\n\n    /// <summary>\n    /// Lookup the value for a key in the vector clock.\n    /// </summary>\n    public Option<long> Lookup(A index)\n    {\n        foreach (var z in Entries)\n        {\n            if (equals<OrdDefault<A>, A>(z.Item1, index)) return z.Item2;\n        }\n\n        return None;\n    }\n\n    /// <summary>\n    /// Is a member?\n    /// </summary>\n    public bool Contains(A index) =>\n        Lookup(index).IsSome;\n\n    /// <summary>\n    /// Delete\n    /// </summary>\n    public VectorClock<A> Remove(A index) =>\n        new (Entries.Filter(e => !equals<OrdDefault<A>, A>(e.Item1, index)).ToSeq());\n\n    /// <summary>\n    /// Insert or replace the entry for a key.\n    /// </summary>\n    public VectorClock<A> Insert(A index, long value)\n    {\n        return new VectorClock<A>(go(Entries));\n\n        Seq<(A, long)> go(Seq<(A, long)> entries) =>\n            entries.IsEmpty\n                ? Seq((index, value))\n                : entries.Head.Value switch\n                  {\n                      (var x1, _) xy when lessThan<OrdDefault<A>, A>(x1, index) => xy.Cons(go(entries.Tail)),\n                      (var x1, _) when equals<OrdDefault<A>, A>(x1, index)      => (index, value).Cons(entries.Tail),\n                      var xy                                                    => (index, value).Cons(xy.Cons(entries.Tail)),\n                  };\n    }\n\n    /// <summary>\n    /// Increment the entry for a key by 1\n    /// </summary>\n    public Option<VectorClock<A>> Inc(A index) =>\n        Lookup(index).Map(y => Insert(index, y + 1));\n\n    /// <summary>\n    /// Increment the entry for a key by 1\n    /// </summary>\n    public VectorClock<A> Inc(A index, long defaultValue) =>\n        Lookup(index).Case switch\n        {\n            long y => Insert(index, y            + 1),\n            _      => Insert(index, defaultValue + 1)\n        };\n\n    /// <summary>\n    /// Combine two vector clocks entry-by-entry\n    /// </summary>\n    /// <param name=\"f\">a function that takes the /key/, the value of the entry in\n    /// the left hand vector clock, if it exists, the value in the\n    /// right hand vector clock, if it exists, and, if it wishes to\n    /// keep a value for this /key/ in the resulting vector clock,\n    /// returns it.</param>\n    /// <param name=\"vc1\">the left hand vector clock</param>\n    /// <param name=\"vc2\">he right hand vector clock</param>\n    /// <returns></returns>\n    public static VectorClock<A> combine(\n        Func<A, Option<long>, Option<long>, Option<long>> f,\n        VectorClock<A> vc1,\n        VectorClock<A> vc2)\n    {\n        return new VectorClock<A>(go(vc1.Entries, vc2.Entries).Somes());\n            \n        Seq<Option<(A, long)>> go(Seq<(A, long)> es1, Seq<(A, long)> es2) =>\n            (es1.IsEmpty, es2.IsEmpty) switch\n            {\n                (true,  _) => es2.Map(xy => mk(xy.Item1, f(xy.Item1, None, Some(xy.Item2)))),\n                (_,  true) => es1.Map(xy => mk(xy.Item1, f(xy.Item1, Some(xy.Item2), None))),\n                _ => compare<OrdDefault<A>, A>(es1.Head.Value.Item1, es2.Head.Value.Item1) switch\n                     {\n                         var c when c < 0  => mk(es1.Head.Value.Item1, f(es1.Head.Value.Item1, Some(es1.Head.Value.Item2), None)).Cons(go(es1.Tail, es2)),\n                         var c when c == 0 => mk(es1.Head.Value.Item1, f(es1.Head.Value.Item1, Some(es1.Head.Value.Item2), Some(es2.Head.Value.Item2))).Cons(go(es1.Tail, es2.Tail)),\n                         _                 => mk(es2.Head.Value.Item1, f(es2.Head.Value.Item1, None, Some(es2.Head.Value.Item2))).Cons(go(es1, es2.Tail)),\n                     }\n            };\n\n        static Option<(A, long)> mk(A x, Option<long> v) =>\n            v.Map(y => (x, y)); \n    }\n\n    /// <summary>\n    /// The maximum of the two vector clocks.\n    /// </summary>\n    public VectorClock<A> Max(VectorClock<A> vc2) =>\n        max(this, vc2);\n\n    /// <summary>\n    /// The maximum of the two vector clocks.\n    /// </summary>\n    public static VectorClock<A> max(VectorClock<A> vc1, VectorClock<A> vc2)\n    {\n        return combine(maxEntry, vc1, vc2);\n\n        static Option<long> maxEntry(A _, Option<long> ea, Option<long> eb) =>\n            (ea.Case, eb.Case) switch\n            {\n                (null, null)     => None,\n                (long x, null)   => Some(x),\n                (null, long y)   => Some(y),\n                (long x, long y) => Some(Math.Max(x, y)),\n                _                => None\n            };\n    }\n\n    /// <summary>\n    /// The relation between the two vector clocks.\n    /// </summary>\n    public Relation Relation(VectorClock<A> vc2) =>\n        relation(this, vc2);\n\n    /// <summary>\n    /// The relation between the two vector clocks.\n    /// </summary>\n    public static Relation relation(VectorClock<A> vc1, VectorClock<A> vc2)\n    {\n        return go(vc1.Entries, vc2.Entries);\n\n        static Relation go(Seq<(A, long)> es1, Seq<(A, long)> es2) =>\n            (es1.IsEmpty, es2.IsEmpty) switch\n            {\n                (false, false) => equals<OrdDefault<A>, A>(es1.Head.Value.Item1, es2.Head.Value.Item1)\n                                      ? es1.Head.Value.Item2 == es2.Head.Value.Item2\n                                            ? go(es1.Tail, es2.Tail)\n                                            : es1.Head.Value.Item2 < es2.Head.Value.Item2\n                                                ? checkCauses(es1.Tail, es2.Tail) ? LanguageExt.Relation.Causes : LanguageExt.Relation.Concurrent\n                                                : checkCauses(es2.Tail, es1.Tail)\n                                                    ? LanguageExt.Relation.CausedBy\n                                                    : LanguageExt.Relation.Concurrent\n                                      : lessThan<OrdDefault<A>, A>(es1.Head.Value.Item1, es2.Head.Value.Item1)\n                                          ? checkCauses(es2, es1.Tail) ? LanguageExt.Relation.CausedBy : LanguageExt.Relation.Concurrent\n                                          : greaterThan<OrdDefault<A>, A>(es1.Head.Value.Item1, es2.Head.Value.Item1)\n                                              ? checkCauses(es1, es2.Tail) ? LanguageExt.Relation.Causes : LanguageExt.Relation.Concurrent\n                                              : LanguageExt.Relation.Concurrent,\n                (true, _) => LanguageExt.Relation.Causes,\n                (_, true) => LanguageExt.Relation.CausedBy,\n            };\n\n        static bool checkCauses(Seq<(A, long)> es1, Seq<(A, long)> es2) =>\n            (es1.IsEmpty, es2.IsEmpty) switch\n            {\n                (false, false) => equals<OrdDefault<A>, A>(es1.Head.Value.Item1, es2.Head.Value.Item1)\n                                      ? es1.Head.Value.Item2 <= es2.Head.Value.Item2 && checkCauses(es1.Tail, es2.Tail)\n                                      : !lessThan<OrdDefault<A>, A>(es1.Head.Value.Item1, es2.Head.Value.Item1) &&\n                                        checkCauses(es1, es2.Tail),\n                (true, _) => true,\n                _         => false\n            };\n    }\n\n    /// <summary>\n    /// Short-hand for relation(vc1, vc2) == Relation.Causes\n    /// </summary>\n    public bool Causes(VectorClock<A> vc2) =>\n        causes(this, vc2);\n\n    /// <summary>\n    /// Short-hand for relation(vc1, vc2) == Relation.Causes\n    /// </summary>\n    public static bool causes(VectorClock<A> vc1, VectorClock<A> vc2) =>\n        relation(vc1, vc2) == LanguageExt.Relation.Causes;\n\n    /// <summary>\n    /// If vc2 causes vc1, compute the smallest vc3\n    /// </summary>\n    /// <remarks>Note that the /first/ parameter is the newer vector clock.</remarks>\n    public Option<VectorClock<A>> Diff(VectorClock<A> vc2) =>\n        diff(this, vc2);\n\n    /// <summary>\n    /// If vc2 causes vc1, compute the smallest vc3\n    /// </summary>\n    /// <remarks>Note that the /first/ parameter is the newer vector clock.</remarks>\n    public static Option<VectorClock<A>> diff(VectorClock<A> vc1, VectorClock<A> vc2)\n    {\n        return vc1 == vc2\n                   ? Some(Empty)\n                   : causes(vc2, vc1)\n                       ? Some(combine(diffOne, vc1, vc2))\n                       : None;\n\n        static Option<long> diffOne(A _, Option<long> ox, Option<long> oy) =>\n            (ox.Case, oy.Case) switch\n            {\n                (null, null)     => None,\n                (long x, null)   => Some(x),\n                (null, long)     => throw new InvalidOperationException(\"diff broken\"),\n                (long x, long y) => x == y ? None : Some(x),\n                _                => throw new InvalidOperationException(\"diff broken\")\n            };\n    }\n\n    bool? valid;\n    public bool Valid \n    {\n        get\n        {\n            if (valid.HasValue) return valid.Value;\n            var keys   = Entries.Map(e => e.Item1);\n            var sorted = keys.Sort<OrdDefault<A>, A>() == keys;\n            var distinct = Entries.Distinct<EqTuple2<OrdDefault<A>, TLong, A, long>, (A, long)>().Count ==\n                           Entries.Count;\n            valid = sorted && distinct;\n            return valid.Value;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VectorClock/VectorClock.OrdA.NumB.A.B.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Trait;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// <para>\n/// To create a vector clock, start from `Empty` or `Single` and `Insert`\n/// elements into it.  As a shortcut, `fromList` just inserts all the\n/// elements in a list, in order.\n/// </para>\n/// <code>\n///     var vc = VectorClock〈char〉.Empty;\n///     vc = vc.Insert('a', 1);\n///     vc = vc.Insert('b', 2);\n///     vc == VectorClock〈char〉.fromList(Seq(('a', 1), ('b', 2)))\n/// </code>\n/// <para>\n/// Note that, for different keys, the order of insertion does not\n/// matter:\n/// </para>\n/// <code>\n///     fromList(Seq(('a', 1), ('b', 2)) == fromList(Seq(('b', 2), ('a', 1))\n/// </code>\n/// <para>\n/// Once you have a given vector clock, you can 'lookup' its fields,\n/// check that keys are 'member's, or convert it back 'toList' form.\n/// </para>\n/// <code>\n///     vc.Lookup('a') == Some(1)\n///     vc.Lookup('c') == None\n/// </code>\n/// <para>\n/// The main operations that you would do with a vector clock are to\n/// increment the entry corresponding to the current process and to\n/// update the process's vector clock with the 'max' of its and the\n/// received message's clocks.\n/// </para>\n/// <code>\n///     vc.Inc('a') == Some [('a', 2), ('b', 2)]\n///     VectorClock.max( [('a', 1), ('b', 2)], [('c', 3), ('b', 1)] ) == [('a', 1), ('b', 2), ('c' 3)]\n/// </code>\n/// <para>\n/// Finally, upon receiving different messages, you may wish to\n/// discover the relationship, if any, between them.  This\n/// information could be useful in determining the correct order to\n/// process the messages.\n/// </para>\n/// <code>\n///     VectorClock.relation (fromList [('a', 1), ('b', 2)], fromList [('a', 2), ('b', 2)]) == Causes\n///     VectorClock.relation (fromList [('a', 2), ('b', 2)], fromList [('a', 1), ('b', 2)]) == CausedBy\n///     VectorClock.relation (fromList [('a', 2), ('b', 2)], fromList [('a', 1), ('b', 3)]) == Concurrent\n/// </code>\n/// <para>\n/// A vector clock is, conceptually, an associative list sorted by the\n/// value of the key, where each key appears only once.\n/// </para>\n/// </summary>\npublic record VectorClock<OrdA, NumB, A, B>(Seq<(A, B)> Entries)\n    where OrdA : Ord<A>\n    where NumB : Num<B>\n{\n    /// <summary>\n    /// Empty vector clock\n    /// </summary>\n    public static readonly VectorClock<OrdA, NumB, A, B> Empty = new(Seq<(A, B)>());\n\n    public virtual bool Equals(VectorClock<OrdA, NumB, A, B>? rhs) =>\n        rhs is not null                                                                      &&\n        GetHashCode() == rhs.GetHashCode()                                                   &&\n        Count         == rhs.Count                                                           &&\n        Entries.Zip(rhs.Entries).ForAll(p => equals<OrdA, A>(p.First.Item1, p.Second.Item1)) &&\n        Entries.Zip(rhs.Entries).ForAll(p => equals<NumB, B>(p.First.Item2, p.Second.Item2));\n\n    public override int GetHashCode() =>\n        Entries.GetHashCode();\n\n    /// <summary>\n    /// A vector clock with a single element\n    /// </summary>\n    public static VectorClock<OrdA, NumB, A, B> Single(A x, B y) =>\n        fromList(Seq((x, y)));\n\n    /// <summary>\n    /// Insert each entry in the list one at a time.\n    /// </summary>\n    public static VectorClock<OrdA, NumB, A, B> fromList(Seq<(A x, B y)> list) =>\n        list.Fold(Empty, (vc, pair) => vc.Insert(pair.x, pair.y));\n\n    /// <summary>\n    /// All the entries in the vector clock.  Note that this is /not/ the inverse of 'fromList'\n    /// </summary>\n    public Seq<(A x, B y)> ToList() =>\n        Entries;\n\n    /// <summary>\n    /// Is the vector clock empty?\n    /// </summary>\n    public bool IsEmpty =>\n        Entries.IsEmpty;\n\n    /// <summary>\n    /// The number of entries in the vector clock.\n    /// </summary>\n    public int Count =>\n        Entries.Count;\n\n    /// <summary>\n    /// Lookup the value for a key in the vector clock and remove the corresponding entry\n    /// </summary>\n    public (Option<B> Value, VectorClock<OrdA, NumB, A, B> Clock) Extract(A index)\n    {\n        Option<B> value = default;\n        return (value, new VectorClock<OrdA, NumB, A, B>(go(Entries)));\n\n        Seq<(A x, B y)> go(Seq<(A x, B y)> zs)\n        {\n            var res = Seq<(A x, B y)>.Empty;\n            foreach (var z in zs)\n            {\n                if (equals<OrdA, A>(z.x, index))\n                {\n                    value = z.y;\n                }\n                else\n                {\n                    res = res.Add(z);\n                }\n            }\n            return res;\n        }\n    }\n\n    /// <summary>\n    /// Lookup the value for a key in the vector clock.\n    /// </summary>\n    public Option<B> Lookup(A index)\n    {\n        foreach (var z in Entries)\n        {\n            if (equals<OrdA, A>(z.Item1, index)) return z.Item2;\n        }\n\n        return None;\n    }\n\n    /// <summary>\n    /// Is a member?\n    /// </summary>\n    public bool Contains(A index) =>\n        Lookup(index).IsSome;\n\n    /// <summary>\n    /// Delete\n    /// </summary>\n    public VectorClock<OrdA, NumB, A, B> Remove(A index) =>\n        new (Entries.Filter(e => !OrdA.Equals(e.Item1, index)).ToSeq());\n\n\n    /// <summary>\n    /// Insert or replace the entry for a key.\n    /// </summary>\n    public VectorClock<OrdA, NumB, A, B> Insert(A index, B value)\n    {\n        return new VectorClock<OrdA, NumB, A, B>(go(Entries));\n\n        Seq<(A, B)> go(Seq<(A, B)> entries) =>\n            entries.IsEmpty\n                ? Seq((index, value))\n                : entries.Head.Value switch\n                  {\n                      (var x1, _) xy when lessThan<OrdA, A>(x1, index) => xy.Cons(go(entries.Tail)),\n                      var (x1, _) when equals<OrdA, A>(x1, index)      => (index, value).Cons(entries.Tail),\n                      var xy                                           => (index, value).Cons(xy.Cons(entries.Tail))\n                  };\n    }\n\n    /// <summary>\n    /// Increment the entry for a key by 1\n    /// </summary>\n    public Option<VectorClock<OrdA, NumB, A, B>> Inc(A index) =>\n        Lookup(index).Map(y => Insert(index, plus<NumB, B>(y, fromInteger<NumB, B>(1))));\n\n    /// <summary>\n    /// Increment the entry for a key by 1\n    /// </summary>\n    public VectorClock<OrdA, NumB, A, B> Inc(A index, B defaultValue) =>\n        Lookup(index).Case switch\n        {\n            B y => Insert(index, plus<NumB, B>(y, fromInteger<NumB, B>(1))),\n            _   => Insert(index, plus<NumB, B>(defaultValue, fromInteger<NumB, B>(1))),\n        };\n\n    /// <summary>\n    /// Combine two vector clocks entry-by-entry\n    /// </summary>\n    /// <param name=\"f\">a function that takes the /key/, the value of the entry in\n    /// the left hand vector clock, if it exists, the value in the\n    /// right hand vector clock, if it exists, and, if it wishes to\n    /// keep a value for this /key/ in the resulting vector clock,\n    /// returns it.</param>\n    /// <param name=\"vc1\">the left hand vector clock</param>\n    /// <param name=\"vc2\">he right hand vector clock</param>\n    /// <returns></returns>\n    public static VectorClock<OrdA, NumB, A, B> combine(\n        Func<A, Option<B>, Option<B>, Option<B>> f,\n        VectorClock<OrdA, NumB, A, B> vc1,\n        VectorClock<OrdA, NumB, A, B> vc2)\n    {\n        return new VectorClock<OrdA, NumB, A, B>(go(vc1.Entries, vc2.Entries).Somes());\n            \n        Seq<Option<(A, B)>> go(Seq<(A, B)> es1, Seq<(A, B)> es2) =>\n            (es1.IsEmpty, es2.IsEmpty) switch\n            {\n                (true,  _) => es2.Map(xy => mk(xy.Item1, f(xy.Item1, None, Some(xy.Item2)))),\n                (_,  true) => es1.Map(xy => mk(xy.Item1, f(xy.Item1, Some(xy.Item2), None))),\n                _ => compare<OrdA, A>(es1.Head.Value.Item1, es2.Head.Value.Item1) switch\n                     {\n                         < 0 => mk(es1.Head.Value.Item1, f(es1.Head.Value.Item1, Some(es1.Head.Value.Item2), None)).Cons(go(es1.Tail, es2)),\n                         0   => mk(es1.Head.Value.Item1, f(es1.Head.Value.Item1, Some(es1.Head.Value.Item2), Some(es2.Head.Value.Item2))).Cons(go(es1.Tail, es2.Tail)),\n                         _   => mk(es2.Head.Value.Item1, f(es2.Head.Value.Item1, None, Some(es2.Head.Value.Item2))).Cons(go(es1, es2.Tail))\n                     }\n            };\n\n        static Option<(A, B)> mk(A x, Option<B> v) =>\n            v.Map(y => (x, y)); \n    }\n\n    /// <summary>\n    /// The maximum of the two vector clocks.\n    /// </summary>\n    public static VectorClock<OrdA, NumB, A, B> max(VectorClock<OrdA, NumB, A, B> vc1, VectorClock<OrdA, NumB, A, B> vc2)\n    {\n        return combine(maxEntry, vc1, vc2);\n\n        static Option<B> maxEntry(A _, Option<B> ea, Option<B> eb) =>\n            (ea.Case, eb.Case) switch\n            {\n                (null, null) => None,\n                (B x, null)  => Some(x),\n                (null, B y)  => Some(y),\n                (B x, B y)   => Some(Ord.max<NumB, B>(x, y)),\n                _            => None\n            };\n    }\n\n    /// <summary>\n    /// The relation between the two vector clocks.\n    /// </summary>\n    public Relation Relation(VectorClock<OrdA, NumB, A, B> vc1, VectorClock<OrdA, NumB, A, B> vc2) =>\n        relation(this, vc2);\n\n    /// <summary>\n    /// The relation between the two vector clocks.\n    /// </summary>\n    public static Relation relation(VectorClock<OrdA, NumB, A, B> vc1, VectorClock<OrdA, NumB, A, B> vc2)\n    {\n        return go(vc1.Entries, vc2.Entries);\n\n        static Relation go(Seq<(A, B)> es1, Seq<(A, B)> es2) =>\n            (es1.IsEmpty, es2.IsEmpty) switch\n            {\n                (false, false) => equals<OrdA, A>(es1.Head.Value.Item1, es2.Head.Value.Item1)\n                                      ? equals<NumB, B>(es1.Head.Value.Item2, es2.Head.Value.Item2)\n                                            ? go(es1.Tail, es2.Tail)\n                                            : lessThan<NumB, B>(es1.Head.Value.Item2, es2.Head.Value.Item2)\n                                                ? checkCauses(es1.Tail, es2.Tail) ? LanguageExt.Relation.Causes : LanguageExt.Relation.Concurrent\n                                                : checkCauses(es2.Tail, es1.Tail)\n                                                    ? LanguageExt.Relation.CausedBy\n                                                    : LanguageExt.Relation.Concurrent\n                                      : lessThan<OrdA, A>(es1.Head.Value.Item1, es2.Head.Value.Item1)\n                                          ? checkCauses(es2, es1.Tail) ? LanguageExt.Relation.CausedBy : LanguageExt.Relation.Concurrent\n                                          : greaterThan<OrdA, A>(es1.Head.Value.Item1, es2.Head.Value.Item1)\n                                              ? checkCauses(es1, es2.Tail) ? LanguageExt.Relation.Causes : LanguageExt.Relation.Concurrent\n                                              : LanguageExt.Relation.Concurrent,\n                (true, _) => LanguageExt.Relation.Causes,\n                (_, true) => LanguageExt.Relation.CausedBy\n            };\n\n        static bool checkCauses(Seq<(A, B)> es1, Seq<(A, B)> es2) =>\n            (es1.IsEmpty, es2.IsEmpty) switch\n            {\n                (false, false) => equals<OrdA, A>(es1.Head.Value.Item1, es2.Head.Value.Item1)\n                                      ? lessOrEq<NumB, B>(es1.Head.Value.Item2, es2.Head.Value.Item2)  && checkCauses(es1.Tail, es2.Tail)\n                                      : !lessThan<OrdA, A>(es1.Head.Value.Item1, es2.Head.Value.Item1) && checkCauses(es1, es2.Tail),\n                (true, _) => true,\n                _         => false\n            };\n    }\n\n    /// <summary>\n    /// Short-hand for relation(vc1, vc2) == Relation.Causes\n    /// </summary>\n    public bool Causes(VectorClock<OrdA, NumB, A, B> vc2) =>\n        causes(this, vc2);\n\n    /// <summary>\n    /// Short-hand for relation(vc1, vc2) == Relation.Causes\n    /// </summary>\n    public static bool causes(VectorClock<OrdA, NumB, A, B> vc1, VectorClock<OrdA, NumB, A, B> vc2) =>\n        relation(vc1, vc2) == LanguageExt.Relation.Causes;\n\n    /// <summary>\n    /// If vc2 causes vc1, compute the smallest vc3\n    /// </summary>\n    /// <remarks>Note that the /first/ parameter is the newer vector clock.</remarks>\n    public Option<VectorClock<OrdA, NumB, A, B>> Diff(VectorClock<OrdA, NumB, A, B> vc2) =>\n        diff(this, vc2);\n        \n    /// <summary>\n    /// If vc2 causes vc1, compute the smallest vc3\n    /// </summary>\n    /// <remarks>Note that the /first/ parameter is the newer vector clock.</remarks>\n    public static Option<VectorClock<OrdA, NumB, A, B>> diff(VectorClock<OrdA, NumB, A, B> vc1, VectorClock<OrdA, NumB, A, B> vc2)\n    {\n        return vc1 == vc2\n                   ? Some(Empty)\n                   : causes(vc2, vc1)\n                       ? Some(combine(diffOne, vc1, vc2))\n                       : None;\n\n        static Option<B> diffOne(A _, Option<B> ox, Option<B> oy) =>\n            (ox.Case, oy.Case) switch\n            {\n                (null, null) => None,\n                (B x, null)  => Some(x),\n                (null, B)    => throw new InvalidOperationException(\"diff broken\"),\n                (B x, B y)   => equals<NumB, B>(x, y) ? None : Some(x),\n                _            => None\n            };\n    }\n\n    bool? valid;\n    public bool Valid \n    { \n        get\n        {\n            if (valid.HasValue) return valid.Value;\n            var keys     = Entries.Map(e => e.Item1);\n            var sorted   = keys.Sort<OrdA, A>()                                         == keys;\n            var distinct = Entries.Distinct<EqTuple2<OrdA, NumB, A, B>, (A, B)>().Count == Entries.Count;\n            valid = sorted && distinct;\n            return valid.Value;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VectorClock/VectorClock.cs",
    "content": "#nullable enable\nusing System;\nusing System.Collections.Generic;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Trait;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// <para>\n    /// To create a vector clock, start from `Empty` or `Single` and `Insert`\n    /// elements into it.  As a shortcut, `fromList` just inserts all the\n    /// elements in a list, in order.\n    /// </para>\n    /// <code>\n    ///     var vc = VectorClock〈char〉.Empty;\n    ///     vc = vc.Insert('a', 1);\n    ///     vc = vc.Insert('b', 2);\n    ///     vc == VectorClock〈char〉.fromList(Seq(('a', 1), ('b', 2)))\n    /// </code>\n    /// <para>\n    /// Note that, for different keys, the order of insertion does not\n    /// matter:\n    /// </para>\n    /// <code>\n    ///     fromList(Seq(('a', 1), ('b', 2)) == fromList(Seq(('b', 2), ('a', 1))\n    /// </code>\n    /// <para>\n    /// Once you have a given vector clock, you can 'lookup' its fields,\n    /// check that keys are 'member's, or convert it back 'toList' form.\n    /// </para>\n    /// <code>\n    ///     vc.Lookup('a') == Some(1)\n    ///     vc.Lookup('c') == None\n    /// </code>\n    /// <para>\n    /// The main operations that you would do with a vector clock are to\n    /// increment the entry corresponding to the current process and to\n    /// update the process's vector clock with the 'max' of its and the\n    /// received message's clocks.\n    /// </para>\n    /// <code>\n    ///     vc.Inc('a') == Some [('a', 2), ('b', 2)]\n    ///     VectorClock.max( [('a', 1), ('b', 2)], [('c', 3), ('b', 1)] ) == [('a', 1), ('b', 2), ('c' 3)]\n    /// </code>\n    /// <para>\n    /// Finally, upon receiving different messages, you may wish to\n    /// discover the relationship, if any, between them.  This\n    /// information could be useful in determining the correct order to\n    /// process the messages.\n    /// </para>\n    /// <code>\n    ///     VectorClock.relation (fromList [('a', 1), ('b', 2)], fromList [('a', 2), ('b', 2)]) == Causes\n    ///     VectorClock.relation (fromList [('a', 2), ('b', 2)], fromList [('a', 1), ('b', 2)]) == CausedBy\n    ///     VectorClock.relation (fromList [('a', 2), ('b', 2)], fromList [('a', 1), ('b', 3)]) == Concurrent\n    /// </code>\n    /// <para>\n    /// A vector clock is, conceptually, an associative list sorted by the\n    /// value of the key, where each key appears only once.\n    /// </para>\n    /// </summary>\n    public static class VectorClock\n    {\n        /// <summary>\n        /// A vector clock with a single element\n        /// </summary>\n        public static VectorClock<A> Single<A>(A x, long y) where A : IComparable<A> =>\n            VectorClock<A>.Single(x, y);\n\n        /// <summary>\n        /// A vector clock with a single element\n        /// </summary>\n        public static VectorClock<OrdA, NumB, A, B> Single<OrdA, NumB, A, B>(A x, B y)\n            where OrdA : Ord<A>\n            where NumB : Num<B> =>\n            VectorClock<OrdA, NumB, A, B>.Single(x, y);\n\n        /// <summary>\n        /// Insert each entry in the list one at a time.\n        /// </summary>\n        public static VectorClock<A> fromList<A>(Seq<(A x, long y)> list) where A : IComparable<A> =>\n            VectorClock<A>.fromList(list);\n\n        /// <summary>\n        /// Insert each entry in the list one at a time.\n        /// </summary>\n        public static VectorClock<OrdA, NumB, A, B> fromList<OrdA, NumB, A, B>(Seq<(A x, B y)> list) \n            where OrdA : Ord<A>\n            where NumB : Num<B> =>\n            VectorClock<OrdA, NumB, A, B>.fromList(list);\n\n        /// <summary>\n        /// Combine two vector clocks entry-by-entry\n        /// </summary>\n        /// <param name=\"f\">a function that takes the /key/, the value of the entry in\n        /// the left hand vector clock, if it exists, the value in the\n        /// right hand vector clock, if it exists, and, if it wishes to\n        /// keep a value for this /key/ in the resulting vector clock,\n        /// returns it.</param>\n        /// <param name=\"vc1\">the left hand vector clock</param>\n        /// <param name=\"vc2\">he right hand vector clock</param>\n        /// <returns></returns>\n        public static VectorClock<A> combine<A>(\n            Func<A, Option<long>, Option<long>, Option<long>> f,\n            VectorClock<A> vc1,\n            VectorClock<A> vc2) where A : IComparable<A> =>\n            VectorClock<A>.combine(f, vc1, vc2);\n\n        /// <summary>\n        /// Combine two vector clocks entry-by-entry\n        /// </summary>\n        /// <param name=\"f\">a function that takes the /key/, the value of the entry in\n        /// the left hand vector clock, if it exists, the value in the\n        /// right hand vector clock, if it exists, and, if it wishes to\n        /// keep a value for this /key/ in the resulting vector clock,\n        /// returns it.</param>\n        /// <param name=\"vc1\">the left hand vector clock</param>\n        /// <param name=\"vc2\">he right hand vector clock</param>\n        /// <returns></returns>\n        public static VectorClock<OrdA, NumB, A, B> combine<OrdA, NumB, A, B>(\n            Func<A, Option<B>, Option<B>, Option<B>> f,\n            VectorClock<OrdA, NumB, A, B> vc1,\n            VectorClock<OrdA, NumB, A, B> vc2)\n            where OrdA : Ord<A>\n            where NumB : Num<B> =>\n            VectorClock<OrdA, NumB, A, B>.combine(f, vc1, vc2);\n\n        /// <summary>\n        /// The maximum of the two vector clocks.\n        /// </summary>\n        public static VectorClock<A> max<A>(VectorClock<A> vc1, VectorClock<A> vc2)\n            where A : IComparable<A> =>\n            VectorClock<A>.max(vc1, vc2);\n\n        /// <summary>\n        /// The maximum of the two vector clocks.\n        /// </summary>\n        public static VectorClock<OrdA, NumB, A, B> max<OrdA, NumB, A, B>(VectorClock<OrdA, NumB, A, B> vc1, VectorClock<OrdA, NumB, A, B> vc2)\n            where OrdA : Ord<A>\n            where NumB : Num<B> =>\n            VectorClock<OrdA, NumB, A, B>.max(vc1, vc2);\n\n        /// <summary>\n        /// The relation between the two vector clocks.\n        /// </summary>\n        public static Relation relation<A>(VectorClock<A> vc1, VectorClock<A> vc2)\n            where A : IComparable<A> =>\n            VectorClock<A>.relation(vc1, vc2);\n\n        /// <summary>\n        /// The relation between the two vector clocks.\n        /// </summary>\n        public static Relation relation<OrdA, NumB, A, B>(VectorClock<OrdA, NumB, A, B> vc1, VectorClock<OrdA, NumB, A, B> vc2)\n            where OrdA : Ord<A>\n            where NumB : Num<B> =>\n            VectorClock<OrdA, NumB, A, B>.relation(vc1, vc2);\n\n        /// <summary>\n        /// Short-hand for relation(vc1, vc2) == Relation.Causes\n        /// </summary>\n        public static bool causes<A>(VectorClock<A> vc1, VectorClock<A> vc2)\n            where A : IComparable<A> =>\n            VectorClock<A>.causes(vc1, vc2);\n\n        /// <summary>\n        /// Short-hand for relation(vc1, vc2) == Relation.Causes\n        /// </summary>\n        public static bool causes<OrdA, NumB, A, B>(VectorClock<OrdA, NumB, A, B>vc1, VectorClock<OrdA, NumB, A, B> vc2)\n            where OrdA : Ord<A>\n            where NumB : Num<B> =>\n            VectorClock<OrdA, NumB, A, B>.causes(vc1, vc2);\n\n        /// <summary>\n        /// If vc2 causes vc1, compute the smallest vc3\n        /// </summary>\n        /// <remarks>Note that the /first/ parameter is the newer vector clock.</remarks>\n        public static Option<VectorClock<A>> diff<A>(VectorClock<A> vc1, VectorClock<A> vc2)\n            where A : IComparable<A> =>\n            VectorClock<A>.diff(vc1, vc2);\n\n        /// <summary>\n        /// If vc2 causes vc1, compute the smallest vc3\n        /// </summary>\n        /// <remarks>Note that the /first/ parameter is the newer vector clock.</remarks>\n        public static Option<VectorClock<OrdA, NumB, A, B>> diff<OrdA, NumB, A, B>(VectorClock<OrdA, NumB, A, B> vc1, VectorClock<OrdA, NumB, A, B> vc2)\n            where OrdA : Ord<A>\n            where NumB : Num<B> =>\n            VectorClock<OrdA, NumB, A, B>.diff(vc1, vc2);\n    }\n}\n#nullable disable\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VersionHashMap/VersionHashMap.ConflictV.K.V.cs",
    "content": "using System;\nusing System.Collections;\nusing LanguageExt.ClassInstances;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// <para>\n/// Versioned hash-map.  Each value has a vector-clock attached to it which understands the causality of updates\n/// from multiple actors.  Actors are just unique keys that represent individual contributors.  They could be client\n/// connections, nodes in a network, users, or whatever is appropriate to discriminate between commits.\n/// </para>\n/// <para>\n/// Deleted items are not removed from the hash-map, they are merely marked as deleted.  This allows conflicts between\n/// writes and deletes to be resolved.  \n/// </para>\n/// <para>\n/// Run `RemoveDeletedItemsOlderThan` to clean up items that have been deleted and are now just hanging around.  Use\n/// a big enough delay that it won't conflict with other commits (this could be seconds, minutes, or longer:\n/// depending on the expected latency of writes to the hash-map).\n/// </para>\n/// <para>\n/// This is a mutable collection with atomic, thread-safe, updates.\n/// </para>\n/// </summary>\npublic class VersionHashMap<ConflictV, K, V> :\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<VersionHashMap<ConflictV, K, V>>\n    where ConflictV : Conflict<V>\n{\n    readonly VersionHashMap<ConflictV, TString, EqDefault<K>, string, K, V> Items;\n\n    /// <summary>\n    /// Empty version map\n    /// </summary>\n    public static VersionHashMap<ConflictV, K, V> Empty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new VersionHashMap<ConflictV, K, V>(VersionHashMap<ConflictV, TString, EqDefault<K>, string, K, V>.Empty);\n    }\n        \n    /// <summary>\n    /// Constructor\n    /// </summary>\n    /// <param name=\"items\">Trie map</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    VersionHashMap(VersionHashMap<ConflictV, TString, EqDefault<K>, string, K, V> items) =>\n        this.Items = items;\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Version - this may be in a state of never existing, but won't ever fail</returns>\n    [Pure]\n    public Version<string, K, V> this[K key]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.FindVersion(key);\n    }\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.IsEmpty;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Count;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Count;\n    }\n\n    /// <summary>\n    /// Atomically swap a key in the map.  Allows for multiple operations on the hash-map in an entirely\n    /// transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of the value associated with the key to a new state</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit SwapKey(K key, Func<Version<string, K, V>, Version<string, K, V>> swap) =>\n        Items.SwapKey(key, swap);\n\n    /// <summary>\n    /// Atomically updates a new item in the map.  If the key already exists, then the vector clocks, within the version\n    /// vector, are compared to ascertain if the proposed version was caused-by, causes, or conflicts with the current\n    /// version:\n    ///\n    ///     * If the proposed version was caused-by the current version, then it is ignored.\n    ///     * If the proposed version causes the current version, then it is accepted and updated as the latest version\n    ///     * If the proposed version is in conflict with the current version, then values from both versions are\n    ///       passed to ConflictV.Append(v1, v2) for value resolution, and the pairwise-maximum of the two vector-clocks\n    ///       is taken to be the new 'time.\n    /// \n    /// </summary>\n    /// <param name=\"version\">Version to update</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Update(Version<string, K, V> version) =>\n        Items.Update(version);\n\n    /// <summary>\n    /// Remove items that are older than the specified time-stamp\n    /// </summary>\n    /// <param name=\"cutoff\">Cut off time-stamp</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit RemoveOlderThan(DateTime cutoff) =>\n        Items.RemoveOlderThan(cutoff);\n\n    /// <summary>\n    /// Remove items that are older than the specified time-stamp\n    /// </summary>\n    /// <param name=\"timeStamp\">Cut off time-stamp</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit RemoveOlderThan(long timeStamp) =>\n        Items.RemoveOlderThan(timeStamp);\n\n    /// <summary>\n    /// Remove deleted items that are older than the specified time-stamp\n    /// </summary>\n    /// <param name=\"cutoff\">Cut off time-stamp</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit RemoveDeletedItemsOlderThan(DateTime cutoff) =>\n        Items.RemoveDeletedItemsOlderThan(cutoff);\n\n    /// <summary>\n    /// Remove deleted items that are older than the specified time-stamp\n    /// </summary>\n    /// <param name=\"timeStamp\">Cut off time-stamp</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit RemoveDeletedItemsOlderThan(long timeStamp) =>\n        Items.RemoveDeletedItemsOlderThan(timeStamp);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<V> Find(K value) =>\n        Items.Find(value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Version<string, K, V> FindVersion(K value) =>\n        Items.FindVersion(value);\n\n    /// <summary>\n    /// Enumerable of keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Keys;\n    }\n\n    /// <summary>\n    /// Enumerable of value\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Values;\n    }\n\n    /// <summary>\n    /// Convert to a HashMap\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> ToHashMap() =>\n        Items.ToHashMap();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Items.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Items.GetEnumerator();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        Items.ToSeq();\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        Items.ToString();\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullString(string separator = \", \") =>\n        Items.ToFullString(separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullArrayString(string separator = \", \") =>\n        Items.ToFullArrayString(separator);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K Key, V Value)> AsIterable() =>\n        Items.AsIterable();\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSubsetOf(IEnumerable<K> other) =>\n        Items.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSupersetOf(IEnumerable<K> other) =>\n        Items.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(IEnumerable<K> other) =>\n        Items.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(HashMap<K, V> other) =>\n        Items.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Items.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSupersetOf(IEnumerable<K> rhs) =>\n        Items.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Intersect(IEnumerable<K> rhs) =>\n        Items.Intersect(rhs);\n        \n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        Items.Overlaps(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Overlaps(IEnumerable<K> other) =>\n        Items.Overlaps(other);\n\n    /// <summary>\n    /// Returns this - rhs.  Only the items in this that are not in \n    /// rhs will be returned.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Except(IEnumerable<K> rhs) =>\n        Items.Except(rhs);\n        \n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is VersionHashMap<ConflictV, K, V> hm && Equals(hm);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(VersionHashMap<ConflictV, K, V>? other) =>\n        other is not null && Items.Equals(other.Items);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        Items.GetHashCode();\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public VersionHashMap<ConflictV, K, V> Where(Func<long, Option<V>, bool> pred) =>\n        new VersionHashMap<ConflictV, K, V>(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public VersionHashMap<ConflictV, K, V> Where(Func<K, long, Option<V>, bool> pred) =>\n        new VersionHashMap<ConflictV, K, V>(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public VersionHashMap<ConflictV, K, V> Filter(Func<long, Option<V>, bool> pred) =>\n        new VersionHashMap<ConflictV, K, V>(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public VersionHashMap<ConflictV, K, V> Filter(Func<K, long, Option<V>, bool> pred) =>\n        new VersionHashMap<ConflictV, K, V>(Items.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit FilterInPlace(Func<long, Option<V>, bool> pred) =>\n        Items.FilterInPlace(pred);\n        \n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit FilterInPlace(Func<K, long, Option<V>, bool> pred) =>\n        Items.FilterInPlace(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<K, V, bool> pred) =>\n        Items.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        Items.ForAll(pred);\n\n    /// <summary>\n    /// Return true if *all* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<KeyValuePair<K, V>, bool> pred) =>\n        Items.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<V, bool> pred) =>\n        Items.ForAll(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<K, V, bool> pred) =>\n        Items.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<(K Key, V Value), bool> pred) =>\n        Items.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<V, bool> pred) =>\n        Items.Exists(pred);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<K, V> action) =>\n        Items.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<V> action) =>\n        Items.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<(K Key, V Value)> action) =>\n        Items.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<KeyValuePair<K, V>> action) =>\n        Items.Iter(action);\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        Items.Fold(state, folder);\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, V, S> folder) =>\n        Items.Fold(state, folder);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VersionHashMap/VersionHashMap.ConflictV.OrdActor.EqK.Actor.K.V.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Collections;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// <para>\n/// Versioned hash-map.  Each value has a vector-clock attached to it which understands the causality of updates\n/// from multiple actors.  Actors are just unique keys that represent individual contributors.  They could be client\n/// connections, nodes in a network, users, or whatever is appropriate to discriminate between commits.\n/// </para>\n/// <para>\n/// Deleted items are not removed from the hash-map, they are merely marked as deleted.  This allows conflicts between\n/// writes and deletes to be resolved.\n/// </para> \n/// <para>\n/// Run `RemoveDeletedItemsOlderThan` to clean up items that have been deleted and are now just hanging around.  Use\n/// a big enough delay that it won't conflict with other commits (this could be seconds, minutes, or longer:\n/// depending on the expected latency of writes to the hash-map).\n/// </para>\n/// <para>\n/// This is a mutable collection with atomic, thread-safe, updates.\n/// </para>\n/// </summary>\npublic class VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V> :\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V>>\n    where OrdActor  : Ord<Actor>\n    where EqK       : Eq<K>\n    where ConflictV : Conflict<V>\n{\n    internal volatile TrieMap<EqK, K, VersionVector<ConflictV, OrdActor, TLong, Actor, long, V>> Items;\n\n    /// <summary>\n    /// Empty version map\n    /// </summary>\n    public static VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V> Empty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new (TrieMap<EqK, K, VersionVector<ConflictV, OrdActor, TLong, Actor, long, V>>.Empty);\n    }\n        \n    /// <summary>\n    /// Constructor\n    /// </summary>\n    /// <param name=\"items\">Trie map</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    VersionHashMap(TrieMap<EqK, K, VersionVector<ConflictV, OrdActor, TLong, Actor, long, V>> items) =>\n        Items = items;\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Version - this may be in a state of never existing, but won't ever fail</returns>\n    [Pure]\n    public Version<Actor, K, V> this[K key]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => FindVersion(key);\n    }\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.IsEmpty;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Count;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Items.Count;\n    }\n        \n    /// <summary>\n    /// Atomically swap a key in the map.  Allows for multiple operations on the hash-map in an entirely\n    /// transactional and atomic way.\n    /// </summary>\n    /// <param name=\"swap\">Swap function, maps the current state of the value associated with the key to a new state</param>\n    /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n    /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n    /// behaviours as possible to avoid repeated attempts</remarks>\n    public Unit SwapKey(K key, Func<Version<Actor, K, V>, Version<Actor, K, V>> swap)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var okey = oitems.Find(key)\n                             .Map(v => v.ToVersion(key))\n                             .IfNone(() => VersionNeverExistedVector<ConflictV, OrdActor, Actor, K, V>.New(key));\n                \n            var nversion = swap(okey);\n\n            var nitems = oitems.AddOrMaybeUpdate(key,\n                                                 exists => exists.Put(nversion.ToVector<ConflictV, OrdActor, Actor, K, V>()!),\n                                                 () => Optional(nversion.ToVector<ConflictV, OrdActor, Actor, K, V>()));\n                \n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n                \n    /// <summary>\n    /// Atomically updates a new item in the map.  If the key already exists, then the vector clocks, within the version\n    /// vector, are compared to ascertain if the proposed version was caused-by, causes, or conflicts with the current\n    /// version:\n    ///\n    ///     * If the proposed version was caused-by the current version, then it is ignored.\n    ///     * If the proposed version causes the current version, then it is accepted and updated as the latest version\n    ///     * If the proposed version is in conflict with the current version, then values from both versions are\n    ///       passed to ConflictV.Append(v1, v2) for value resolution, and the pairwise-maximum of the two vector-clocks\n    ///       is taken to be the new 'time.\n    /// \n    /// </summary>\n    /// <param name=\"version\">Version to update</param>\n    public Unit Update(Version<Actor, K, V> nversion)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var nitems = oitems.AddOrMaybeUpdate(nversion.Key,\n                                                 exists => exists.Put(nversion.ToVector<ConflictV, OrdActor, Actor, K, V>()!),\n                                                 () => Optional(nversion.ToVector<ConflictV, OrdActor, Actor, K, V>()));\n                \n            if(ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Remove items that are older than the specified time-stamp\n    /// </summary>\n    /// <param name=\"cutoff\">Cut off time-stamp</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit RemoveOlderThan(DateTime cutoff) =>\n        RemoveOlderThan(cutoff.ToUniversalTime().Ticks);\n\n    /// <summary>\n    /// Remove items that are older than the specified time-stamp\n    /// </summary>\n    /// <param name=\"timeStamp\">Cut off time-stamp</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit RemoveOlderThan(long timeStamp) =>\n        FilterInPlace((ts, _) => ts > timeStamp);\n\n    /// <summary>\n    /// Remove deleted items that are older than the specified time-stamp\n    /// </summary>\n    /// <param name=\"cutoff\">Cut off time-stamp</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit RemoveDeletedItemsOlderThan(DateTime cutoff) =>\n        RemoveDeletedItemsOlderThan(cutoff.ToUniversalTime().Ticks);\n\n    /// <summary>\n    /// Remove deleted items that are older than the specified time-stamp\n    /// </summary>\n    /// <param name=\"timeStamp\">Cut off time-stamp</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit RemoveDeletedItemsOlderThan(long timeStamp) =>\n        FilterInPlace((ts, v) => v.IsSome || ts > timeStamp);\n        \n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<V> Find(K value) =>\n        Items.Find(value).Bind(static v => v.Value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Version<Actor, K, V> FindVersion(K key) =>\n        Items.Find(key).Match(\n            Some: v => v.ToVersion(key),\n            None: () => VersionNeverExistedVector<ConflictV, OrdActor, Actor, K, V>.New(key));\n\n    /// <summary>\n    /// Enumerable of keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => AsIterable().Map(static x => x.Key);\n    }\n\n    /// <summary>\n    /// Enumerable of value\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => AsIterable().Map(static x => x.Value);\n    }\n\n    /// <summary>\n    /// Convert to a HashMap\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> ToHashMap() =>\n        Items.AsIterable().Choose(static x => x.Value.Value.Map(v => (x.Key, v))).ToHashMap();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        Items.AsIterable().Choose(static x => x.Value.Value.Map(v => (x.Key, v))).GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Items.GetEnumerator();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        toSeq(AsIterable());\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K Key, V Value)> AsIterable() =>\n        Items.AsIterable().Choose(static x => x.Value.Value.Map(v => (x.Key, v)));\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        ToHashMap().IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSubsetOf(IEnumerable<K> other) =>\n        Items.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        ToHashMap().IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSupersetOf(IEnumerable<K> other) =>\n        Items.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        ToHashMap().IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(IEnumerable<K> other) =>\n        Items.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(HashMap<K, V> other) =>\n        ToHashMap().IsSubsetOf(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        ToHashMap().IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSupersetOf(IEnumerable<K> rhs) =>\n        Items.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public Unit Intersect(IEnumerable<K> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);            \n        while (true)\n        {\n            var oitems = this.Items;\n            var nitems = this.Items.Intersect(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        ToHashMap().Overlaps(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Overlaps(IEnumerable<K> other) =>\n        ToHashMap().Overlaps(other);\n\n    /// <summary>\n    /// Returns this - rhs.  Only the items in this that are not in \n    /// rhs will be returned.\n    /// </summary>\n    public Unit Except(IEnumerable<K> rhs)\n    {\n        SpinWait sw   = default;\n        var      srhs = toSeq(rhs);            \n        while (true)\n        {\n            var oitems = this.Items;\n            var nitems = this.Items.Except(srhs);\n            if (ReferenceEquals(Interlocked.CompareExchange(ref this.Items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V> hm && Equals(hm);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V>? other) =>\n        other is not null && Items.Equals(other.Items);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        Items.GetHashCode();\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V> Where(Func<long, Option<V>, bool> pred) =>\n        new (Items.Filter(v => pred(v.TimeStamp, v.Value)));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V> Where(Func<K, long, Option<V>, bool> pred) =>\n        new VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V>(Items.Filter((k, v) => pred(k, v.TimeStamp, v.Value)));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V> Filter(Func<long, Option<V>, bool> pred) =>\n        new VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V>(Items.Filter(v => pred(v.TimeStamp, v.Value)));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V> Filter(Func<K, long, Option<V>, bool> pred) =>\n        new VersionHashMap<ConflictV, OrdActor, EqK, Actor, K, V>(Items.Filter((k, v) => pred(k, v.TimeStamp, v.Value)));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    public Unit FilterInPlace(Func<long, Option<V>, bool> pred)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var nitems = oitems.Filter(v => pred(v.TimeStamp, v.Value));\n\n            if (ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    public Unit FilterInPlace(Func<K, long, Option<V>, bool> pred)\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            var oitems = Items;\n            var nitems = oitems.Filter((k, v) => pred(k, v.TimeStamp, v.Value));\n\n            if (ReferenceEquals(oitems, nitems))\n            {\n                // no change\n                return default;\n            }\n\n            if (ReferenceEquals(Interlocked.CompareExchange(ref Items, nitems, oitems), oitems))\n            {\n                return default;\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<K, V, bool> pred)\n    {\n        foreach (var (key, value) in AsIterable())\n        {\n            if (!pred(key, value)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        AsIterable().Map(kv => (kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if *all* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<KeyValuePair<K, V>, bool> pred) =>\n        AsIterable().Map(kv => new KeyValuePair<K, V>(kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<V, bool> pred) =>\n        AsIterable().Map(static x => x.Value).ForAll(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<K, V, bool> pred)\n    {\n        foreach (var (key, value) in AsIterable())\n        {\n            if (pred(key, value)) return true;\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<(K Key, V Value), bool> pred) =>\n        AsIterable().Map(kv => (kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<V, bool> pred) =>\n        AsIterable().Map(static x => x.Value).Exists(pred);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<K, V> action)\n    {\n        foreach (var (key, value) in this)\n        {\n            action(key, value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<(K Key, V Value)> action)\n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<KeyValuePair<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new KeyValuePair<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        AsIterable().Fold(state, (s, x) => folder(s, x.Key, x.Value));\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, V, S> folder) =>\n        AsIterable().Map(static x => x.Value).Fold(state, folder);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VersionHashMap/VersionHashMap.K.V.cs",
    "content": "using System;\nusing System.Collections;\nusing LanguageExt.ClassInstances;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// <para>\n    /// Versioned hash-map.  Each value has a vector-clock attached to it which understands the causality of updates\n    /// from multiple actors.  Actors are just unique keys that represent individual contributors.  They could be client\n    /// connections, nodes in a network, users, or whatever is appropriate to discriminate between commits.\n    /// </para>\n    /// <para>\n    /// Deleted items are not removed from the hash-map, they are merely marked as deleted.  This allows conflicts between\n    /// writes and deletes to be resolved.\n    /// </para> \n    /// <para>\n    /// Run `RemoveDeletedItemsOlderThan` to clean up items that have been deleted and are now just hanging around.  Use\n    /// a big enough delay that it won't conflict with other commits (this could be seconds, minutes, or longer:\n    /// depending on the expected latency of writes to the hash-map).\n    /// </para>\n    /// <para>\n    /// This is a mutable collection with atomic, thread-safe, updates.\n    /// </para>\n    /// </summary>\n    public class VersionHashMap<K, V> :\n        IEnumerable<(K Key, V Value)>,\n        IEquatable<VersionHashMap<K, V>>\n    {\n        readonly VersionHashMap<LastWriteWins<V>, TString, EqDefault<K>, string, K, V> Items;\n\n        /// <summary>\n        /// Empty version map\n        /// </summary>\n        public static VersionHashMap<K, V> Empty\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => new VersionHashMap<K, V>(VersionHashMap<LastWriteWins<V>, TString, EqDefault<K>, string, K, V>.Empty);\n        }\n        \n        /// <summary>\n        /// Constructor\n        /// </summary>\n        /// <param name=\"items\">Trie map</param>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        VersionHashMap(VersionHashMap<LastWriteWins<V>, TString, EqDefault<K>, string, K, V> items) =>\n            this.Items = items;\n\n        /// <summary>\n        /// 'this' accessor\n        /// </summary>\n        /// <param name=\"key\">Key</param>\n        /// <returns>Version - this may be in a state of never existing, but won't ever fail</returns>\n        [Pure]\n        public Version<string, K, V> this[K key]\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => Items.FindVersion(key);\n        }\n\n        /// <summary>\n        /// Is the map empty\n        /// </summary>\n        [Pure]\n        public bool IsEmpty\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => Items.IsEmpty;\n        }\n\n        /// <summary>\n        /// Number of items in the map\n        /// </summary>\n        [Pure]\n        public int Count\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => Items.Count;\n        }\n\n        /// <summary>\n        /// Alias of Count\n        /// </summary>\n        [Pure]\n        public int Length\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => Items.Count;\n        }\n\n        /// <summary>\n        /// Atomically swap a key in the map.  Allows for multiple operations on the hash-map in an entirely\n        /// transactional and atomic way.\n        /// </summary>\n        /// <param name=\"swap\">Swap function, maps the current state of the value associated with the key to a new state</param>\n        /// <remarks>Any functions passed as arguments may be run multiple times if there are multiple threads competing\n        /// to update this data structure.  Therefore the functions must spend as little time performing the injected\n        /// behaviours as possible to avoid repeated attempts</remarks>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit SwapKey(K key, Func<Version<string, K, V>, Version<string, K, V>> swap) =>\n            Items.SwapKey(key, swap);\n\n        /// <summary>\n        /// Atomically updates a new item in the map.  If the key already exists, then the vector clocks, within the version\n        /// vector, are compared to ascertain if the proposed version was caused-by, causes, or conflicts with the current\n        /// version:\n        ///\n        ///     * If the proposed version was caused-by the current version, then it is ignored.\n        ///     * If the proposed version causes the current version, then it is accepted and updated as the latest version\n        ///     * If the proposed version is in conflict with the current version, then values from both versions are\n        ///       passed to ConflictV.Append(v1, v2) for value resolution, and the pairwise-maximum of the two vector-clocks\n        ///       is taken to be the new 'time.\n        /// \n        /// </summary>\n        /// <param name=\"version\">Version to update</param>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit Update(Version<string, K, V> version) =>\n            Items.Update(version);\n\n        /// <summary>\n        /// Remove items that are older than the specified time-stamp\n        /// </summary>\n        /// <param name=\"cutoff\">Cut off time-stamp</param>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit RemoveOlderThan(DateTime cutoff) =>\n            Items.RemoveOlderThan(cutoff);\n\n        /// <summary>\n        /// Remove items that are older than the specified time-stamp\n        /// </summary>\n        /// <param name=\"timeStamp\">Cut off time-stamp</param>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit RemoveOlderThan(long timeStamp) =>\n            Items.RemoveOlderThan(timeStamp);\n\n        /// <summary>\n        /// Remove deleted items that are older than the specified time-stamp\n        /// </summary>\n        /// <param name=\"cutoff\">Cut off time-stamp</param>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit RemoveDeletedItemsOlderThan(DateTime cutoff) =>\n            Items.RemoveDeletedItemsOlderThan(cutoff);\n\n        /// <summary>\n        /// Remove deleted items that are older than the specified time-stamp\n        /// </summary>\n        /// <param name=\"timeStamp\">Cut off time-stamp</param>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit RemoveDeletedItemsOlderThan(long timeStamp) =>\n            Items.RemoveDeletedItemsOlderThan(timeStamp);\n\n        /// <summary>\n        /// Retrieve a value from the map by key\n        /// </summary>\n        /// <param name=\"key\">Key to find</param>\n        /// <returns>Found value</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Option<V> Find(K value) =>\n            Items.Find(value);\n\n        /// <summary>\n        /// Retrieve a value from the map by key\n        /// </summary>\n        /// <param name=\"key\">Key to find</param>\n        /// <returns>Found value</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Version<string, K, V> FindVersion(K value) =>\n            Items.FindVersion(value);\n\n        /// <summary>\n        /// Enumerable of keys\n        /// </summary>\n        [Pure]\n        public Iterable<K> Keys\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => Items.Keys;\n        }\n\n        /// <summary>\n        /// Enumerable of value\n        /// </summary>\n        [Pure]\n        public Iterable<V> Values\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => Items.Values;\n        }\n\n        /// <summary>\n        /// Convert to a HashMap\n        /// </summary>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public HashMap<K, V> ToHashMap() =>\n            Items.ToHashMap();\n\n        /// <summary>\n        /// GetEnumerator - IEnumerable interface\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n            Items.GetEnumerator();\n\n        /// <summary>\n        /// GetEnumerator - IEnumerable interface\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        IEnumerator IEnumerable.GetEnumerator() =>\n            Items.GetEnumerator();\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Seq<(K Key, V Value)> ToSeq() =>\n            Items.ToSeq();\n\n        /// <summary>\n        /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n        /// The ellipsis is used for collections over 50 items\n        /// To get a formatted string with all the items, use `ToFullString`\n        /// or `ToFullArrayString`.\n        /// </summary>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public override string ToString() =>\n            Items.ToString();\n\n        /// <summary>\n        /// Format the collection as `(key: value), (key: value), (key: value), ...`\n        /// </summary>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public string ToFullString(string separator = \", \") =>\n            Items.ToFullString(separator);\n\n        /// <summary>\n        /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n        /// </summary>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public string ToFullArrayString(string separator = \", \") =>\n            Items.ToFullArrayString(separator);\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Iterable<(K Key, V Value)> AsIterable() =>\n            Items.AsIterable();\n\n        /// <summary>\n        /// Returns True if 'other' is a proper subset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a proper subset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n            Items.IsProperSubsetOf(other);\n\n        /// <summary>\n        /// Returns True if 'other' is a proper subset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a proper subset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsProperSubsetOf(IEnumerable<K> other) =>\n            Items.IsProperSubsetOf(other);\n\n        /// <summary>\n        /// Returns True if 'other' is a proper superset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a proper superset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n            Items.IsProperSupersetOf(other);\n\n        /// <summary>\n        /// Returns True if 'other' is a proper superset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a proper superset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsProperSupersetOf(IEnumerable<K> other) =>\n            Items.IsProperSupersetOf(other);\n\n        /// <summary>\n        /// Returns True if 'other' is a superset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a superset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n            Items.IsSubsetOf(other);\n\n        /// <summary>\n        /// Returns True if 'other' is a superset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a superset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsSubsetOf(IEnumerable<K> other) =>\n            Items.IsSubsetOf(other);\n\n        /// <summary>\n        /// Returns True if 'other' is a superset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a superset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsSubsetOf(HashMap<K, V> other) =>\n            Items.IsSubsetOf(other);\n\n        /// <summary>\n        /// Returns True if 'other' is a superset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a superset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n            Items.IsSupersetOf(other);\n\n        /// <summary>\n        /// Returns True if 'other' is a superset of this set\n        /// </summary>\n        /// <returns>True if 'other' is a superset of this set</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool IsSupersetOf(IEnumerable<K> rhs) =>\n            Items.IsSupersetOf(rhs);\n\n        /// <summary>\n        /// Returns the elements that are in both this and other\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit Intersect(IEnumerable<K> rhs) =>\n            Items.Intersect(rhs);\n        \n        /// <summary>\n        /// Returns True if other overlaps this set\n        /// </summary>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n            Items.Overlaps(other);\n\n        /// <summary>\n        /// Returns True if other overlaps this set\n        /// </summary>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool Overlaps(IEnumerable<K> other) =>\n            Items.Overlaps(other);\n\n        /// <summary>\n        /// Returns this - rhs.  Only the items in this that are not in \n        /// rhs will be returned.\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit Except(IEnumerable<K> rhs) =>\n            Items.Except(rhs);\n        \n        /// <summary>\n        /// Equality of keys and values with `EqDefault〈V〉` used for values\n        /// </summary>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public override bool Equals(object? obj) =>\n            obj is VersionHashMap<K, V> hm && Equals(hm);\n\n        /// <summary>\n        /// Equality of keys and values with `EqDefault〈V〉` used for values\n        /// </summary>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool Equals(VersionHashMap<K, V>? other) =>\n            other is not null && Items.Equals(other.Items);\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public override int GetHashCode() =>\n            Items.GetHashCode();\n\n        /// <summary>\n        /// Atomically filter out items that return false when a predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>New map with items filtered</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public VersionHashMap<K, V> Where(Func<long, Option<V>, bool> pred) =>\n            new VersionHashMap<K, V>(Items.Filter(pred));\n\n        /// <summary>\n        /// Atomically filter out items that return false when a predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>New map with items filtered</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public VersionHashMap<K, V> Where(Func<K, long, Option<V>, bool> pred) =>\n            new VersionHashMap<K, V>(Items.Filter(pred));\n\n        /// <summary>\n        /// Atomically filter out items that return false when a predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>New map with items filtered</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public VersionHashMap<K, V> Filter(Func<long, Option<V>, bool> pred) =>\n            new VersionHashMap<K, V>(Items.Filter(pred));\n\n        /// <summary>\n        /// Atomically filter out items that return false when a predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>New map with items filtered</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public VersionHashMap<K, V> Filter(Func<K, long, Option<V>, bool> pred) =>\n            new VersionHashMap<K, V>(Items.Filter(pred));\n\n        /// <summary>\n        /// Atomically filter out items that return false when a predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>New map with items filtered</returns>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit FilterInPlace(Func<long, Option<V>, bool> pred) =>\n            Items.FilterInPlace(pred);\n        \n        /// <summary>\n        /// Atomically filter out items that return false when a predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>New map with items filtered</returns>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit FilterInPlace(Func<K, long, Option<V>, bool> pred) =>\n            Items.FilterInPlace(pred);\n\n        /// <summary>\n        /// Return true if all items in the map return true when the predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>True if all items in the map return true when the predicate is applied</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool ForAll(Func<K, V, bool> pred) =>\n            Items.ForAll(pred);\n\n        /// <summary>\n        /// Return true if all items in the map return true when the predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>True if all items in the map return true when the predicate is applied</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n            Items.ForAll(pred);\n\n        /// <summary>\n        /// Return true if *all* items in the map return true when the predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>True if all items in the map return true when the predicate is applied</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool ForAll(Func<KeyValuePair<K, V>, bool> pred) =>\n            Items.ForAll(pred);\n\n        /// <summary>\n        /// Return true if all items in the map return true when the predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>True if all items in the map return true when the predicate is applied</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool ForAll(Func<V, bool> pred) =>\n            Items.ForAll(pred);\n\n        /// <summary>\n        /// Return true if *any* items in the map return true when the predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>True if all items in the map return true when the predicate is applied</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool Exists(Func<K, V, bool> pred) =>\n            Items.Exists(pred);\n\n        /// <summary>\n        /// Return true if *any* items in the map return true when the predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>True if all items in the map return true when the predicate is applied</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool Exists(Func<(K Key, V Value), bool> pred) =>\n            Items.Exists(pred);\n\n        /// <summary>\n        /// Return true if *any* items in the map return true when the predicate is applied\n        /// </summary>\n        /// <param name=\"pred\">Predicate</param>\n        /// <returns>True if all items in the map return true when the predicate is applied</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool Exists(Func<V, bool> pred) =>\n            Items.Exists(pred);\n\n        /// <summary>\n        /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n        /// action on each\n        /// </summary>\n        /// <param name=\"action\">Action to execute</param>\n        /// <returns>Unit</returns>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit Iter(Action<K, V> action) =>\n            Items.Iter(action);\n\n        /// <summary>\n        /// Atomically iterate through all values in the map (in order) and execute an\n        /// action on each\n        /// </summary>\n        /// <param name=\"action\">Action to execute</param>\n        /// <returns>Unit</returns>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit Iter(Action<V> action) =>\n            Items.Iter(action);\n\n        /// <summary>\n        /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n        /// and execute an action on each\n        /// </summary>\n        /// <param name=\"action\">Action to execute</param>\n        /// <returns>Unit</returns>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit Iter(Action<(K Key, V Value)> action) =>\n            Items.Iter(action);\n\n        /// <summary>\n        /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n        /// action on each\n        /// </summary>\n        /// <param name=\"action\">Action to execute</param>\n        /// <returns>Unit</returns>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Unit Iter(Action<KeyValuePair<K, V>> action) =>\n            Items.Iter(action);\n\n        /// <summary>\n        /// Atomically folds all items in the map (in order) using the folder function provided.\n        /// </summary>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <param name=\"state\">Initial state</param>\n        /// <param name=\"folder\">Fold function</param>\n        /// <returns>Folded state</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n            Items.Fold(state, folder);\n\n        /// <summary>\n        /// Atomically folds all items in the map (in order) using the folder function provided.\n        /// </summary>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <param name=\"state\">Initial state</param>\n        /// <param name=\"folder\">Fold function</param>\n        /// <returns>Folded state</returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public S Fold<S>(S state, Func<S, V, S> folder) =>\n            Items.Fold(state, folder);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VersionVector/Version.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Wraps up a version vector, making it easier to work with and not generics hell\n/// </summary>\n/// <typeparam name=\"Actor\">Actor type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\npublic abstract record Version<Actor, K, V>(K Key)\n{\n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public abstract Version<Actor, K, V> Write(Actor actor, long timeStamp, V value);\n\n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public Version<Actor, K, V> Write(Actor actor, V value) =>\n        Write(actor, DateTime.UtcNow.Ticks, value);\n\n    /// <summary>\n    /// Perform a delete to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public abstract Version<Actor, K, V> Delete(Actor actor, long timeStamp);\n\n    /// <summary>\n    /// Perform a delete to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public Version<Actor, K, V> Delete(Actor actor) =>\n        Delete(actor, DateTime.UtcNow.Ticks);\n\n    /// <summary>\n    /// Get the value if there is one\n    /// </summary>\n    public abstract Option<V> Value { get; }\n}\n\n/// <summary>\n/// Internal: Helper functions for mapping between the non-generics Version and the generics heavy VersionVector\n/// </summary>\ninternal static class Version\n{\n    public static Version<Actor, K, V> ToVersion<ConflictV, OrdActor, Actor, K, V>(this VersionVector<ConflictV, OrdActor, TLong, Actor, long, V> vector, K key)\n        where OrdActor   : Ord<Actor>\n        where ConflictV : Conflict<V> =>\n        vector.Value.IsSome\n            ? new VersionValueVector<ConflictV, OrdActor, Actor, K, V>(key, vector)\n            : new VersionDeletedVector<ConflictV, OrdActor, Actor, K, V>(key, vector);\n\n    public static VersionVector<ConflictV, OrdActor, TLong, Actor, long, V>? ToVector<ConflictV, OrdActor, Actor, K, V>(\n        this Version<Actor, K, V> version)\n        where OrdActor : Ord<Actor>\n        where ConflictV : Conflict<V> =>\n        version switch\n        {\n            VersionValueVector<ConflictV, OrdActor, Actor, K, V> vv   => vv.Vector,\n            VersionDeletedVector<ConflictV, OrdActor, Actor, K, V> vd => vd.Vector,\n            _                                                         => null\n        };\n}\n\n/// <summary>\n/// Abstract representation of a version vector with a value\n/// </summary>\n/// <typeparam name=\"Actor\">Actor type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\ninternal abstract record VersionSome<Actor, K, V>(K Key, V value) : Version<Actor, K, V>(Key)\n{\n    /// <summary>\n    /// Get the value if there is one\n    /// </summary>\n    public override Option<V> Value =>\n        value;\n}\n\n/// <summary>\n/// Abstract representation of a version vector without a value (it either never existed or has been deleted)\n/// </summary>\n/// <typeparam name=\"Actor\">Actor type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\ninternal abstract record VersionNone<Actor, K, V>(K Key) : Version<Actor, K, V>(Key)\n{\n\n    /// <summary>\n    /// Get the value if there is one\n    /// </summary>\n    public override Option<V> Value =>\n        None;\n}\n\n/// <summary>\n/// Representation of a version vector that never existed\n/// </summary>\n/// <typeparam name=\"Actor\">Actor type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\ninternal record VersionNeverExistedVector<ConflictV, OrdActor, Actor, K, V>(K Key) : VersionNone<Actor, K, V>(Key)\n    where OrdActor  : Ord<Actor>\n    where ConflictV : Conflict<V>\n{\n    public static Version<Actor, K, V> New(K key) => new VersionNeverExistedVector<ConflictV, OrdActor, Actor, K, V>(key);\n\n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public override Version<Actor, K, V> Write(Actor actor, long timeStamp, V value) =>\n        new VersionValueVector<ConflictV, OrdActor, Actor, K, V>(\n            Key,\n            new VersionVector<ConflictV, OrdActor, TLong, Actor, long, V>(\n                value,\n                timeStamp,\n                VectorClock.Single<OrdActor, TLong, Actor, long>(actor, 1L)));\n\n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public override Version<Actor, K, V> Delete(Actor actor, long timeStamp) =>\n        this;\n}\n\n/// <summary>\n/// Representation of a version vector that existed but has since had its value deleted\n/// </summary>\n/// <typeparam name=\"Actor\">Actor type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\ninternal record VersionDeletedVector<ConflictV, OrdActor, Actor, K, V>(K Key, VersionVector<ConflictV, OrdActor, TLong, Actor, long, V> Vector) : VersionNone<Actor, K, V>(Key)\n    where OrdActor : Ord<Actor>\n    where ConflictV : Conflict<V>\n{\n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public override Version<Actor, K, V> Write(Actor actor, long timeStamp, V value) =>\n        new VersionValueVector<ConflictV, OrdActor, Actor, K, V>(Key, Vector.Put(actor, timeStamp, value));\n        \n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public override Version<Actor, K, V> Delete(Actor actor, long timeStamp) =>\n        new VersionDeletedVector<ConflictV, OrdActor, Actor, K, V>(Key, Vector.Put(actor, timeStamp, None));\n}\n\n/// <summary>\n/// Representation of a version vector with a value\n/// </summary>\n/// <typeparam name=\"Actor\">Actor type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\ninternal record VersionValueVector<ConflictV, OrdActor, Actor, K, V>(K Key, VersionVector<ConflictV, OrdActor, TLong, Actor, long, V> Vector) : \n    VersionSome<Actor, K, V>(Key, Vector.Value.Value ?? throw new ArgumentNullException(nameof(Vector.Value.Value)))\n    where OrdActor : Ord<Actor>\n    where ConflictV : Conflict<V>\n{\n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public override Version<Actor, K, V> Write(Actor actor, long timeStamp, V value) =>\n        new VersionValueVector<ConflictV, OrdActor, Actor, K, V>(Key, Vector.Put(actor, timeStamp, value));\n        \n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public override Version<Actor, K, V> Delete(Actor actor, long timeStamp) =>\n        new VersionDeletedVector<ConflictV, OrdActor, Actor, K, V>(Key, Vector.Put(actor, timeStamp, None));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Concurrency/VersionVector/VersionVector.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Version vector.  Container of an optional value, a time-stamp, and a vector clock.  Used to manage versioning\n/// of a single value.  ConflictA allows for injectable conflict resolution.\n/// </summary>\n/// <typeparam name=\"ConflictA\">Conflict resolution instance type</typeparam>\n/// <typeparam name=\"OrdActor\">Actor ordering instance type</typeparam>\n/// <typeparam name=\"NumClock\">Numeric clock instance type</typeparam>\n/// <typeparam name=\"Actor\">Actor type</typeparam>\n/// <typeparam name=\"Clock\">Clock type</typeparam>\n/// <typeparam name=\"A\">Value to version type</typeparam>\npublic record VersionVector<ConflictA, OrdActor, NumClock, Actor, Clock, A>(\n    Option<A> Value, \n    long TimeStamp, \n    VectorClock<OrdActor, NumClock, Actor, Clock> Vector) \n    where OrdActor  : Ord<Actor>\n    where NumClock  : Num<Clock>\n    where ConflictA : Conflict<A>\n{\n    /// <summary>\n    /// Register a write from any actor\n    /// </summary>\n    /// <param name=\"actor\">Actor that did the write operation</param>\n    /// <param name=\"value\">Value that the actor wrote</param>\n    /// <param name=\"vector\">The vector of the actor</param>\n    /// <returns></returns>\n    public VersionVector<ConflictA, OrdActor, NumClock, Actor, Clock, A> Put(\n        VersionVector<ConflictA, OrdActor, NumClock, Actor, Clock, A> version) =>\n        VectorClock.relation(Vector, version.Vector) switch\n        {\n            // `version` happened in the past, we don't care about it\n            Relation.CausedBy => this,\n\n            // `version` is causally linked to us, it is the future of us, so accept it\n            Relation.Causes => version,\n\n            // `version` has changed on a different branch of time to us, and so it conflicts.  Resolve it\n            // by using the monoid as a merge for the values, and take the pairwise maximum of the two vector clocks \n            Relation.Concurrent => ResolveConflict(version),\n\n            // Should never get here\n            _ => throw new NotSupportedException()\n        };\n\n    VersionVector<ConflictA, OrdActor, NumClock, Actor, Clock, A> ResolveConflict(VersionVector<ConflictA, OrdActor, NumClock, Actor, Clock, A> version)\n    {\n        var (ts, nv) = ConflictA.Resolve((TimeStamp, Value), (version.TimeStamp, version.Value));\n        return new VersionVector<ConflictA, OrdActor, NumClock, Actor, Clock, A>(\n            Value: nv, \n            TimeStamp: ts, \n            Vector: VectorClock.max(Vector, version.Vector));\n    }\n\n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public VersionVector<ConflictA, OrdActor, NumClock, Actor, Clock, A> Put(Actor actor, long timeStamp, Option<A> value) =>\n        new (Value: value, \n             TimeStamp: timeStamp, \n             Vector: Vector.Inc(actor, NumClock.FromInteger(0)));\n}\n\n/// <summary>\n/// Version vector.  Container of an optional value, a time-stamp, and a vector clock.  Used to manage versioning\n/// of a single value.  ConflictA allows for injectable conflict resolution.\n/// </summary>\n/// <typeparam name=\"ConflictA\">Conflict resolution instance type</typeparam>\n/// <typeparam name=\"Actor\">Actor type</typeparam>\n/// <typeparam name=\"A\">Value to version type</typeparam>\npublic record VersionVector<ConflictA, Actor, A>(Option<A> Value, long TimeStamp, VectorClock<Actor> Vector)\n    where Actor : IComparable<Actor>\n    where ConflictA : Conflict<A>\n{\n    /// <summary>\n    /// Register a write from any actor\n    /// </summary>\n    /// <param name=\"actor\">Actor that did the write operation</param>\n    /// <param name=\"value\">Value that the actor wrote</param>\n    /// <param name=\"vector\">The vector of the actor</param>\n    /// <returns></returns>\n    public VersionVector<ConflictA, Actor, A> Put(VersionVector<ConflictA, Actor, A> version) =>\n        VectorClock.relation(Vector, version.Vector) switch\n        {\n            // `version` happened in the past, we don't care about it\n            Relation.CausedBy => this,\n\n            // `version` is causally linked to us, it is the future of us, so accept it\n            Relation.Causes => version,\n\n            // `version` has changed on a different branch of time to us, and so it conflicts.  Resolve it\n            // by using the monoid as a merge for the values, and take the pairwise maximum of the two vector clocks \n            Relation.Concurrent => ResolveConflict(version),\n\n            // Should never get here\n            _ => throw new NotSupportedException()\n        };\n\n    VersionVector<ConflictA, Actor, A> ResolveConflict(VersionVector<ConflictA, Actor, A> version)\n    {\n        var (ts, nv) = ConflictA.Resolve((TimeStamp, Value), (version.TimeStamp, version.Value));\n        return new VersionVector<ConflictA, Actor, A>(Value: nv,\n                                                      TimeStamp: ts,\n                                                      Vector: VectorClock.max(Vector, version.Vector));\n    }\n\n    /// <summary>\n    /// Perform a write to the vector.  This increases the vector-clock by 1 for the `actor` provided.\n    /// </summary>\n    /// <param name=\"value\">Value to write</param>\n    public VersionVector<ConflictA, Actor, A> Put(Actor actor, long timeStamp, Option<A> value) =>\n        new(Value: value, TimeStamp: timeStamp, Vector: Vector.Inc(actor, 0L));\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/BigInt/BigInt.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// BigInteger convenience wrapper\n/// </summary>\n#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters. Such names may become reserved for the language.\npublic readonly struct bigint : \n#pragma warning restore CS8981 // The type name only contains lower-cased ascii characters. Such names may become reserved for the language.\n    IComparable, \n    IComparable<bigint>, \n    IEquatable<bigint>, \n    Monoid<bigint>\n{\n    public readonly BigInteger Value;\n\n    /// <summary>\n    /// Initializes a new instance of bigint structure using provided BigInteger value.\n    /// </summary>\n    /// <param name=\"value\">A big integer value to initialise this structure with</param>\n    public bigint(BigInteger value) =>\n        Value = value;\n\n    /// <summary>\n    /// Initializes a new instance of the bigint structure using\n    /// the values in a byte array.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// An array of byte values in little-endian order.\n    ///\n    /// </remarks>\n    public bigint(byte[] value)\n    {\n        Value = new BigInteger(value);\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the bigint structure using\n    /// a System.Decimal value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A decimal number.\n    /// </remarks>\n    public bigint(decimal value)\n    {\n        Value = new BigInteger(value);\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the bigint structure using\n    /// a double-precision floating-point value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A double-precision floating-point value.\n    ///\n    /// </remarks>\n    public bigint(double value)\n    {\n        Value = new BigInteger(value);\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the bigint structure using\n    /// a 32-bit signed integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A 32-bit signed integer.\n    /// </remarks>\n    public bigint(int value)\n    {\n        Value = new BigInteger(value);\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the bigint structure using\n    /// a 64-bit signed integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A 64-bit signed integer.\n    /// </remarks>\n    public bigint(long value)\n    {\n        Value = new BigInteger(value);\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the bigint structure using\n    /// a single-precision floating-point value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A single-precision floating-point value.\n    ///\n    /// </remarks>\n    public bigint(float value)\n    {\n        Value = new BigInteger(value);\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the bigint structure using\n    /// an unsigned 32-bit integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// An unsigned 32-bit integer value.\n    /// </remarks>\n    public bigint(uint value)\n    {\n        Value = new BigInteger(value);\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the bigint structure with an\n    /// unsigned 64-bit integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// An unsigned 64-bit integer.\n    /// </remarks>\n    public bigint(ulong value)\n    {\n        Value = new BigInteger(value);\n    }\n\n    /// <summary>\n    /// Gets a value that represents the number one (1).\n    /// </summary>\n    /// <returns>\n    /// An object whose value is one (1).\n    /// </returns>\n    public static readonly bigint One = new (1);\n\n    /// <summary>\n    /// Gets a value that represents the number negative one (-1).\n    /// </summary>\n    /// <returns>\n    /// An integer whose value is negative one (-1).\n    /// </returns>\n    public static readonly bigint MinusOne = new (-1);\n\n    /// <summary>\n    /// Gets a value that represents the number 0 (zero).\n    /// </summary>\n    /// <returns>\n    /// An integer whose value is 0 (zero).\n    /// </returns>\n    public static bigint Zero = new (0);\n\n    /// <summary>\n    /// Indicates whether the value of the current bigint object\n    /// is an even number.\n    /// </summary>\n    /// <returns>\n    /// true if the value of the bigint object is an even number;\n    /// otherwise, false.\n    /// </returns>\n    public bool IsEven => Value.IsEven;\n\n    /// <summary>\n    /// Indicates whether the value of the current bigint object\n    /// is bigint.Zero.\n    /// </summary>\n    /// <returns>\n    /// true if the value of the bigint object is bigint.Zero;\n    /// otherwise, false.\n    /// </returns>\n    public bool IsZero => Value.IsZero;\n\n    /// <summary>\n    /// Indicates whether the value of the current bigint object\n    /// is a power of two.\n    /// </summary>\n    /// <returns>\n    /// true if the value of the bigint object is a power of two;\n    /// otherwise, false.\n    /// </returns>\n    public bool IsPowerOfTwo => Value.IsPowerOfTwo;\n\n    /// <summary>\n    /// Indicates whether the value of the current bigint object\n    /// is bigint.One.\n    /// </summary>\n    /// <returns>\n    /// true if the value of the bigint object is bigint.One;\n    /// otherwise, false.\n    /// </returns>\n    public bool IsOne => Value.IsOne;\n\n    /// <summary>\n    /// Gets a number that indicates the sign (negative, positive, or zero) of the current\n    /// bigint object.\n    /// </summary>\n    /// <returns>\n    /// A number that indicates the sign of the bigint object, as\n    /// shown in the following table.NumberDescription-1The value of this object is negative.0The\n    /// value of this object is 0 (zero).1The value of this object is positive.\n    /// </returns>\n    public int Sign => Value.Sign;\n\n    /// <summary>\n    /// Gets the absolute value of a bigint object.\n    /// </summary>\n    /// <returns>\n    /// The absolute value of value.\n    /// </returns>\n    public static bigint Abs(bigint value) => \n        new (BigInteger.Abs(value.Value));\n\n    /// <summary>\n    /// Adds two bigint values and returns the result.\n    /// </summary>\n    /// <returns>\n    /// The sum of left and right.\n    /// </returns>\n    public static bigint Add(bigint left, bigint right) =>\n        BigInteger.Add(left.Value, right.Value);\n\n    /// <summary>\n    /// Compares two bigint values and returns an integer that indicates\n    /// whether the first value is less than, equal to, or greater than the second value.\n    /// </summary>\n    /// <returns>\n    /// A signed integer that indicates the relative values of left and right, as shown\n    /// in the following table.ValueConditionLess than zeroleft is less than right.Zeroleft\n    /// equals right.Greater than zeroleft is greater than right.\n    /// </returns>\n    public static int Compare(bigint left, bigint right) =>\n        left.Value.CompareTo(right.Value);\n\n    /// <summary>\n    /// Divides one bigint value by another and returns the result.\n    ///\n    /// </summary><remarks>\n    /// dividend:\n    /// The value to be divided.\n    ///\n    /// divisor:\n    /// The value to divide by.\n    ///\n    /// </remarks><returns>\n    /// The quotient of the division.\n    ///\n    /// </returns>\n    public static bigint Divide(bigint dividend, bigint divisor) =>\n        BigInteger.Divide(dividend.Value, divisor.Value);\n\n    /// <summary>\n    /// Divides one bigint value by another, returns the quotient and remainder.\n    ///\n    /// </summary><remarks>\n    /// dividend:\n    /// The value to be divided.\n    ///\n    /// divisor:\n    /// The value to divide by.\n    ///\n    /// </remarks><returns>\n    /// The quotient and remainder of the division as a tuple\n    ///\n    /// </returns>\n    public static (bigint Quotient, bigint Remainder) DivRem(bigint dividend, bigint divisor)\n    {\n        var res = BigInteger.DivRem(dividend.Value, divisor.Value, out BigInteger rem);\n        return (new (res), new (rem));\n    }\n\n    /// <summary>\n    /// Finds the greatest common divisor of two bigint values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value.\n    ///\n    /// right:\n    /// The second value.\n    ///\n    /// </remarks><returns>\n    /// The greatest common divisor of left and right.\n    /// </returns>\n    public static bigint GreatestCommonDivisor(bigint left, bigint right) =>\n        new (BigInteger.GreatestCommonDivisor(left.Value, right.Value));\n\n    /// <summary>\n    /// Returns the natural (base e) logarithm of a specified number.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The number whose logarithm is to be found.\n    ///\n    /// </remarks><returns>\n    /// The natural (base e) logarithm of value, as shown in the table in the Remarks\n    /// section.\n    ///\n    /// </returns>\n    public static double Log(bigint value) =>\n        BigInteger.Log(value.Value);\n\n    /// <summary>\n    /// Returns the logarithm of a specified number in a specified base.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A number whose logarithm is to be found.\n    ///\n    /// baseValue:\n    /// The base of the logarithm.\n    ///\n    /// </remarks><returns>\n    /// The base baseValue logarithm of value, as shown in the table in the Remarks section.\n    ///\n    /// </returns>\n    public static double Log(bigint value, double baseValue) =>\n        BigInteger.Log(value.Value, baseValue);\n\n    /// <summary>\n    /// Returns the base 10 logarithm of a specified number.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A number whose logarithm is to be found.\n    ///\n    /// </remarks><returns>\n    /// The base 10 logarithm of value, as shown in the table in the Remarks section.\n    ///\n    /// </returns>\n    public static double Log10(bigint value) =>\n        BigInteger.Log10(value.Value);\n\n    /// <summary>\n    /// Returns the larger of two bigint values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// The left or right parameter, whichever is larger.\n    /// </returns>\n    public static bigint Max(bigint left, bigint right) =>\n        new (BigInteger.Max(left.Value, right.Value));\n\n    /// <summary>\n    /// Returns the smaller of two bigint values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// The left or right parameter, whichever is smaller.\n    /// </returns>\n    public static bigint Min(bigint left, bigint right) =>\n        new (BigInteger.Min(left.Value, right.Value));\n\n    /// <summary>\n    /// Performs modulus division on a number raised to the power of another number.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The number to raise to the exponent power.\n    ///\n    /// exponent:\n    /// The exponent to raise value by.\n    ///\n    /// modulus:\n    /// The number by which to divide value raised to the exponent power.\n    ///\n    /// </remarks><returns>\n    /// The remainder after dividing value exponent by modulus.\n    ///\n    /// </returns>\n    public static bigint ModPow(bigint value, bigint exponent, bigint modulus) =>\n        new (BigInteger.ModPow(value.Value, exponent.Value, modulus.Value));\n\n    /// <summary>\n    /// Returns the product of two bigint values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first number to multiply.\n    ///\n    /// right:\n    /// The second number to multiply.\n    ///\n    /// </remarks><returns>\n    /// The product of the left and right parameters.\n    /// </returns>\n    public static bigint Multiply(bigint left, bigint right) =>\n        new (BigInteger.Multiply(left.Value, right.Value));\n\n    /// <summary>\n    /// Negates a specified bigint value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to negate.\n    ///\n    /// </remarks><returns>\n    /// The result of the value parameter multiplied by negative one (-1).\n    /// </returns>\n    public static bigint Negate(bigint value) =>\n        new (BigInteger.Negate(value.Value));\n\n    /// <summary>\n    /// Converts the string representation of a number in a specified style to its bigint\n    /// equivalent.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A string that contains a number to convert.\n    ///\n    /// style:\n    /// A bitwise combination of the enumeration values that specify the permitted format\n    /// of value.\n    ///\n    /// </remarks><returns>\n    /// A value that is equivalent to the number specified in the value parameter.\n    ///\n    /// </returns>\n    public static bigint Parse(string value, NumberStyles style) =>\n        new (BigInteger.Parse(value, style));\n\n    /// <summary>\n    /// Converts the string representation of a number in a specified culture-specific\n    /// format to its bigint equivalent.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A string that contains a number to convert.\n    ///\n    /// provider:\n    /// An object that provides culture-specific formatting information about value.\n    ///\n    /// </remarks><returns>\n    /// A value that is equivalent to the number specified in the value parameter.\n    ///\n    /// </returns>\n    public static bigint Parse(string value, IFormatProvider provider) =>\n        new (BigInteger.Parse(value, provider));\n\n    /// <summary>\n    /// Converts the string representation of a number to its bigint\n    /// equivalent.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A string that contains the number to convert.\n    ///\n    /// </remarks><returns>\n    /// A value that is equivalent to the number specified in the value parameter.\n    ///\n    /// </returns>\n    public static bigint Parse(string value) =>\n        new (BigInteger.Parse(value));\n\n    /// <summary>\n    /// Converts the string representation of a number in a specified style and culture-specific\n    /// format to its bigint equivalent.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// A string that contains a number to convert.\n    ///\n    /// style:\n    /// A bitwise combination of the enumeration values that specify the permitted format\n    /// of value.\n    ///\n    /// provider:\n    /// An object that provides culture-specific formatting information about value.\n    ///\n    /// </remarks><returns>\n    /// A value that is equivalent to the number specified in the value parameter.\n    ///\n    /// </returns>\n    public static bigint Parse(string value, NumberStyles style, IFormatProvider provider) =>\n        new (BigInteger.Parse(value, style, provider));\n\n    /// <summary>\n    /// Raises a bigint value to the power of a specified value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The number to raise to the exponent power.\n    ///\n    /// exponent:\n    /// The exponent to raise value by.\n    ///\n    /// </remarks><returns>\n    /// The result of raising value to the exponent power.\n    ///\n    /// </returns>\n    public static bigint Pow(bigint value, int exponent) =>\n        new (BigInteger.Pow(value.Value, exponent));\n\n    /// <summary>\n    /// Performs integer division on two bigint values and returns\n    /// the remainder.\n    ///\n    /// </summary><remarks>\n    /// dividend:\n    /// The value to be divided.\n    ///\n    /// divisor:\n    /// The value to divide by.\n    ///\n    /// </remarks><returns>\n    /// The remainder after dividing dividend by divisor.\n    ///\n    /// </returns>\n    public static bigint Remainder(bigint dividend, bigint divisor) =>\n        new (BigInteger.Remainder(dividend.Value, divisor.Value));\n\n    /// <summary>\n    /// Subtracts one bigint value from another and returns the result.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The value to subtract from (the minuend).\n    ///\n    /// right:\n    /// The value to subtract (the subtrahend).\n    ///\n    /// </remarks><returns>\n    /// The result of subtracting right from left.\n    /// </returns>\n    public static bigint Subtract(bigint left, bigint right) =>\n        new (BigInteger.Subtract(left.Value, right.Value));\n\n    /// <summary>\n    /// Tries to convert the string representation of a number in a specified style and\n    /// culture-specific format to its bigint equivalent, and returns\n    /// a value that indicates whether the conversion succeeded.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The string representation of a number. The string is interpreted using the style\n    /// specified by style.\n    ///\n    /// style:\n    /// A bitwise combination of enumeration values that indicates the style elements\n    /// that can be present in value. A typical value to specify is System.Globalization.NumberStyles.Integer.\n    ///\n    /// provider:\n    /// An object that supplies culture-specific formatting information about value.\n    ///\n    /// </remarks><returns>\n    /// Optional value \n    ///\n    /// </returns>\n    public static Option<bigint> TryParse(string value, NumberStyles style, IFormatProvider provider) =>\n        BigInteger.TryParse(value, style, provider, out BigInteger res)\n            ? Some(new bigint(res))\n            : None;\n\n    /// <summary>\n    /// Tries to convert the string representation of a number to its bigint\n    /// equivalent, and returns a value that indicates whether the conversion succeeded.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The string representation of a number.\n    ///\n    /// </remarks><returns>\n    /// Optional value \n    ///\n    /// </returns>\n    public static Option<bigint> TryParse(string value) =>\n        BigInteger.TryParse(value, out BigInteger res)\n            ? Some(new bigint(res))\n            : None;\n    /// <summary>\n    /// Compares this instance to a signed 64-bit integer and returns an integer that\n    /// indicates whether the value of this instance is less than, equal to, or greater\n    /// than the value of the signed 64-bit integer.\n    ///\n    /// </summary><remarks>\n    /// other:\n    /// The signed 64-bit integer to compare.\n    ///\n    /// </remarks><returns>\n    /// A signed integer value that indicates the relationship of this instance to other,\n    /// as shown in the following table.Return valueDescriptionLess than zeroThe current\n    /// instance is less than other.ZeroThe current instance equals other.Greater than\n    /// zeroThe current instance is greater than other.\n    /// </returns>\n    public int CompareTo(long other) =>\n        Value.CompareTo(other);\n\n    /// <summary>\n    /// Compares this instance to an unsigned 64-bit integer and returns an integer that\n    /// indicates whether the value of this instance is less than, equal to, or greater\n    /// than the value of the unsigned 64-bit integer.\n    ///\n    /// </summary><remarks>\n    /// other:\n    /// The unsigned 64-bit integer to compare.\n    ///\n    /// </remarks><returns>\n    /// A signed integer that indicates the relative value of this instance and other,\n    /// as shown in the following table.Return valueDescriptionLess than zeroThe current\n    /// instance is less than other.ZeroThe current instance equals other.Greater than\n    /// zeroThe current instance is greater than other.\n    /// </returns>\n    public int CompareTo(ulong other) =>\n        Value.CompareTo(other);\n\n    /// <summary>\n    /// Compares this instance to a second bigint and returns an\n    /// integer that indicates whether the value of this instance is less than, equal\n    /// to, or greater than the value of the specified object.\n    ///\n    /// </summary><remarks>\n    /// other:\n    /// The object to compare.\n    ///\n    /// </remarks><returns>\n    /// A signed integer value that indicates the relationship of this instance to other,\n    /// as shown in the following table.Return valueDescriptionLess than zeroThe current\n    /// instance is less than other.ZeroThe current instance equals other.Greater than\n    /// zeroThe current instance is greater than other.\n    /// </returns>\n    public int CompareTo(BigInteger other) =>\n        Value.CompareTo(other);\n\n    /// <summary>\n    /// Compares this instance to a second bigint and returns an\n    /// integer that indicates whether the value of this instance is less than, equal\n    /// to, or greater than the value of the specified object.\n    ///\n    /// </summary><remarks>\n    /// other:\n    /// The object to compare.\n    ///\n    /// </remarks><returns>\n    /// A signed integer value that indicates the relationship of this instance to other,\n    /// as shown in the following table.Return valueDescriptionLess than zeroThe current\n    /// instance is less than other.ZeroThe current instance equals other.Greater than\n    /// zeroThe current instance is greater than other.\n    /// </returns>\n    public int CompareTo(bigint other) =>\n        Value.CompareTo(other.Value);\n\n    /// <summary>\n    /// Returns a value that indicates whether the current instance and a signed 64-bit\n    /// integer have the same value.\n    ///\n    /// </summary><remarks>\n    /// other:\n    /// The signed 64-bit integer value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the signed 64-bit integer and the current instance have the same value;\n    /// otherwise, false.\n    /// </returns>\n    public bool Equals(long other) =>\n        Value.Equals(other);\n\n    /// <summary>\n    /// Returns a value that indicates whether the current instance and a specified bigint\n    /// object have the same value.\n    ///\n    /// </summary><remarks>\n    /// other:\n    /// The object to compare.\n    ///\n    /// </remarks><returns>\n    /// true if this bigint object and other have the same value;\n    /// otherwise, false.\n    /// </returns>\n    public bool Equals(BigInteger other) =>\n        Value.Equals(other);\n\n    /// <summary>\n    /// Returns a value that indicates whether the current instance and a specified bigint\n    /// object have the same value.\n    ///\n    /// </summary><remarks>\n    /// other:\n    /// The object to compare.\n    ///\n    /// </remarks><returns>\n    /// true if this bigint object and other have the same value;\n    /// otherwise, false.\n    /// </returns>\n    public bool Equals(bigint other) =>\n        Value.Equals(other.Value);\n\n    /// <summary>\n    /// Returns a value that indicates whether the current instance and a specified object\n    /// have the same value.\n    ///\n    /// </summary><remarks>\n    /// obj:\n    /// The object to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the obj parameter is a bigint object or a type capable\n    /// of implicit conversion to a bigint value, and its value is\n    /// equal to the value of the current bigint object; otherwise,\n    /// false.\n    /// </returns>\n    public override bool Equals(object? obj) =>\n        obj switch\n        {\n            bigint rhs     => Value.Equals(rhs.Value),\n            BigInteger rhs => Value.Equals(rhs),\n            _              => false\n        };\n\n    /// <summary>\n    /// Returns a value that indicates whether the current instance and an unsigned 64-bit\n    /// integer have the same value.\n    ///\n    /// </summary><remarks>\n    /// other:\n    /// The unsigned 64-bit integer to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the current instance and the unsigned 64-bit integer have the same value;\n    /// otherwise, false.\n    /// </returns>\n    public bool Equals(ulong other) =>\n        Value.Equals(other);\n\n    /// <summary>\n    /// Returns the hash code for the current bigint object.\n    ///\n    /// </summary>\n    /// <returns>\n    /// A 32-bit signed integer hash code.\n    /// </returns>\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            bigint rhs     => Value.CompareTo(rhs.Value),\n            BigInteger rhs => Value.CompareTo(rhs),\n            _              => 1\n        };        \n\n    /// <summary>\n    /// Converts a bigint value to a byte array.\n    ///\n    /// </summary><returns>\n    /// The value of the current bigint object converted to an array\n    /// of bytes.\n    /// </returns>\n    public byte[] ToByteArray() =>\n        Value.ToByteArray();\n\n    /// <summary>\n    /// Converts the numeric value of the current bigint object to\n    /// its equivalent string representation.\n    /// </summary>\n    /// <returns>\n    /// The string representation of the current bigint value.\n    /// </returns>\n    public override string ToString() =>\n        Value.ToString();\n\n    /// <summary>\n    /// Converts the numeric value of the current bigint object to\n    /// its equivalent string representation by using the specified format.\n    ///\n    /// </summary><remarks>\n    /// format:\n    /// A standard or custom numeric format string.\n    ///\n    /// </remarks><returns>\n    /// The string representation of the current bigint value in\n    /// the format specified by the format parameter.\n    ///\n    /// </returns>\n    public string ToString(string format) =>\n        Value.ToString(format);\n\n    /// <summary>\n    /// Converts the numeric value of the current bigint object to\n    /// its equivalent string representation by using the specified culture-specific\n    /// formatting information.\n    ///\n    /// </summary><remarks>\n    /// provider:\n    /// An object that supplies culture-specific formatting information.\n    ///\n    /// </remarks><returns>\n    /// The string representation of the current bigint value in\n    /// the format specified by the provider parameter.\n    /// </returns>\n    public string ToString(IFormatProvider provider) =>\n        Value.ToString(provider);\n\n    /// <summary>\n    /// Converts the numeric value of the current bigint object to\n    /// its equivalent string representation by using the specified format and culture-specific\n    /// format information.\n    ///\n    /// </summary><remarks>\n    /// format:\n    /// A standard or custom numeric format string.\n    ///\n    /// provider:\n    /// An object that supplies culture-specific formatting information.\n    ///\n    /// </remarks><returns>\n    /// The string representation of the current bigint value as\n    /// specified by the format and provider parameters.\n    ///\n    /// </returns>\n    public string ToString(string format, IFormatProvider provider) =>\n        Value.ToString(format, provider);\n\n    /// <summary>\n    /// Returns the value of the bigint operand. (The sign of the\n    /// operand is unchanged.)\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// An integer value.\n    ///\n    /// </remarks><returns>\n    /// The value of the value operand.\n    /// </returns>\n    public static bigint operator +(bigint value) =>\n        value;\n\n    /// <summary>\n    /// Adds the values of two specified bigint objects.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to add.\n    ///\n    /// right:\n    /// The second value to add.\n    ///\n    /// </remarks><returns>\n    /// The sum of left and right.\n    /// </returns>\n    public static bigint operator +(bigint left, bigint right) =>\n        new (left.Value + right.Value);\n\n    /// <summary>\n    /// Negates a specified BigInteger value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to negate.\n    ///\n    /// </remarks><returns>\n    /// The result of the value parameter multiplied by negative one (-1).\n    /// </returns>\n    public static bigint operator -(bigint value) =>\n        new (-value.Value);\n\n    /// <summary>\n    /// Subtracts a bigint value from another bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The value to subtract from (the minuend).\n    ///\n    /// right:\n    /// The value to subtract (the subtrahend).\n    ///\n    /// </remarks><returns>\n    /// The result of subtracting right from left.\n    /// </returns>\n    public static bigint operator -(bigint left, bigint right) =>\n        new (left.Value - right.Value);\n\n    /// <summary>\n    /// Returns the bitwise one's complement of a bigint value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// An integer value.\n    ///\n    /// </remarks><returns>\n    /// The bitwise one's complement of value.\n    /// </returns>\n    public static bigint operator ~(bigint value) =>\n        new (~value.Value);\n\n    /// <summary>\n    /// Increments a bigint value by 1.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to increment.\n    ///\n    /// </remarks><returns>\n    /// The value of the value parameter incremented by 1.\n    /// </returns>\n    public static bigint operator ++(bigint value) =>\n        value + One;\n\n    /// <summary>\n    /// Decrements a bigint value by 1.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to decrement.\n    ///\n    /// </remarks><returns>\n    /// The value of the value parameter decremented by 1.\n    /// </returns>\n    public static bigint operator --(bigint value) =>\n        value - One;\n\n    /// <summary>\n    /// Multiplies two specified bigint values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to multiply.\n    ///\n    /// right:\n    /// The second value to multiply.\n    ///\n    /// </remarks><returns>\n    /// The product of left and right.\n    /// </returns>\n    public static bigint operator *(bigint left, bigint right) =>\n        new (left.Value * right.Value);\n\n    /// <summary>\n    /// Divides a specified bigint value by another specified bigint\n    /// value by using integer division.\n    ///\n    /// </summary><remarks>\n    /// dividend:\n    /// The value to be divided.\n    ///\n    /// divisor:\n    /// The value to divide by.\n    ///\n    /// </remarks><returns>\n    /// The integral result of the division.\n    ///\n    /// </returns>\n    public static bigint operator /(bigint dividend, bigint divisor) =>\n        new (dividend.Value / divisor.Value);\n\n    /// <summary>\n    /// Returns the remainder that results from division with two specified bigint\n    /// values.\n    ///\n    /// </summary><remarks>\n    /// dividend:\n    /// The value to be divided.\n    ///\n    /// divisor:\n    /// The value to divide by.\n    ///\n    /// </remarks><returns>\n    /// The remainder that results from the division.\n    ///\n    /// </returns>\n    public static bigint operator %(bigint dividend, bigint divisor) =>\n        new (dividend.Value % divisor.Value);\n\n    /// <summary>\n    /// Performs a bitwise And operation on two bigint values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value.\n    ///\n    /// right:\n    /// The second value.\n    ///\n    /// </remarks><returns>\n    /// The result of the bitwise And operation.\n    /// </returns>\n    public static bigint operator &(bigint left, bigint right) =>\n        new (left.Value & right.Value);\n\n    /// <summary>\n    /// Performs a bitwise Or operation on two bigint values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value.\n    ///\n    /// right:\n    /// The second value.\n    ///\n    /// </remarks><returns>\n    /// The result of the bitwise Or operation.\n    /// </returns>\n    public static bigint operator |(bigint left, bigint right) =>\n        new (left.Value | right.Value);\n\n    /// <summary>\n    /// Performs a bitwise exclusive Or (XOr) operation on two bigint\n    /// values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value.\n    ///\n    /// right:\n    /// The second value.\n    ///\n    /// </remarks><returns>\n    /// The result of the bitwise Or operation.\n    /// </returns>\n    public static bigint operator ^(bigint left, bigint right) =>\n        new (left.Value ^ right.Value);\n\n    /// <summary>\n    /// Shifts a bigint value a specified number of bits to the left.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value whose bits are to be shifted.\n    ///\n    /// shift:\n    /// The number of bits to shift value to the left.\n    ///\n    /// </remarks><returns>\n    /// A value that has been shifted to the left by the specified number of bits.\n    /// </returns>\n    public static bigint operator <<(bigint value, int shift) =>\n        new (value.Value << shift);\n\n    /// <summary>\n    /// Shifts a bigint value a specified number of bits to the right.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value whose bits are to be shifted.\n    ///\n    /// shift:\n    /// The number of bits to shift value to the right.\n    ///\n    /// </remarks><returns>\n    /// A value that has been shifted to the right by the specified number of bits.\n    /// </returns>\n    public static bigint operator >>(bigint value, int shift) =>\n        new (value.Value >> shift);\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value and\n    /// an unsigned long integer value are equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the left and right parameters have the same value; otherwise, false.\n    /// </returns>\n    public static bool operator ==(bigint left, ulong right) =>\n        left.Value == right;\n\n    /// <summary>\n    /// Returns a value that indicates whether the values of two bigint\n    /// objects are equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the left and right parameters have the same value; otherwise, false.\n    /// </returns>\n    public static bool operator ==(BigInteger left, bigint right) =>\n        left == right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether the values of two bigint\n    /// objects are equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the left and right parameters have the same value; otherwise, false.\n    /// </returns>\n    public static bool operator ==(bigint left, BigInteger right) =>\n        left.Value == right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a signed long integer value and a bigint\n    /// value are equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the left and right parameters have the same value; otherwise, false.\n    /// </returns>\n    public static bool operator ==(long left, bigint right) =>\n        left == right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value and\n    /// a signed long integer value are equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the left and right parameters have the same value; otherwise, false.\n    /// </returns>\n    public static bool operator ==(bigint left, long right) =>\n        left.Value == right;\n\n    /// <summary>\n    /// Returns a value that indicates whether the values of two bigint\n    /// objects are equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the left and right parameters have the same value; otherwise, false.\n    /// </returns>\n    public static bool operator ==(bigint left, bigint right) =>\n        left.Value == right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether an unsigned long integer value and a bigint\n    /// value are equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if the left and right parameters have the same value; otherwise, false.\n    /// </returns>\n    public static bool operator ==(ulong left, bigint right) =>\n        left == right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit unsigned integer and a bigint\n    /// value are not equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left and right are not equal; otherwise, false.\n    /// </returns>\n    public static bool operator !=(ulong left, bigint right) =>\n        left != right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value and\n    /// a 64-bit unsigned integer are not equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left and right are not equal; otherwise, false.\n    /// </returns>\n    public static bool operator !=(bigint left, ulong right) =>\n        left.Value != right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit signed integer and a bigint\n    /// value are not equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left and right are not equal; otherwise, false.\n    /// </returns>\n    public static bool operator !=(long left, bigint right) =>\n        left != right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value and\n    /// a 64-bit signed integer are not equal.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left and right are not equal; otherwise, false.\n    /// </returns>\n    public static bool operator !=(bigint left, long right) =>\n        left.Value != right;\n\n    /// <summary>\n    /// Returns a value that indicates whether two bigint objects\n    /// have different values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left and right are not equal; otherwise, false.\n    /// </returns>\n    public static bool operator !=(bigint left, bigint right) =>\n        left.Value != right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether two bigint objects\n    /// have different values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left and right are not equal; otherwise, false.\n    /// </returns>\n    public static bool operator !=(BigInteger left, bigint right) =>\n        left != right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether two bigint objects\n    /// have different values.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left and right are not equal; otherwise, false.\n    /// </returns>\n    public static bool operator !=(bigint left, BigInteger right) =>\n        left.Value != right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit signed integer is less than a\n    /// bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than right; otherwise, false.\n    /// </returns>\n    public static bool operator <(long left, bigint right) =>\n        left < right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than a 64-bit unsigned integer.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than right; otherwise, false.\n    /// </returns>\n    public static bool operator <(bigint left, ulong right) =>\n        left.Value < right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit unsigned integer is less than\n    /// a bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than right; otherwise, false.\n    /// </returns>\n    public static bool operator <(ulong left, bigint right) =>\n        left < right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than right; otherwise, false.\n    /// </returns>\n    public static bool operator <(bigint left, bigint right) =>\n        left.Value < right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than right; otherwise, false.\n    /// </returns>\n    public static bool operator <(BigInteger left, bigint right) =>\n        left < right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than right; otherwise, false.\n    /// </returns>\n    public static bool operator <(bigint left, BigInteger right) =>\n        left.Value < right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than a 64-bit signed integer.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than right; otherwise, false.\n    /// </returns>\n    public static bool operator <(bigint left, long right) =>\n        left.Value < right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than a 64-bit unsigned integer.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >(ulong left, bigint right) =>\n        left < right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >(bigint left, bigint right) =>\n        left.Value > right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >(BigInteger left, bigint right) =>\n        left > right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >(bigint left, BigInteger right) =>\n        left.Value > right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit signed integer is greater than\n    /// a bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >(long left, bigint right) =>\n        left > right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint is greater\n    /// than a 64-bit signed integer value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >(bigint left, long right) =>\n        left.Value > right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than a 64-bit unsigned integer.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >(bigint left, ulong right) =>\n        left.Value > right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit signed integer is less than or\n    /// equal to a bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than or equal to right; otherwise, false.\n    /// </returns>\n    public static bool operator <=(long left, bigint right) =>\n        left <= right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than or equal to a 64-bit signed integer.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than or equal to right; otherwise, false.\n    /// </returns>\n    public static bool operator <=(bigint left, long right) =>\n        left.Value <= right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than or equal to another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than or equal to right; otherwise, false.\n    /// </returns>\n    public static bool operator <=(bigint left, bigint right) =>\n        left.Value <= right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than or equal to another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than or equal to right; otherwise, false.\n    /// </returns>\n    public static bool operator <=(BigInteger left, bigint right) =>\n        left <= right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than or equal to another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than or equal to right; otherwise, false.\n    /// </returns>\n    public static bool operator <=(bigint left, BigInteger right) =>\n        left.Value <= right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// less than or equal to a 64-bit unsigned integer.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than or equal to right; otherwise, false.\n    /// </returns>\n    public static bool operator <=(bigint left, ulong right) =>\n        left.Value <= right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit unsigned integer is less than\n    /// or equal to a bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is less than or equal to right; otherwise, false.\n    /// </returns>\n    public static bool operator <=(ulong left, bigint right) =>\n        left <= right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit signed integer is greater than\n    /// or equal to a bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >=(long left, bigint right) =>\n        left >= right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than or equal to a 64-bit signed integer value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >=(bigint left, long right) =>\n        left.Value >= right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than or equal to another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >=(bigint left, bigint right) =>\n        left.Value >= right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than or equal to another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >=(BigInteger left, bigint right) =>\n        left >= right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than or equal to another bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >=(bigint left, BigInteger right) =>\n        left.Value >= right;\n\n    /// <summary>\n    /// Returns a value that indicates whether a 64-bit unsigned integer is greater than\n    /// or equal to a bigint value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >=(ulong left, bigint right) =>\n        left >= right.Value;\n\n    /// <summary>\n    /// Returns a value that indicates whether a bigint value is\n    /// greater than or equal to a 64-bit unsigned integer value.\n    ///\n    /// </summary><remarks>\n    /// left:\n    /// The first value to compare.\n    ///\n    /// right:\n    /// The second value to compare.\n    ///\n    /// </remarks><returns>\n    /// true if left is greater than right; otherwise, false.\n    /// </returns>\n    public static bool operator >=(bigint left, ulong right) =>\n        left.Value >= right;\n\n    /// <summary>\n    /// Defines an implicit conversion of a BigInteger to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(BigInteger value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an implicit conversion of an unsigned byte to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(byte value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an implicit conversion of a 16-bit unsigned integer to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(ushort value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an implicit conversion of an 8-bit signed integer to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(sbyte value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an implicit conversion of a 32-bit unsigned integer to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(uint value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an implicit conversion of a signed 64-bit integer to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(long value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an implicit conversion of a signed 32-bit integer to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(int value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an implicit conversion of a signed 16-bit integer to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(short value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an implicit conversion of a 64-bit unsigned integer to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static implicit operator bigint(ulong value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an explicit conversion of a System.Decimal object to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static explicit operator bigint(decimal value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an explicit conversion of a System.Double value to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator bigint(double value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to an unsigned\n    /// byte value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a System.Byte.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator byte(bigint value) =>\n        (byte)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to an bigint value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a System.Byte.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static implicit operator BigInteger(bigint value) =>\n        value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to a System.Decimal\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a System.Decimal.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator decimal(bigint value) =>\n        (decimal)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to a System.Double\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a System.Double.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    /// </returns>\n    public static explicit operator double(bigint value) =>\n        (double)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to a 16-bit\n    /// signed integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a 16-bit signed integer.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator short(bigint value) =>\n        (short)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to a 64-bit\n    /// signed integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a 64-bit signed integer.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator long(bigint value) =>\n        (long)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to a signed\n    /// 8-bit value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a signed 8-bit value.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator sbyte(bigint value) =>\n        (sbyte)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to an unsigned\n    /// 16-bit integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to an unsigned 16-bit integer.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter\n    ///\n    /// </returns>\n    public static explicit operator ushort(bigint value) =>\n        (ushort)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to an unsigned\n    /// 32-bit integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to an unsigned 32-bit integer.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator uint(bigint value) =>\n        (uint)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to an unsigned\n    /// 64-bit integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to an unsigned 64-bit integer.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator ulong(bigint value) =>\n        (ulong)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a System.Single object to a bigint\n    /// value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a bigint.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator bigint(float value) =>\n        new (value);\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to a 32-bit\n    /// signed integer value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a 32-bit signed integer.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the value of the value parameter.\n    ///\n    /// </returns>\n    public static explicit operator int(bigint value) =>\n        (int)value.Value;\n\n    /// <summary>\n    /// Defines an explicit conversion of a bigint object to a single-precision\n    /// floating-point value.\n    ///\n    /// </summary><remarks>\n    /// value:\n    /// The value to convert to a single-precision floating-point value.\n    ///\n    /// </remarks><returns>\n    /// An object that contains the closest possible representation of the value parameter.\n    /// </returns>\n    public static explicit operator float(bigint value) =>\n        (float)value.Value;\n    \n    /// <summary>\n    /// Semigroup append\n    /// </summary>\n    bigint Semigroup<bigint>.Combine(bigint y) => \n        Value + y.Value;\n\n    /// <summary>\n    /// Monoid Empty\n    /// </summary>\n    static bigint Monoid<bigint>.Empty =>\n        BigInteger.Zero;\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Change/Change.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents changes to a value in a collection type (i.e. a key-value collection)\n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic abstract class Change<A> :\n    IEquatable<Change<A>>,\n    Monoid<Change<A>>\n{\n    /// <summary>\n    /// Returns true if nothing has changed\n    /// </summary>\n    public bool HasNoChange => this is NoChange<A>;\n\n    /// <summary>\n    /// Returns true if anything has changed (add, update, or removal)\n    /// </summary>\n    public bool HasChanged => !HasNoChange;\n        \n    /// <summary>\n    /// Returns true if a value has been removed\n    /// </summary>\n    public bool HasRemoved => this is EntryRemoved<A>;\n        \n    /// <summary>\n    /// Returns true if a value has been mapped to another\n    /// </summary>\n    public bool HasMapped => this is EntryMappedTo<A>;\n        \n    /// <summary>\n    /// Returns true if a value has been mapped to another\n    /// </summary>\n    public bool HasMappedFrom<FROM>() => \n        this is EntryMappedFrom<FROM>;\n        \n    /// <summary>\n    /// Returns true if a value has been added\n    /// </summary>\n    public bool HasAdded => this is EntryAdded<A>;\n\n    /// <summary>\n    /// If a value has been updated this will return Some(Value), else none\n    /// </summary>\n    public Option<A> ToOption() =>\n        this switch\n        {\n            EntryAdded<A>(var v)    => Some(v),\n            EntryMappedTo<A>(var v) => Some(v),\n            _                       => Option<A>.None\n        };\n\n    /// <summary>\n    /// Returns a `NoChange` state\n    /// </summary>\n    public static Change<A> None => NoChange<A>.Default;\n\n    /// <summary>\n    /// Returns a `EntryRemoved` state\n    /// </summary>\n    public static Change<A> Removed(A oldValue) => new EntryRemoved<A>(oldValue);\n\n    /// <summary>\n    /// Returns a `EntryAdded` state\n    /// </summary>\n    public static Change<A> Added(A value) => new EntryAdded<A>(value);\n\n    /// <summary>\n    /// Returns a `EntryMapped` state\n    /// </summary>\n    public static Change<A> Mapped<FROM>(FROM oldValue, A value) => new EntryMapped<FROM, A>(oldValue, value);\n        \n    /// <summary>\n    /// Equality\n    /// </summary>\n    public override bool Equals(object? obj) =>\n        obj is Change<A> rhs && Equals(rhs);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    public abstract bool Equals(Change<A>? obj);\n\n    /// <summary>\n    /// Hash code\n    /// </summary>\n    public override int GetHashCode() => FNV32.OffsetBasis;\n\n    public Change<A> Combine(Change<A> y) =>\n        (this, y) switch\n        {\n            (NoChange<A>, _)                                       => y,\n            (_, NoChange<A>)                                       => this,\n            (_, EntryRemoved<A>)                                   => y,\n            (EntryRemoved<A> (var vx), EntryAdded<A> (var vy))     => Mapped(vx, vy),\n            (EntryAdded<A>, EntryMappedTo<A>(var vz))              => Added(vz),\n            (EntryMappedFrom<A>(var vx), EntryMappedTo<A>(var vz)) => Mapped(vx, vz),\n            _                                                      => y\n        };\n\n    static Change<A> Monoid<Change<A>>.Empty =>\n        None;\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Change/EntryAdded.cs",
    "content": "﻿using System;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Entry added to a collection\n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic sealed class EntryAdded<A> :\n    Change<A>, \n    IEquatable<EntryAdded<A>>\n{\n    /// <summary>\n    /// Value that has been added\n    /// </summary>\n    public readonly A Value;\n\n    internal EntryAdded(A value) =>\n        Value = value;\n\n    public override bool Equals(Change<A>? obj) =>\n        obj is EntryAdded<A> rhs && Equals(rhs);\n\n    public bool Equals(EntryAdded<A>? rhs) =>\n        !ReferenceEquals(rhs, null) &&\n        EqDefault<A>.Equals(Value, rhs.Value);\n\n    public override int GetHashCode() =>\n        Value?.GetHashCode() ?? FNV32.OffsetBasis;\n\n    public void Deconstruct(out A value) =>\n        value = Value;\n\n    public override string ToString() => $\"+{Value}\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Change/EntryMapped.cs",
    "content": "﻿using System;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Existing entry updated to this value\n/// </summary>\n/// <typeparam name=\"B\">Value mapped to type</typeparam>\npublic interface EntryMappedTo<B>\n{\n    /// <summary>\n    /// Value mapped-to\n    /// </summary>\n    public B To { get; }\n\n    /// <summary>\n    /// Deconstructs to a single value\n    /// </summary>\n    void Deconstruct(out B @to);\n}\n    \n/// <summary>\n/// Existing entry updated from this value\n/// </summary>\n/// <typeparam name=\"A\">Value mapped from type</typeparam>\npublic interface EntryMappedFrom<A>\n{\n    /// <summary>\n    /// Value mapped-from\n    /// </summary>\n    public A From { get; }\n\n    /// <summary>\n    /// Deconstructs to a single value\n    /// </summary>\n    void Deconstruct(out A @from);\n}\n    \n/// <summary>\n/// Existing entry updated \n/// </summary>\npublic sealed class EntryMapped<A, B> : \n    Change<B>,\n    EntryMappedFrom<A>,\n    EntryMappedTo<B>,\n    IEquatable<EntryMapped<A, B>>\n{\n    internal EntryMapped(A @from, B to)\n    {\n        From = @from;\n        To = @to;\n    }\n\n    /// <summary>\n    /// Value mapped from \n    /// </summary>\n    public A From { get; }\n        \n    /// <summary>\n    /// Value mapped to\n    /// </summary>\n    public B To { get; }\n\n    public override bool Equals(Change<B>? obj) =>\n        obj is EntryMapped<A, B> rhs && Equals(rhs);\n\n    public bool Equals(EntryMapped<A, B>? rhs) =>\n        !ReferenceEquals(rhs, null)         &&\n        EqDefault<A>.Equals(From, rhs.From) &&\n        EqDefault<B>.Equals(To, rhs.To);\n\n    public override int GetHashCode() =>\n        FNV32.Next(\n            From?.GetHashCode() ?? FNV32.OffsetBasis,\n            To?.GetHashCode()   ?? FNV32.OffsetBasis);\n\n    public override string ToString() => $\"{From} -> {To}\";\n\n    public void Deconstruct(out B to) =>\n        to = To;\n\n    public void Deconstruct(out A @from) =>\n        @from = From;\n\n    public void Deconstruct(out A @from, out B to)\n    {\n        @from = From;\n        to = To;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Change/EntryRemoved.cs",
    "content": "﻿using System;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Existing entry removed \n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic sealed class EntryRemoved<A> : \n    Change<A>, \n    IEquatable<EntryRemoved<A>>\n{\n    /// <summary>\n    /// Value that was removed\n    /// </summary>\n    public readonly A OldValue;\n\n    internal EntryRemoved(A oldValue) =>\n        OldValue = oldValue;\n\n    public override bool Equals(Change<A>? obj) =>\n        obj is EntryRemoved<A> rhs && Equals(rhs);\n\n    public override int GetHashCode() => \n        OldValue?.GetHashCode() ?? FNV32.OffsetBasis;\n        \n    public bool Equals(EntryRemoved<A>? rhs) =>\n        !ReferenceEquals(rhs, null) &&\n        EqDefault<A>.Equals(OldValue, rhs.OldValue);\n\n    public void Deconstruct(out A oldValue)\n    {\n        oldValue = OldValue;\n    }\n        \n    public override string ToString() => $\"-{OldValue}\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Change/NoChange.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// No change to the collection\n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic sealed class NoChange<A> : \n    Change<A>, \n    IEquatable<NoChange<A>>\n{\n    /// <summary>\n    /// Singleton value of `NoChange`\n    /// </summary>\n    public static readonly Change<A> Default = new NoChange<A>();\n\n    private NoChange()\n    { }\n\n    public override bool Equals(Change<A>? obj) =>\n        obj is NoChange<A>;\n\n    public bool Equals(NoChange<A>? rhs) =>\n        rhs is not null;\n\n    public override int GetHashCode() => \n        FNV32.OffsetBasis;\n\n    public override string ToString() => $\"No Change\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Compositions/Compositions.Extensions.cs",
    "content": "﻿using LanguageExt;\nusing LanguageExt.Traits;\n\npublic static class CompositionsExt\n{\n    public static Compositions<A> Cons<A>(this A a, Compositions<A> ma) where A : Monoid<A> =>\n        Compositions.cons(a, ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Compositions/Compositions.Module.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing LanguageExt.Traits;\nusing System.Collections.Generic;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\npublic static class Compositions\n{\n    /// <summary>\n    /// Returns true if the given tree is appropriately right-biased.\n    /// </summary>\n    public static bool wellFormed<EqA, A>(Compositions<A> ca) \n        where EqA : Eq<A>\n        where A : Monoid<A> \n    {\n        bool wellFormedNode(int n, Compositions<A>.Node node)\n        {\n            var ni = node.Size;\n            if (n == 1                    && ni == 1 && node.Children.IsNone) return true;\n            else if (node.Children.IsSome && n  == ni)\n            {\n                var v = node.Value;\n                var (l, r) = ((Compositions<A>.Node, Compositions<A>.Node))node.Children;\n                return wellFormedNode(n / 2, l)                          &&\n                       EqA.Equals(v, l.Value.Combine(r.Value)) &&\n                       wellFormedNode(n / 2, r);\n            }\n            else\n            {\n                return false;\n            }\n        }\n\n        bool go(int m, Seq<Compositions<A>.Node> ma)\n        {\n            if (ma.IsEmpty) return true;\n            var x  = ma.Head.Value!;\n            var xs = ma.Tail;\n            var s  = x.Size;\n            return s >= m && wellFormedNode(s, x) && go(s * 2, xs);\n        }\n        return go(1, ca.Tree);\n    }\n\n    /// <summary>\n    /// Return the compositions list with the first `k` elements removed, in `O(log k)` time.\n    /// </summary>\n    public static Compositions<A> skip<A>(int amount, Compositions<A> compositions)\n        where A : Monoid<A>\n    {\n        Seq<Compositions<A>.Node> go(int n, Seq<Compositions<A>.Node> nodes)\n        {\n            if (nodes.IsEmpty) return nodes;\n            if (n <= 0) return nodes;\n            var s   = nodes.Head.Value!.Size;\n            var c   = nodes.Head.Value!.Children;\n            var ri  = nodes.Tail;\n            var ord = n.CompareTo(s);\n            if (ord < 0)\n            {\n                var (l, r) = ((Compositions<A>.Node, Compositions<A>.Node))c;\n                return go(n, l.Cons(r.Cons(ri)));\n            }\n            else\n            {\n                return go(n - s, ri);\n            }\n        }\n        return new Compositions<A>(go(amount, compositions.Tree));\n    }\n\n    /// <summary>\n    /// Return the compositions list containing only the first `k` elements\n    /// of the input.  In the worst case, performs `O(k log k)` element compositions,\n    /// in order to maintain the right-associative bias.  If you wish to run `composed`\n    /// on the result of `take`, use `takeComposed` for better performance.\n    /// </summary>\n    public static Compositions<A> take<A>(int amount, Compositions<A> compositions) where A : Monoid<A>\n    {\n        Seq<Compositions<A>.Node> go(int n, Seq<Compositions<A>.Node> nodes)\n        {\n            if (nodes.IsEmpty) return nodes;\n            if (n <= 0) return Seq<Compositions<A>.Node>();\n            var x   = nodes.Head.Value!;\n            var s   = x.Size;\n            var c   = x.Children;\n            var ri  = nodes.Tail;\n            var ord = n.CompareTo(s);\n            if (ord < 0)\n            {\n                var (l, r) = ((Compositions<A>.Node, Compositions<A>.Node))c;\n                return go(n, l.Cons(r.Cons(ri)));\n            }\n            else\n            {\n                return new Compositions<A>([x])\n                        .Combine(new Compositions<A>(go(n - s, ri)))\n                        .Tree;\n            }\n        }\n        return new Compositions<A>(go(amount, compositions.Tree));\n    }\n\n    /// <summary>\n    /// Returns the composition of the first `k` elements of the compositions list, doing only `O(log k)` compositions.\n    /// Faster than simply using `take` and then `composed` separately.\n    /// </summary>\n    public static A takeComposed<A>(int amount, Compositions<A> compositions) where A : Monoid<A>\n    {\n        A go(int n, Seq<Compositions<A>.Node> nodes)\n        {\n            if (nodes.IsEmpty) return A.Empty;\n            if (n <= 0) return A.Empty;\n            var x   = nodes.Head.Value!;\n            var s   = x.Size;\n            var c   = x.Children;\n            var v   = x.Value;\n            var ri  = nodes.Tail;\n            var ord = n.CompareTo(s);\n            if (ord < 0)\n            {\n                var (l, r) = ((Compositions<A>.Node, Compositions<A>.Node))c;\n                return go(n, l.Cons(r.Cons(ri)));\n            }\n            else\n            {\n                return v.Combine(go(n - s, ri));\n            }\n        }\n        return go(amount, compositions.Tree);\n    }\n\n    /// <summary>\n    /// A convenience alias for 'take' and 'drop'\n    /// </summary>\n    public static (Compositions<A> taken, Compositions<A> skipped) splitAt<A>(int i, Compositions<A> c)\n        where A : Monoid<A> =>\n        (take(i, c), skip(i, c));\n\n    /// <summary>\n    /// Compose every element in the compositions list. Performs only `O(log n)` compositions.\n    /// </summary>\n    public static A composed<A>(Compositions<A> compositions)\n        where A : Monoid<A> =>\n        FoldCompositions<A>.Fold(compositions, A.Empty, (x, y) => x.Combine(y))(unit);\n\n    /// <summary>\n    /// Construct a compositions list containing just one element.\n    /// </summary>\n    public static Compositions<A> singleton<A>(A value) \n        where A : Monoid<A> =>\n        new ([new Compositions<A>.Node(1, None, value)]);\n\n    /// <summary>\n    /// Get the number of elements in the compositions list, in `O(log n)` time.\n    /// </summary>\n    public static int count<A>(Compositions<A> compositions)\n        where A : Monoid<A> =>\n        compositions.Tree.Map(n => n.Size).Sum();\n\n    /// <summary>\n    /// Add a new element to the front of a compositions list. Performs `O(log n)` element compositions.\n    /// </summary>\n    public static Compositions<A> cons<A>(A x, Compositions<A> xs)\n        where A : Monoid<A> =>\n        singleton(x).Combine(xs);\n\n    /// <summary>\n    /// Convert a compositions list into a list of elements. The other direction\n    /// is provided in the 'Data.Foldable.Foldable' instance.This will perform O(n log n) element compositions.\n    /// </summary>\n    public static Compositions<A> fromList<A>(IEnumerable<A> ma)\n        where A : Monoid<A> =>\n        ma.AsIterable().Fold(Compositions<A>.Empty, (s, x) => s.Combine(singleton(x)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Compositions/Compositions.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing LanguageExt.Traits;\nusing System.Collections.Generic;\nusing LanguageExt.ClassInstances;\nusing System.Collections;\nusing System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A _compositions list_ or _composition tree_ is a list data type where the elements are monoids, \n/// and the 'mconcat' of any contiguous sublist can be computed in logarithmic time.\n/// \n/// A common use case of this type is in a wiki, version control system, or collaborative editor, where \n/// each change or delta would be stored in a list, and it is sometimes necessary to compute the composed \n/// delta between any two versions.\n///\n/// This version of a composition list is strictly biased to right-associativity, in that we only support \n/// efficient consing to the front of the list. This also means that the 'take' operation can be inefficient. \n/// \n/// The append operation `append(a, b)` performs `O(a log (a + b))` element compositions, so you want\n/// the left-hand list `a` to be as small as possible.\n/// </summary>\npublic struct Compositions<A> : \n    IEquatable<Compositions<A>>, \n    IEnumerable<A>, \n    Monoid<Compositions<A>> \n    where A : Monoid<A>\n{\n    public static Compositions<A> Empty { get; } = new(Seq<Node>());\n\n    public readonly Seq<Node> Tree;\n    int? hashCode;\n\n    internal Compositions(Seq<Node> tree)\n    {\n        hashCode = null;\n        Tree = tree;\n    }\n\n    public Compositions<A> Combine(Compositions<A> compy)\n    {\n        var compx = this;\n        Seq<Node> go(Seq<Node> mx, Seq<Node> my)\n        {\n            if (mx.IsEmpty) return my;\n            if (my.IsEmpty) return go(mx.Tail, [mx.Head.Value!]);\n\n            var x  = mx.Head.Value!;\n            var sx = mx.Head.Value!.Size;\n            var cx = mx.Head.Value!.Children;\n            var vx = mx.Head.Value!.Value;\n            var xs = mx.Tail;\n\n            var y  = my.Head.Value!;\n            var sy = my.Head.Value!.Size;\n            var vy = my.Head.Value!.Value;\n            var ys = my.Tail;\n\n            var ord = sx.CompareTo(sy);\n            if (ord      < 0) return go(xs, x.Cons(my));\n            else if (ord > 0)\n            {\n                var (l, r) = ((Node, Node))cx;\n                return go(r.Cons(l.Cons(xs)), my);\n            }\n            else\n            {\n                return go(new Node(sx + sy, Some((x, y)), vx.Combine(vy)).Cons(xs), ys);\n            }\n        }\n        return new Compositions<A>(go(compx.Tree, compy.Tree));\n    }\n    \n    /// <summary>\n    /// Returns true if the given tree is appropriately right-biased.\n    /// </summary>\n    public bool WellFormed<EqA>() \n        where EqA : Eq<A> =>\n        Compositions.wellFormed<EqA, A>(this);\n\n    /// <summary>\n    /// Return the compositions list with the first `k` elements removed, in `O(log k)` time.\n    /// </summary>\n    public Compositions<A> Skip(int amount) =>\n        Compositions.skip(amount, this);\n\n    /// <summary>\n    /// Return the compositions list containing only the first `k` elements\n    /// of the input.  In the worst case, performs `O(k log k)` element compositions,\n    /// in order to maintain the right-associative bias.  If you wish to run `composed`\n    /// on the result of `take`, use `takeComposed` for better performance.\n    /// </summary>\n    public Compositions<A> Take(int amount) =>\n        Compositions.take(amount, this);\n\n    /// <summary>\n    /// Returns the composition of the first `k` elements of the compositions list, doing only `O(log k)` compositions.\n    /// Faster than simply using `take` and then `composed` separately.\n    /// </summary>\n    public A TakeComposed(int amount) =>\n        Compositions.takeComposed(amount, this);\n\n    /// <summary>\n    /// A convenience alias for 'take' and 'skip'\n    /// </summary>\n    public (Compositions<A> taken, Compositions<A> skipped) SplitAt(int i) =>\n        Compositions.splitAt(i, this);\n\n    /// <summary>\n    /// Compose every element in the compositions list. Performs only `O(log n)` compositions.\n    /// </summary>\n    public A Composed() =>\n        Compositions.composed(this);\n\n    /// <summary>\n    /// Construct a compositions list containing just one element.\n    /// </summary>\n    public static Compositions<A> Singleton(A value) =>\n        Compositions.singleton(value);\n\n    /// <summary>\n    /// Get the number of elements in the compositions list, in `O(log n)` time.\n    /// </summary>\n    public int Count() =>\n        Compositions.count(this);\n\n    /// <summary>\n    /// Convert a compositions list into a list of elements. The other direction\n    /// is provided in the 'Data.Foldable.Foldable' instance.This will perform O(n log n) element compositions.\n    /// </summary>\n    public static Compositions<A> FromList(IEnumerable<A> ma) =>\n        Compositions.fromList(ma);\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public bool Equals(Compositions<A> b) =>\n        EqEnumerable<A>.Equals(this, b);\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public override bool Equals(object? obj) =>\n        obj is Compositions<A> b && Equals(b);\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public static bool operator ==(Compositions<A> a, Compositions<A> b) =>\n        a.Equals(b);\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public static bool operator !=(Compositions<A> a, Compositions<A> b) =>\n        !(a == b);\n\n    /// <summary>\n    /// Get hash code\n    /// </summary>\n    /// <returns></returns>\n    public override int GetHashCode() =>\n        hashCode ?? (int)(hashCode = hash(this));\n\n    /// <summary>\n    /// Convert to a sequence\n    /// </summary>\n    public Seq<A> ToSeq() =>\n        FoldCompositions<A>.Fold(this, Seq<A>(), (s, x) => x.Cons(s))(unit);\n\n    /// <summary>\n    /// Convert to an enumerable\n    /// </summary>\n    public Iterable<A> AsIterable() =>\n        FoldCompositions<A>.Fold(this, Seq<A>(), (s, x) => x.Cons(s))(unit).AsIterable();\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    public IEnumerator<A> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsIterable().GetEnumerator();\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsIterable().GetEnumerator();\n\n    public class Node\n    {\n        public readonly int Size;\n        public readonly Option<(Node, Node)> Children;\n        public readonly A Value;\n\n        public Node(int size, Option<(Node, Node)> children, A value)\n        {\n            Size = size;\n            Children = children;\n            Value = value;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Compositions/FoldCompositions.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing LanguageExt.Traits;\nusing System;\n\nnamespace LanguageExt.ClassInstances;\n\npublic struct FoldCompositions<A>\n    where A : Monoid<A>\n{\n    static S FoldNode<S>(S state, Func<S, A, S> f, Compositions<A>.Node node)\n    {\n        if (node.Children.IsNone) return f(state, node.Value);\n        var (l, r) = ((Compositions<A>.Node, Compositions<A>.Node))node.Children;\n        state      = FoldNode(state, f, l);\n        state      = FoldNode(state, f, r);\n        return state;\n    }\n\n    static S FoldNodes<S>(S state, Func<S, A, S> f, Seq<Compositions<A>.Node> nodes) =>\n        nodes.Fold(state, (s, n) => FoldNode(s, f, n));\n\n    static S FoldNodeBack<S>(S state, Func<S, A, S> f, Compositions<A>.Node node)\n    {\n        if (node.Children.IsNone) return f(state, node.Value);\n        var (l, r) = ((Compositions<A>.Node, Compositions<A>.Node))node.Children;\n        state      = FoldNode(state, f, r);\n        state      = FoldNode(state, f, l);\n        return state;\n    }\n\n    static S FoldNodesBack<S>(S state, Func<S, A, S> f, Seq<Compositions<A>.Node> nodes) =>\n        nodes.FoldBack(state, (s, n) => FoldNode(s, f, n));\n\n    internal static Seq<B> FoldMap<B>(Func<A, B> f, Seq<Compositions<A>.Node> nodes) =>\n        FoldNodes(Seq<B>(), (s, n) => f(n).Cons(s), nodes);\n\n    internal static Seq<B> FoldMapBack<B>(Func<A, B> f, Seq<Compositions<A>.Node> nodes) =>\n        FoldNodesBack(Seq<B>(), (s, n) => f(n).Cons(s), nodes);\n\n    public static Func<Unit, int> Count(Compositions<A> fa) => _ =>\n        FoldNodes(0, (s, _) => s + 1, fa.Tree);\n\n    public static Func<Unit, S> Fold<S>(Compositions<A> fa, S state, Func<S, A, S> f) => _ =>\n        FoldNodes(state, f, fa.Tree);\n\n    public static Func<Unit, S> FoldBack<S>(Compositions<A> fa, S state, Func<S, A, S> f) => _ =>\n        FoldNodesBack(state, f, fa.Tree);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Fail/Fail.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class FailExtensions\n{\n    extension<A>(Fail<A> lhs)\n    {\n        /// <summary>\n        /// Value extraction\n        /// </summary>\n        public static A operator >>(Fail<A> px, Lower _) =>\n            px.Value;\n    }\n\n    extension<A, B>(Fail<A> lhs)\n    {\n        /// <summary>\n        /// Function composition\n        /// </summary>\n        /// <param name=\"x\">Input</param>\n        /// <param name=\"f\">Function</param>\n        /// <returns>Result of invoking the function</returns>\n        public static Fail<B> operator >>(Fail<A> x, Func<A, B> f) =>\n            new (f(x.Value));\n    }     \n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Conversion\n    //\n    \n    public static Validation<F, A> ToValidation<F, A>(this Fail<F> fail) \n        where F : Monoid<F> =>\n        Validation.Fail<F, A>(fail.Value);\n    \n    extension(Fail<Error> fail)\n    {\n        public Fin<A> ToFin<A>() =>\n            Fin.Fail<A>(fail.Value);\n        \n        public Eff<RT, A> ToEff<RT, A>() =>\n            Eff<RT, A>.Fail(fail.Value);\n\n        public Eff<A> ToEff<A>() =>\n            Eff<A>.Fail(fail.Value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Fail/Fail.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents an error value.  \n/// </summary>\n/// <remarks>\n/// On its own this doesn't do much, but  allows other monads to convert\n/// from it and provide binding extensions that mean it can be lifted into\n/// other monads without specifying lots of extra generic arguments.\n/// </remarks>\n/// <param name=\"Value\">Bound value</param>\n/// <typeparam name=\"E\">Bound value type</typeparam>\npublic readonly record struct Fail<E>(E Value)\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Standard operators\n    //\n\n    public Fail<F> MapFail<F>(Func<E, F> f) =>\n        new(f(Value));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Conversion\n    //\n\n    public Either<E, A> ToEither<A>() =>\n        Either.Left<E, A>(Value);\n\n    public override string ToString() =>\n        $\"Fail({Value})\";\n\n    public Either<E, C> SelectMany<B, C>(Func<Unit, Pure<B>> bind, Func<Unit, B, C> project) =>\n        this;\n\n    public Option<C> SelectMany<B, C>(Func<Unit, Option<B>> bind, Func<Unit, B, C> project) =>\n        default;\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Loop/Loop.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class LoopExtensions\n{\n    extension<A>(Loop<A> lhs)\n    {\n        /// <summary>\n        /// Value extraction\n        /// </summary>\n        public static A operator >>(Loop<A> px, Lower _) =>\n            px.Value;\n    }\n\n    extension<A, B>(Loop<A> lhs)\n    {\n        /// <summary>\n        /// Function composition\n        /// </summary>\n        /// <param name=\"x\">Input</param>\n        /// <param name=\"f\">Function</param>\n        /// <returns>Result of invoking the function</returns>\n        public static Loop<B> operator >>(Loop<A> x, Func<A, B> f) =>\n            new (f(x.Value));\n    }   \n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Loop/Loop.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    [Pure]\n    public static Loop<A> Loop<A>(A value) => \n        new (value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Loop/Loop.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents a value to use in tail-recursive loops.  Usually understood to be the value t\n/// pass to the next stage of the loop so it can continue (and either generated by the previous\n/// loop-stage or is the initial trigger-value.\n/// </summary>\n/// <see cref=\"LanguageExt.Next\"/>\n/// <remarks>\n/// On its own this doesn't do much, but  allows other types to convert from it and provide\n/// binding extensions that mean it can be lifted into other monads without specifying lots\n/// of extra generic arguments.\n/// </remarks>\n/// <param name=\"Value\">Bound value</param>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic readonly record struct Loop<A>(A Value)\n{\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Result bound value type</typeparam>\n    /// <returns>Result of the applying the mapping function to the `Pure` value</returns>\n    public Loop<B> Map<B>(Func<A, B> f) =>\n        new (f(Value));\n\n    /// <summary>\n    /// Convert to a `Next` value\n    /// </summary>\n    public Next<A, B> ToNext<B>() =>\n        Next.Loop<A, B>(Value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Lower/Lower.cs",
    "content": "namespace LanguageExt;\n\npublic readonly record struct Lower;\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/MapPatch/HashMapPatch.cs",
    "content": "﻿using System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents change to a Hash-Map\n/// </summary>\n/// <remarks>\n/// This is primarily used by the `Change` events on the `AtomHashMap` types,\n/// and the `Changes` property of `TrackingHashMap`. \n/// </remarks>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\npublic sealed class HashMapPatch<K, V>\n{\n    readonly TrieMap<EqDefault<K>, K, V> prev;\n    readonly TrieMap<EqDefault<K>, K, V> curr;\n    readonly TrieMap<EqDefault<K>, K, Change<V>>? changes;\n    readonly K? key;\n    readonly Change<V>? change;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal HashMapPatch(\n        TrieMap<EqDefault<K>, K, V> prev,\n        TrieMap<EqDefault<K>, K, V> curr,\n        TrieMap<EqDefault<K>, K, Change<V>> changes)\n    {\n        this.prev = prev;\n        this.curr = curr;\n        this.changes = changes;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal HashMapPatch(\n        TrieMap<EqDefault<K>, K, V> prev,\n        TrieMap<EqDefault<K>, K, V> curr,\n        K key,\n        Change<V> change)\n    {\n        this.prev = prev;\n        this.curr = curr;\n        this.key = key;\n        this.change = change;\n    }\n\n    public HashMap<K, V> From\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new(prev);\n    }\n\n    public HashMap<K, V> To\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new(curr);\n    }\n\n    public HashMap<K, Change<V>> Changes\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => changes is null\n                   ? HashMap<K, Change<V>>.Empty.Add(key!, change!)\n                   : new HashMap<K, Change<V>>(changes);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() => \n        Changes.ToString();\n}\n  \n/// <summary>\n/// Represents change to a Hash-Map\n/// </summary>\n/// <remarks>\n/// This is primarily used by the `Change` events on the `AtomHashMap` types,\n/// and the `Changes` property of `TrackingHashMap`. \n/// </remarks>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\npublic sealed class HashMapPatch<EqK, K, V>\n    where EqK : Eq<K>\n{\n    readonly TrieMap<EqK, K, V> prev;\n    readonly TrieMap<EqK, K, V> curr;\n    readonly TrieMap<EqK, K, Change<V>>? changes;\n    readonly K? key;\n    readonly Change<V>? change;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal HashMapPatch(\n        TrieMap<EqK, K, V> prev,\n        TrieMap<EqK, K, V> curr,\n        TrieMap<EqK, K, Change<V>> changes)\n    {\n        this.prev = prev;\n        this.curr = curr;\n        this.changes = changes;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal HashMapPatch(\n        TrieMap<EqK, K, V> prev,\n        TrieMap<EqK, K, V> curr,\n        K key,\n        Change<V> change)\n    {\n        this.prev = prev;\n        this.curr = curr;\n        this.key = key;\n        this.change = change;\n    }\n \n    public HashMap<EqK, K, V> From\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new (prev);\n    }\n\n    public HashMap<EqK, K, V> To\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new (curr);\n    }\n\n    public HashMap<EqK, K, Change<V>> Changes\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => changes is null\n                   ? HashMap<EqK, K, Change<V>>.Empty.Add(key!, change!) \n                   : new HashMap<EqK, K, Change<V>>(changes);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() => \n        Changes.ToString();\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Next/Next.Module.cs",
    "content": "namespace LanguageExt;\n\n/// <summary>\n/// Module for the `Next` data-type\n/// </summary>\npublic static class Next\n{\n    /// <summary>\n    /// Continue the recursion\n    /// </summary>\n    /// <param name=\"value\">Value to pass back to the recursive function to 'go around'</param>\n    /// <typeparam name=\"A\">Loop value type</typeparam>\n    /// <typeparam name=\"B\">Done value type</typeparam>\n    /// <returns>Next structure</returns>\n    public static Next<A, B> Loop<A, B>(A value) =>\n        new (1, value, default!);\n    \n    /// <summary>\n    /// Cancel the recursion and return\n    /// </summary>\n    /// <param name=\"value\">Final value</param>\n    /// <typeparam name=\"A\">Loop value type</typeparam>\n    /// <typeparam name=\"B\">Loop value type</typeparam>\n    /// <returns>Next structure</returns>\n    public static Next<A, B> Done<A, B>(B value) =>\n        new (2, default!, value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Next/Next.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Simple data type that helps indicate whether a recursive function should loop or not.\n/// </summary>\n/// <remarks>\n/// This was created to pair with the `Monad` trait `Tail` function and is extremely lightweight.\n/// </remarks>\n/// <remarks>\n/// It's designed to cause no additional allocations when used in a tail-recursive manner.  That does mean there\n/// are some footguns in here if you're not careful.  So, make sure that before you access `Loop` or `Done`\n/// that you've confirmed the state of the structure by using `IsLoop` or `IsDone`.\n///\n/// You can then use C#'s pattern-matching to extract the value from the structure:\n///\n///     var result = next switch\n///     {\n///         { IsLoop: true, Loop: var value } => ...,\n///         { IsDone: true, Done: var value } => ...,\n///         _                                 => throw new Exception(\"Invalid state\")   \n///     };\n/// </remarks>\n/// <remarks>\n/// If we ever get real struct discriminated unions, then this can be replaced with that.\n/// </remarks>\n/// <typeparam name=\"A\">Loop value type</typeparam>\n/// <typeparam name=\"B\">Done value type</typeparam>\npublic readonly struct Next<A, B>\n{\n    readonly int state;\n    readonly A left;\n    readonly B right;\n\n    internal static Next<A, B> UnsafeDefault = default;\n    \n    internal Next(int state, A left, B right)\n    {\n        this.state = state;\n        this.left = left;\n        this.right = right;\n    }\n\n    /// <summary>\n    /// Pattern match\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public C Match<C>(Func<A, C> Loop, Func<B, C> Done) =>\n        IsLoop \n            ? Loop(left) \n            : IsDone\n                ? Done(right)\n                : throw new BottomException();\n\n    public Next<A, C> Map<C>(Func<B, C> f) =>\n        state switch\n        {\n            1 => new Next<A, C>(state, left, default!),\n            2 => new Next<A, C>(state, left, f(right)),\n            _ => throw new BottomException()\n        };\n    \n    public Either<A, B> ToEither() =>\n        state switch\n        {\n            1 => Left(left),\n            2 => Right(right),\n            _ => throw new BottomException()\n        };\n    \n    /// <summary>\n    /// Returns true if we should loop\n    /// </summary>\n    public bool IsLoop\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => state == 1;\n    }\n\n    /// <summary>\n    /// Returns true if we should complete and return\n    /// </summary>\n    public bool IsDone\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => state == 2;\n    }\n\n    /// <summary>\n    /// Try to access the loop-value type\n    /// </summary>\n    /// <returns>Either a valid `A` value or will throw an exception</returns>\n    /// <exception cref=\"InvalidCastException\">Throws if the structure is in a done state</exception>\n    public A Loop\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => state == 1\n                   ? left\n                   : throw new InvalidCastException();\n    }\n\n    /// <summary>\n    /// Try to access the done-value type\n    /// </summary>\n    /// <returns>Either a valid `B` value or will throw an exception</returns>\n    /// <exception cref=\"InvalidCastException\">Throws if the structure is in a done state</exception>\n    public B Done\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => state == 2\n                   ? right\n                   : throw new InvalidCastException();\n    }\n\n    /// <summary>\n    /// Explicit cast to the complete value type\n    /// </summary>\n    /// <param name=\"next\">Next structure</param>\n    /// <returns>Either a valid `A` value or will throw an exception</returns>\n    /// <exception cref=\"InvalidCastException\">Throws if the structure is in a done state</exception>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static explicit operator A(Next<A, B> next) =>\n        next.Loop;\n\n    /// <summary>\n    /// Explicit cast to the complete value type\n    /// </summary>\n    /// <param name=\"next\">Next structure</param>\n    /// <returns>Either a valid `A` value or will throw an exception</returns>\n    /// <exception cref=\"InvalidCastException\">Throws if the structure is in a done state</exception>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static explicit operator B(Next<A, B> next) =>\n        next.Done;\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Next<A, B>(Loop<A> value) =>\n        Next.Loop<A, B>(value.Value);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Next<A, B>(Pure<B> value) =>\n        Next.Done<A, B>(value.Value);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Next<A, B>(Either<A, B> value) =>\n        value switch\n        {\n            Either<A, B>.Left(var l)  => Next.Loop<A, B>(l),\n            Either<A, B>.Right(var r) => Next.Done<A, B>(r),\n            _                         => throw new BottomException()\n        };\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Either<A, B>(Next<A, B> value) =>\n        value.ToEither();\n    \n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Patch/Edit.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Data type that represents an edit in a patch.  Supports three sub-class 'cases':\n/// \n///     Edit.Insert\n///     Edit.Delete\n///     Edit.Replace\n///     \n/// These represent the total set of operations that can be represented in a `Patch`\n/// </summary>\n/// <typeparam name=\"EqA\"></typeparam>\n/// <typeparam name=\"A\"></typeparam>\npublic abstract class Edit<EqA, A> : IEquatable<Edit<EqA, A>> where EqA : Eq<A>\n{\n    public readonly int Position;\n    public readonly A Element;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    Edit(int position, A element)\n    {\n        Position = position;\n        Element = element;\n    }\n\n    /// <summary>\n    /// Position lens that allows for the Position to be modified\n    /// </summary>\n    internal abstract Edit<EqA, A> Index(Func<int, int> f);\n\n    /// <summary>\n    /// Maps the outgoing value using the function provided.  This has\n    /// no effect on Insert\n    /// </summary>\n    public abstract Edit<EqA, A> MapOld(Func<A, A> f);\n\n    /// <summary>\n    /// Maps the new value using the function provided.  This has\n    /// no effect on Delete\n    /// </summary>\n    public abstract Edit<EqA, A> MapNew(Func<A, A> f);\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public override bool Equals(object? obj) => \n        obj is Edit<EqA, A> edit && Equals(edit);\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public static bool operator ==(Edit<EqA, A> a, Edit<EqA, A> b) => a.Equals(b);\n\n    /// <summary>\n    /// Non-equality operator\n    /// </summary>\n    public static bool operator !=(Edit<EqA, A> a, Edit<EqA, A> b) => !(a == b);\n\n    /// <summary>\n    /// Hash code provider\n    /// </summary>\n    public override int GetHashCode() => \n        (Position + 13) * Element!.GetHashCode();\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public bool Equals(Edit<EqA, A>? other) =>\n        ReferenceEquals(this, other) ||\n        (Position  == other?.Position &&\n         GetType() == other.GetType() &&\n         EqA.Equals(Element, other.Element));\n\n    /// <summary>\n    /// Represents an Insert edit operation\n    /// </summary>\n    public sealed class Insert : Edit<EqA, A>, IEquatable<Insert>\n    {\n        public Insert(int position, A element) : base(position, element) { }\n        public static Insert New(int position, A element) => new Insert(position, element);\n        public override string ToString() => $\"Insert({Position}, {Element})\";\n        internal override Edit<EqA, A> Index(Func<int, int> f) => new Insert(f(Position), Element);\n        public override Edit<EqA, A> MapOld(Func<A, A> f) => this;\n        public override Edit<EqA, A> MapNew(Func<A, A> f) => new Insert(Position, f(Element));\n        public bool Equals(Insert? other) => base.Equals(other);\n        public override bool Equals(object? obj) => obj is Insert ins && Equals(ins);\n        public static bool operator ==(Insert a, Insert b) => a.Equals(b);\n        public static bool operator !=(Insert a, Insert b) => !(a == b);\n        public override int GetHashCode() => (Position + 13) * (Element!.GetHashCode() + 7);\n    }\n\n    /// <summary>\n    /// Represents an Delete edit operation\n    /// </summary>\n    public sealed class Delete : Edit<EqA, A>, IEquatable<Delete>\n    {\n        public Delete(int position, A element) : base(position, element) { }\n        public static Delete New(int position, A element) => new Delete(position, element);\n        public override string ToString() => $\"Delete({Position}, {Element})\";\n        internal override Edit<EqA, A> Index(Func<int, int> f) => new Delete(f(Position), Element);\n        public override Edit<EqA, A> MapOld(Func<A, A> f) => new Delete(Position, f(Element));\n        public override Edit<EqA, A> MapNew(Func<A, A> f) => this;\n        public bool Equals(Delete? other) => base.Equals(other);\n        public override bool Equals(object? obj) => obj is Delete del && Equals(del);\n        public static bool operator ==(Delete a, Delete b) => a.Equals(b);\n        public static bool operator !=(Delete a, Delete b) => !(a == b);\n        public override int GetHashCode() => (Position + 13) * (Element!.GetHashCode() + 7);\n    }\n\n    /// <summary>\n    /// Represents an Replace edit operation\n    /// </summary>\n    public sealed class Replace : Edit<EqA, A>, IEquatable<Replace>\n    {\n        public readonly A ReplaceElement;\n        public Replace(int position, A element, A replaceElement) : base(position, element) =>\n            ReplaceElement = replaceElement;\n        public static Replace New(int position, A element, A replaceElement) => new (position, element, replaceElement);\n        public override string ToString() => $\"Replace({Position}, {Element} -> {ReplaceElement})\";\n        internal override Edit<EqA, A> Index(Func<int, int> f) => new Replace(f(Position), Element, ReplaceElement);\n        public override Edit<EqA, A> MapOld(Func<A, A> f) => new Replace(Position, f(Element), ReplaceElement);\n        public override Edit<EqA, A> MapNew(Func<A, A> f) => new Replace(Position, Element, f(ReplaceElement));\n        public bool Equals(Replace? other) =>\n            ReferenceEquals(this, other) ||\n            (base.Equals(other) && EqA.Equals(ReplaceElement, other.ReplaceElement));\n        public override bool Equals(object? obj) => obj is Replace repl && Equals(repl);\n        public static bool operator ==(Replace a, Replace b) => a.Equals(b);\n        public static bool operator !=(Replace a, Replace b) => !(a == b);\n        public override int GetHashCode() => (Position + 13) * (Element!.GetHashCode() + 17) * (ReplaceElement!.GetHashCode() + 7);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Patch/Patch.Internal.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing System;\nusing System.Linq;\n\nnamespace LanguageExt;\n\ninternal static class PatchInternal\n{\n    public static (A, Seq<C>) mapAccumR<A, B, C>(Func<A, B, (A, C)> f, A state, Seq<B> t)\n    {\n        if (t.IsEmpty) return (state, Seq<C>());\n        var (a1, c1) = mapAccumR(f, state, t.Tail);\n        var (a, c) = f(a1, t.Head.Value!);\n        return (a, c.Cons(c1));\n    }\n\n    public static (A, Seq<C>) mapAccumL<A, B, C>(Func<A, B, (A, C)> f, A state, Seq<B> t)\n    {\n        if (t.IsEmpty) return (state, Seq<C>());\n        var (a, c)   = f(state, t.Head.Value!);\n        var (a1, c1) = mapAccumL(f, a, t.Tail);\n        return (a1, c.Cons(c1));\n    }\n\n    public static (C, Seq<O>) leastChanges<OrdC, V, O, C>(PatchParams<V, O, C> p, SpanArray<V> ss, SpanArray<V> tt)\n        where OrdC : Ord<C>\n        where C : Monoid<C>\n    {\n        var rawChanges = rawChanges<OrdC, V, O, C>(p, ss, tt);\n        var changes    = rawChanges.Last;\n        var newlst     = changes.Map(pair => toSeq(pair.Item2.Somes().Reverse()));\n        return (changes.Item1, newlst);\n    }\n\n    static (int quot, int rem) quotRem(int x, int y) =>\n        (x / y, x % y);\n\n    static A minimumBy<A>(Func<A, A, int> compare, Lst<A> list) =>\n        list.Count == 0\n            ? throw new Exception(\"List is empty\")\n            : list.Fold(list[0], (x, y) => compare(x, y) > 0 ? y : x);\n\n    static SpanArray<A> constructN<A>(int n, Func<SpanArray<A>, A> f)\n    {\n        var vector = SpanArray<A>.New(n);\n        for (var i = 0; i < n; i++)\n        {\n            var slice = vector.Slice(0, i);\n            var x     = f(slice);\n            vector[i] = x;\n        }\n        return vector;\n    }\n\n    public static SpanArray<(C, Seq<Option<O>>)> rawChanges<OrdC, V, O, C>(PatchParams<V, O, C> p, SpanArray<V> src, SpanArray<V> dst)\n        where OrdC : Ord<C>\n        where C : Monoid<C>\n    {\n        var lenX = 1 + dst.Count;\n        var lenY = 1 + src.Count;\n        var lenN = lenX * lenY;\n\n        int ix(int x, int y) => x * lenY + y;\n\n        (C, Seq<Option<O>>) get(SpanArray<(C, Seq<Option<O>>)> m, int x, int y)\n        {\n            int i = ix(x, y);\n            return i < m.Count\n                       ? m[i]\n                       : throw new Exception($\"Unable to get ({x},{y}) from change matrix\");\n        }\n\n        int position(Seq<Option<O>> seq) =>\n            seq.Map(oo => oo.Map(p.positionOffset).IfNone(1)).Sum();\n\n        (C, Seq<Option<O>>) ctr(SpanArray<(C, Seq<Option<O>>)> v)\n        {\n            var (quot, rem) = quotRem(v.Count, lenY);\n\n            if (quot == 0 && rem == 0)\n            {\n                return (C.Empty, Seq<Option<O>>());\n            }\n            else if (quot == 0)\n            {\n                var y = rem - 1;\n                var o = p.delete(0, src[y]);\n                var (pc, po) = get(v, 0, y);\n                return (p.cost(o).Combine(pc), Some(o).Cons(po));\n            }\n            else if (rem == 0)\n            {\n                var x = quot - 1;\n                var o = p.insert(x, dst[x]);\n                var (pc, po) = get(v, x, 0);\n                return (p.cost(o).Combine(pc), Some(o).Cons(po));\n            }\n            else\n            {\n                var y    = rem  - 1;\n                var x    = quot - 1;\n                var s    = src[y];\n                var d    = dst[x];\n                var tl   = get(v, x, y);\n                var top  = get(v, x    + 1, y);\n                var left = get(v, x, y + 1);\n                if (p.equivalent(s, d))\n                {\n                    return (tl.Item1, Prelude.Cons(None, tl.Item2));\n                }\n                else\n                {\n                    var c1    = p.delete(position(top.Item2), s);\n                    var item1 = (p.cost(c1).Combine(top.Item1), Some(c1).Cons(top.Item2));\n\n                    var c2    = p.insert(position(left.Item2), d);\n                    var item2 = (p.cost(c2).Combine(left.Item1), Some(c2).Cons(left.Item2));\n\n                    var c3    = p.substitute(position(tl.Item2), s, d);\n                    var item3 = (p.cost(c3).Combine(tl.Item1), Some(c3).Cons(tl.Item2));\n\n                    var compare = OrdTupleFirst<OrdC, C, Seq<Option<O>>>.Compare;\n\n                    return minimumBy(compare, List(item1, item2, item3));\n                }\n            }\n        }\n        return constructN<(C, Seq<Option<O>>)>(lenN, ctr);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Patch/Patch.Module.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing LanguageExt.Traits;\nusing System;\nusing System.Linq;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A `Patch` is a collection of edits performed to a _document_, in this case an 'IEnumerable〈A〉'. \n/// They are implemented as a list of 'Edit', and can be converted to and from raw lists of edits using \n/// `toList` and `fromList` respectively.\n/// \n/// Patches form a groupoid (a 'Monoid' with inverses, and a partial composition relation), where the \n/// inverse element can be computed with 'inverse' and the groupoid operation is a _composition_ of \n/// patches.  Applying `append(p1, p2)` is the same as applying `p1` _then_\n/// `p2` (see `Patch.apply`). This composition operator may produce structurally different patches depending \n/// on associativity, however the patches are guaranteed to be _equivalent_ in the sense that the resultant \n/// document will be the same when they are applied.\n/// \n/// For convenience, we make our composition operator here total, to fit the `Monoid` typeclass, but provide \n/// some predicates (`Patch.composable` and `Patch.applicable`) to determine if the operation can be validly \n/// used.\n/// </summary>\npublic static class Patch\n{\n    /// <summary>\n    /// Convert a list of edits to a patch, making sure to eliminate conflicting edits \n    /// and sorting by index.\n    /// </summary>\n    public static Patch<EqA, A> unsafeFromSeq<EqA, A>(Seq<Edit<EqA, A>> edits) where EqA : Eq<A> =>\n        new (edits);\n\n    /// <summary>\n    /// Convert a list of edits to a patch, making sure to eliminate conflicting edits \n    /// and sorting by index.\n    /// </summary>\n    public static Patch<EqA, A> fromSeq<EqA, A>(Seq<Edit<EqA, A>> edits) where EqA : Eq<A> =>\n        new (toSeq((from es in normalise(edits)\n                    group es by es.Position into eg\n                    from ed in eg.Distinct()\n                    orderby ed.Position\n                    select ed).ToArray()));\n\n    /// <summary>\n    /// Internal: Eliminate conflicting edits\n    /// </summary>\n    internal static Seq<Edit<EqA, A>> normalise<EqA, A>(Seq<Edit<EqA, A>> edits) where EqA : Eq<A>\n    {\n        var (inss, dels, repls) = partition3(edits);\n        return normalise1(inss, dels, repls);\n            \n        static (Seq<Edit<EqA, A>.Insert> inserts, Seq<Edit<EqA, A>.Delete> deletes, Seq<Edit<EqA, A>.Replace> replaces) partition3(Seq<Edit<EqA, A>> grp)\n        {\n            if (grp.IsEmpty) return (Seq<Edit<EqA, A>.Insert>(), Seq<Edit<EqA, A>.Delete>(), Seq<Edit<EqA, A>.Replace>());\n            if (grp.Head.Value! is Edit<EqA, A>.Insert ins)\n            {\n                var (i, d, r) = partition3(grp.Tail);\n                return (ins.Cons(i), d, r);\n            }\n            else if (grp.Head.Value! is Edit<EqA, A>.Delete del)\n            {\n                var (i, d, r) = partition3(grp.Tail);\n                return (i, del.Cons(d), r);\n            }\n            else if (grp.Head.Value! is Edit<EqA, A>.Replace repl)\n            {\n                var (i, d, r) = partition3(grp.Tail);\n                return (i, d, repl.Cons(r));\n            }\n            else\n            {\n                throw new NotSupportedException();\n            }\n        }\n\n        static Seq<Edit<EqA, A>> normalise1(Seq<Edit<EqA, A>.Insert> inserts, Seq<Edit<EqA, A>.Delete> deletes, Seq<Edit<EqA, A>.Replace> replaces)\n        {\n            if (!inserts.IsEmpty && !deletes.IsEmpty) return normalise1(inserts.Tail, deletes.Tail, Edit<EqA, A>.Replace.New(deletes.Head.Value!.Position, deletes.Head.Value!.Element, inserts.Head.Value!.Element).Cons(replaces));\n            if (deletes.IsEmpty) return toSeq(inserts.Map(i => i as Edit<EqA, A>).ConcatFast(replaces.Take(1)).ToArray());\n            if (inserts.IsEmpty) return [deletes.Head.Value!];\n            throw new InvalidOperationException();\n        }\n    }\n\n    /// <summary>\n    /// Monoid append: produces a patch is a merged version of both provided\n    /// patches.  \n    /// </summary>\n    public static Patch<EqA, A> append<EqA, A>(Patch<EqA, A> px, Patch<EqA, A> py) \n        where EqA : Eq<A> =>\n        px.Combine(py);\n\n    /// <summary>\n    /// Compute the inverse of a patch\n    /// </summary>\n    public static Patch<EqA, A> inverse<EqA, A>(Patch<EqA, A> patch) where EqA : Eq<A>\n    {\n        return new Patch<EqA, A>(PatchInternal.mapAccumL(go, 0, patch.Edits).Item2);\n            \n        (int, Edit<EqA, A>) go(int off, Edit<EqA, A> edit) =>\n            edit switch\n            {\n                Edit<EqA, A>.Insert ins  => (off + 1, Edit<EqA, A>.Delete.New(off + ins.Position, ins.Element)),\n                Edit<EqA, A>.Delete del  => (off - 1, Edit<EqA, A>.Insert.New(off + del.Position, del.Element)),\n                Edit<EqA, A>.Replace rpl => (off, Edit<EqA, A>.Replace.New(off + rpl.Position, rpl.ReplaceElement, rpl.Element)),\n                _                        => throw new NotSupportedException()\n            };\n    }\n\n    /// <summary>\n    /// Returns true if a patch can be safely applied to a document, that is,\n    /// `applicable(p, d)` holds when `d` is a valid source document for the patch `p`.\n    /// </summary>\n    public static bool applicable<EqA, A>(Patch<EqA, A> pa, IEnumerable<A> va) where EqA : Eq<A>\n    {\n        var i = SpanArray<A>.New(va);\n\n        return pa.Edits.ForAll(\n            e =>\n                e switch\n                {\n                    Edit<EqA, A>.Insert ins => ins.Position <= i.Count,\n                    Edit<EqA, A>.Delete del => i.Elem(del.Position).Match(\n                        Some: ci => EqA.Equals(del.Element, ci),\n                        None: () => false),\n                    _ => e is Edit<EqA, A>.Replace repl && i.Elem(repl.Position).Match(\n                             Some: ci => EqA.Equals(repl.Element, ci),\n                             None: () => false)\n                });\n    }\n\n    /// <summary>\n    /// Returns true if a patch can be validly composed with another.\n    /// That is, `composable(p, q)` holds if `q` can be validly applied after `p`.\n    /// </summary>\n    public static bool composable<EqA, A>(Patch<EqA, A> pa, Patch<EqA, A> pb) where EqA : Eq<A>\n    {\n        return go(pa.Edits, pb.Edits, 0);\n\n        static bool go(Seq<Edit<EqA, A>> ea, Seq<Edit<EqA, A>> eb, int off)\n        {\n            if (ea.IsEmpty || eb.IsEmpty) return true;\n            var x  = ea.Head.Value!;\n            var xs = ea.Tail;\n            var y  = eb.Head.Value!;\n            var ys = eb.Tail;\n            var yi = y.Index(i => i + off);\n            var xi = x.Position;\n            if (xi < yi.Position)\n            {\n                return go(xs, eb, off + offset(x));\n            }\n            else if (xi > yi.Position)\n            {\n                return go(ea, ys, off);\n            }\n            else\n            {\n                switch (x)\n                {\n                    case Edit<EqA, A>.Delete when yi is Edit<EqA, A>.Insert:\n                        return go(xs, ys, off + offset(x));\n                    case Edit<EqA, A>.Delete:\n                        return go(xs, eb, off + offset(x));\n                    default:\n                    {\n                        return yi is Edit<EqA, A>.Insert\n                                   ? go(ea, ys, off)\n                                   : x switch\n                                     {\n                                         Edit<EqA, A>.Replace replA1 when yi is Edit<EqA, A>.Replace replB1 =>\n                                             EqA.Equals(replA1.ReplaceElement, replB1.Element) && go(xs, ys, off),\n\n                                         Edit<EqA, A>.Replace replA2 when yi is Edit<EqA, A>.Delete del3 =>\n                                             EqA.Equals(replA2.ReplaceElement, del3.Element) && go(xs, ys, off),\n\n                                         Edit<EqA, A>.Insert ins3 when yi is Edit<EqA, A>.Replace replB2 =>\n                                             EqA.Equals(ins3.Element, replB2.Element) && go(xs, ys, off + offset(x)),\n\n                                         Edit<EqA, A>.Insert ins4 when yi is Edit<EqA, A>.Delete del4 =>\n                                             EqA.Equals(ins4.Element, del4.Element) && go(xs, ys, off + offset(x)),\n\n                                         _ => throw new NotSupportedException()\n                                     };\n                    }\n                }\n            }\n        }\n\n        static int offset(Edit<EqA, A> edit) =>\n            edit switch\n            {\n                Edit<EqA, A>.Insert  => -1,\n                Edit<EqA, A>.Delete  => 1,\n                Edit<EqA, A>.Replace => 0,\n                _                    => throw new NotSupportedException()\n            };\n    }\n\n    /// <summary>\n    /// Build the default parameters for building a patch\n    /// </summary>\n    static PatchParams<A, Edit<EqA, A>, MInt32> parms<EqA, A>() where EqA : Eq<A> =>\n        new (EqA.Equals,\n             Edit<EqA, A>.Delete.New,\n             Edit<EqA, A>.Insert.New,\n             Edit<EqA, A>.Replace.New,\n             static _ => MInt32.One,\n             static x => x is Edit<EqA, A>.Delete ? 0 : 1);\n\n    /// <summary>\n    /// Returns the delta of the document's size when a patch is applied.\n    /// Essentially the number of `Insert` minus the number of `Delete`.\n    /// </summary>\n    public static int sizeChange<EqA, A>(Patch<EqA, A> patch) where EqA : Eq<A>\n    {\n        var count = 0;\n        foreach (var item in patch.Edits)\n        {\n            switch (item)\n            {\n                case Edit<EqA, A>.Delete:\n                    count--;\n                    break;\n                case Edit<EqA, A>.Insert:\n                    count++;\n                    break;\n            }\n        }\n        return count;\n    }\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public static Lst<A> apply<EqA, A>(Patch<EqA, A> patch, Lst<A> va) where EqA : Eq<A> =>\n        toList(apply(patch, va.AsIterable()));\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public static Seq<A> apply<EqA, A>(Patch<EqA, A> patch, Seq<A> va) where EqA : Eq<A> =>\n        toSeq(apply(patch, va.AsEnumerable()));\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public static Arr<A> apply<EqA, A>(Patch<EqA, A> patch, Arr<A> va) where EqA : Eq<A> =>\n        apply(patch, va.AsIterable()).ToArr();\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public static A[] apply<EqA, A>(Patch<EqA, A> patch, A[] va) where EqA : Eq<A> =>\n        apply(patch, va.AsEnumerable()).ToArray();\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public static SpanArray<A> apply<EqA, A>(Patch<EqA, A> patch, SpanArray<A> va) where EqA : Eq<A> =>\n        SpanArray<A>.New(apply(patch, va.AsEnumerable()));\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public static List<A> apply<EqA, A>(Patch<EqA, A> patch, List<A> va) where EqA : Eq<A> =>\n        [..apply(patch, va.AsEnumerable())];\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public static Iterable<A> apply<EqA, A>(Patch<EqA, A> patch, IEnumerable<A> va) where EqA : Eq<A>\n    {\n        if (patch.Edits.Count == 0) return va.AsIterable();\n        var i = SpanArray<A>.New(va);\n\n        var dlength = i.Count + sizeChange(patch);\n        var d       = SpanArray<A>.New(dlength);\n\n        go(patch.Edits, i, d, 0);\n        return d.AsIterable();\n \n        static Unit go(Seq<Edit<EqA, A>> edits, SpanArray<A> src, SpanArray<A> dest, int si)\n        {\n            while (true)\n            {\n                if (edits.IsEmpty)\n                {\n                    return dest.Count > 0\n                               ? src.UnsafeCopy(dest)\n                               : unit;\n                }\n                else\n                {\n                    var x = edits.Head.Value!.Position - si;\n                    if (x > 0)\n                    {\n                        src.Take(x).UnsafeCopy(dest.Take(x));\n                        src  = src.Skip(x);\n                        dest = dest.Skip(x);\n                        si   = si + x;\n                    }\n                    else\n                    {\n                        switch (edits.Head.Value!)\n                        {\n                            case Edit<EqA, A>.Insert insert:\n                                dest[0] = insert.Element;\n                                edits   = edits.Tail;\n                                dest    = dest.Tail;\n                                continue;\n\n                            case Edit<EqA, A>.Delete:\n                                edits = edits.Tail;\n                                src   = src.Tail;\n                                si    = si + 1;\n                                continue;\n\n                            case Edit<EqA, A>.Replace replace:\n                                dest[0] = replace.ReplaceElement;\n                                edits   = edits.Tail;\n                                src     = src.Tail;\n                                dest    = dest.Tail;\n                                si      = si + 1;\n                                continue;\n\n                            default:\n                                throw new NotSupportedException();\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Empty patch\n    /// </summary>\n    public static Patch<EqA, A> empty<EqA, A>() where EqA : Eq<A> =>\n        Patch<EqA, A>.Empty;\n\n    /// <summary>\n    /// Resolve a conflict by always using the left-hand side\n    /// </summary>\n    public static A ours<A>(A x, A y) =>\n        x;\n\n    /// <summary>\n    /// Resolve a conflict by always using the right-hand side\n    /// </summary>\n    public static A theirs<A>(A x, A y) =>\n        y;\n\n    /// <summary>\n    /// A convenience version of `transformWith` which resolves conflicts using `append`.\n    /// </summary>\n    public static (Patch<EqA, A> a, Patch<EqA, A> b) transform<EqA, A>(Patch<EqA, A> p, Patch<EqA, A> q)\n        where EqA : Eq<A>\n        where A : Monoid<A> =>\n        transformWith((x, y) => x.Combine(y), p, q);\n\n    /// <summary>\n    /// Given two diverging patches `p` and `q`, `transform(m, p, q)` returns\n    /// a pair of updated patches `(np, nq)` such that `append(q, np)` and\n    /// `append(p, nq)` are equivalent patches that incorporate the changes\n    /// of _both_ `p` and `q`, up to merge conflicts, which are handled by\n    /// the provided function `m`.\n    /// \n    /// This is the standard `transform` function of Operational Transformation\n    /// patch resolution techniques, and can be thought of as the pushout\n    /// of two diverging patches within the patch groupoid.\n    /// </summary>\n    public static (Patch<EqA, A> a, Patch<EqA, A> b) transformWith<EqA, A>(Func<A, A, A> conflict, Patch<EqA, A> p, Patch<EqA, A> q) where EqA : Eq<A>\n    {\n        var (pi, qi) = go(p.Edits, 0, q.Edits, 0, conflict);\n        return (new Patch<EqA, A>(pi), new Patch<EqA, A>(qi));\n \n        static (Seq<Edit<EqA, A>> a, Seq<Edit<EqA, A>> b) go(Seq<Edit<EqA, A>> xs, int a, Seq<Edit<EqA, A>> ys, int b, Func<A, A, A> conflict)\n        {\n            if (xs.IsEmpty && ys.IsEmpty) return (xs, ys);\n            if (ys.IsEmpty) return (xs.Map(e => e.Index(i => i     + a)), ys);\n            if (xs.IsEmpty) return (xs, ys.Map(e => e.Index(i => i + b)));\n            var x   = xs.Head.Value!;\n            var y   = ys.Head.Value!;\n            var ord = x.Position.CompareTo(y.Position);\n            switch (ord)\n            {\n                case < 0:\n                {\n                    var (_1, _2) = go(xs.Tail, a, ys, b + offset(x), conflict);\n                    return (x.Index(i => i + a).Cons(_1), _2);\n                }\n                case > 0:\n                {\n                    var (_1, _2) = go(xs, a + offset(y), ys.Tail, b, conflict);\n                    return (_1, y.Index(i => i + b).Cons(_2));\n                }\n                default:\n                {\n                    if (x == y)\n                    {\n                        return go(xs.Tail, a + offset(y), ys.Tail, b + offset(x), conflict);\n                    }\n                    else switch (x)\n                    {\n                        case Edit<EqA, A>.Insert ins1 when y is Edit<EqA, A>.Insert ins2:\n                        {\n                            var n = conflict(ins1.Element, ins2.Element);\n                            return cons2(\n                                (Edit<EqA, A>.Replace.New(ins1.Position + a, ins2.Element, n),\n                                 Edit<EqA, A>.Replace.New(ins1.Position + b, ins1.Element, n)),\n                                go(xs.Tail, a + offset(y), ys.Tail, b + offset(x), conflict));\n                        }\n                        case Edit<EqA, A>.Replace repl1 when y is Edit<EqA, A>.Replace repl2:\n                        {\n                            var n = conflict(repl1.ReplaceElement, repl2.ReplaceElement);\n                            return cons2(\n                                (Edit<EqA, A>.Replace.New(repl1.Position + a, repl2.ReplaceElement, n),\n                                 Edit<EqA, A>.Replace.New(repl1.Position + b, repl1.ReplaceElement, n)),\n                                go(xs.Tail, a, ys.Tail, b, conflict));\n                        }\n                        case Edit<EqA, A>.Insert:\n                        {\n                            var (_1, _2) = go(xs.Tail, a, ys, b + offset(x), conflict);\n                            return (x.Index(i => i + a).Cons(_1), _2);\n                        }\n                        default:\n                        {\n                            if (y is Edit<EqA, A>.Insert)\n                            {\n                                var (_1, _2) = go(xs, a + offset(y), ys.Tail, b, conflict);\n                                return (_1, y.Index(i => i + b).Cons(_2));\n                            }\n                            else switch (x)\n                            {\n                                case Edit<EqA, A>.Replace repl3 when y is Edit<EqA, A>.Delete:\n                                {\n                                    var (_1, _2) = go(xs.Tail, a + offset(y), ys.Tail, b, conflict);\n                                    return (_1, (Edit<EqA, A>.Delete.New(repl3.Position, repl3.ReplaceElement)).Index(i => i + b).Cons(_2));\n                                }\n                                case Edit<EqA, A>.Delete when y is Edit<EqA, A>.Replace repl4:\n                                {\n                                    var (_1, _2) = go(xs.Tail, a, ys.Tail, b + offset(x), conflict);\n                                    return ((Edit<EqA, A>.Delete.New(repl4.Position, repl4.ReplaceElement)).Index(i => i + a).Cons(_1), _2);\n                                }\n                                case Edit<EqA, A>.Delete when y is Edit<EqA, A>.Delete:\n                                    return go(xs.Tail, a + offset(y), ys.Tail, b + offset(x), conflict);\n                                default:\n                                    throw new NotSupportedException();\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        static int offset(Edit<EqA, A> edit) =>\n            edit switch\n            {\n                Edit<EqA, A>.Insert  => 1,\n                Edit<EqA, A>.Delete  => -1,\n                Edit<EqA, A>.Replace => 0,\n                _                    => throw new NotSupportedException()\n            };\n\n        static (Seq<Edit<EqA, A>>, Seq<Edit<EqA, A>>) cons2((Edit<EqA, A> cx, Edit<EqA, A> cy) head, (Seq<Edit<EqA, A>> cxs, Seq<Edit<EqA, A>> cys) tail) =>\n            (head.cx.Cons(tail.cxs), head.cy.Cons(tail.cys));\n    }\n\n    /// <summary>\n    /// Compute the difference between two documents, using the Wagner-Fischer algorithm. \n    /// O(mn) time and space.\n    /// \n    ///     apply(diff(d,e), d) == e\n    ///     \n    ///     diff(d, d) == Patch.empty\n    ///     \n    ///     apply(diff(d, e), d) == apply(inverse(diff(e, d)), d)\n    ///     \n    ///     apply(append(diff(a, b), diff(b, c), a) == apply(diff(a, c), a)\n    ///     \n    ///     applicable(diff(a, b) a)\n    /// \n    /// </summary>\n    public static Patch<EqA, A> diff<EqA, A>(IEnumerable<A> va, IEnumerable<A> vb) where EqA : Eq<A>\n    {\n        var (_, s) = PatchInternal.leastChanges<MInt32, A, Edit<EqA, A>, MInt32>(\n            parms<EqA, A>(), \n            SpanArray<A>.New(va), \n            SpanArray<A>.New(vb));\n        \n        return new Patch<EqA, A>(adjust(0, s));\n\n        static Seq<Edit<EqA, A>> adjust(int o, Seq<Edit<EqA, A>> list) =>\n            list.IsEmpty\n                ? Seq<Edit<EqA, A>>()\n                : list.Head.Value! is Edit<EqA, A>.Insert ia ? Edit<EqA, A>.Insert.New(ia.Position + o, ia.Element).Cons(adjust(o - 1, list.Tail))\n                    : list.Head.Value! is Edit<EqA, A>.Delete da ? Edit<EqA, A>.Delete.New(da.Position + o, da.Element).Cons(adjust(o + 1, list.Tail))\n                        : list.Head.Value! is Edit<EqA, A>.Replace ra ? Edit<EqA, A>.Replace.New(ra.Position + o, ra.Element, ra.ReplaceElement).Cons(adjust(o, list.Tail))\n                            : throw new NotSupportedException();\n    }\n\n    // TODO: Consider building a monoid wrappers for all numeric values (and strings)\n    internal readonly record struct MInt32(int Value) : Monoid<MInt32>, Ord<MInt32>\n    {\n        public MInt32 Combine(MInt32 y) => \n            new (Value + y.Value);\n\n        public static MInt32 Empty { get; } = \n            new (0);\n\n        public static readonly MInt32 Zero = \n            new(0);\n\n        public static readonly MInt32 One = \n            new(1);\n\n        public static int GetHashCode(MInt32 x) => \n            x.Value.GetHashCode();\n\n        public static bool Equals(MInt32 x, MInt32 y) =>\n            x.Value == y.Value;\n\n        public static int Compare(MInt32 x, MInt32 y) =>\n            x.Value.CompareTo(y.Value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Patch/Patch.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing System;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A `Patch` is a collection of edits performed to a _document_, in this case an 'IEnumerable〈A〉'. \n/// They are implemented as a list of 'Edit', and can be converted to and from raw lists of edits using \n/// `toList` and `fromList` respectively.\n/// \n/// Patches form a groupoid (a 'Monoid' with inverses, and a partial composition relation), where the \n/// inverse element can be computed with 'inverse' and the groupoid operation is a _composition_ of \n/// patches.  Applying `append(p1, p2)` is the same as applying `p1` _then_\n/// `p2` (see `Patch.apply`). This composition operator may produce structurally different patches depending \n/// on associativity, however the patches are guaranteed to be _equivalent_ in the sense that the resultant \n/// document will be the same when they are applied.\n/// \n/// For convenience, we make our composition operator here total, to fit the `Monoid` typeclass, but provide \n/// some predicates (`Patch.composable` and `Patch.applicable`) to determine if the operation can be validly \n/// used.\n/// </summary>\npublic readonly struct Patch<EqA, A> :\n    Monoid<Patch<EqA, A>>,\n    IEquatable<Patch<EqA, A>> \n    where EqA : Eq<A>\n{\n    /// <summary>\n    /// Empty patch\n    /// </summary>\n    public static Patch<EqA, A> Empty { get; } = new(Seq<Edit<EqA, A>>());\n\n    /// <summary>\n    /// Edits that represent the operations to perform on a document \n    /// to transform it.\n    /// </summary>\n    public readonly Seq<Edit<EqA, A>> Edits;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    internal Patch(Seq<Edit<EqA, A>> edits) =>\n        Edits = edits;\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public bool Equals(Patch<EqA, A> mb) =>\n        EqSeq<EqEdit<EqA, A>, Edit<EqA, A>>.Equals(Edits, mb.Edits);\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public override bool Equals(object? obj) =>\n        obj is Patch<EqA, A> p && Equals(p);\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    public static bool operator ==(Patch<EqA, A> pa, Patch<EqA, A> pb) =>\n        pa.Equals(pb);\n\n    /// <summary>\n    /// Non-equality operator\n    /// </summary>\n    public static bool operator !=(Patch<EqA, A> pa, Patch<EqA, A> pb) =>\n        !(pa == pb);\n\n    /// <summary>\n    /// Patch summing operator: monoid append\n    /// </summary>\n    public static Patch<EqA, A> operator +(Patch<EqA, A> pa, Patch<EqA, A> pb) => pa.Combine(pb);\n\n    /// <summary>\n    /// Patch inverse operator\n    /// </summary>\n    public static Patch<EqA, A> operator -(Patch<EqA, A> pa) =>\n        Patch.inverse(pa);\n\n    /// <summary>\n    /// Hash code provider\n    /// </summary>\n    public override int GetHashCode() =>\n        Edits.GetHashCode();\n\n    /// <summary>\n    /// Return a string representation of the patch\n    /// </summary>\n    public override string ToString() =>\n        $\"[{String.Join(\"; \", Edits.Map(x => x.ToString()))}]\";\n\n    /// <summary>\n    /// Returns true if a patch can be safely applied to a document, that is,\n    /// `applicable(p, d)` holds when `d` is a valid source document for the patch `p`.\n    /// </summary>\n    public bool Applicable(IEnumerable<A> document) =>\n        Patch.applicable(this, document);\n\n    /// <summary>\n    /// Monoid append: produces a patch is a merged version of this \n    /// and the provided patch.  \n    /// </summary>\n    public Patch<EqA, A> Combine(Patch<EqA, A> mb)\n    {\n        var px = this;\n        var py = mb;\n\n        Seq<Edit<EqA, A>> replace(int i, A o, A n, Seq<Edit<EqA, A>> seq) =>\n            EqA.Equals(o, n)\n                ? seq\n                : Edit<EqA, A>.Replace.New(i, o, n).Cons(seq);\n\n        Seq<Edit<EqA, A>> merge(Seq<Edit<EqA, A>> ex, Seq<Edit<EqA, A>> ey, int off)\n        {\n            if (ex.IsEmpty)\n            {\n                return ey.Map(e => e.Index(i => i + off));\n            }\n            else if (ey.IsEmpty)\n            {\n                return ex;\n            }\n            else\n            {\n                var x  = ex.Head.Value!;\n                var xs = ex.Tail;\n                var y  = ey.Head.Value!;\n                var ys = ey.Tail;\n\n                var yi  = y.Index(i => i + off);\n                var ord = x.Position.CompareTo(yi.Position);\n                if (ord < 0)\n                {\n                    return x.Cons(merge(xs, ey, off + offset(x)));\n                }\n                else if (ord > 0)\n                {\n                    return yi.Cons(merge(ex, ys, off));\n                }\n                else\n                {\n                    if (x is Edit<EqA, A>.Delete del1 && yi is Edit<EqA, A>.Insert ins1)\n                    {\n                        return replace(del1.Position, del1.Element, ins1.Element, merge(xs, ys, off + offset(x)));\n                    }\n                    else if (x is Edit<EqA, A>.Delete)\n                    {\n                        return x.Cons(merge(xs, ey, off + offset(x)));\n                    }\n                    else if (yi is Edit<EqA, A>.Insert)\n                    {\n                        return yi.Cons(merge(ex, ys, off));\n                    }\n                    else if (x is Edit<EqA, A>.Replace replA1 && yi is Edit<EqA, A>.Replace replB1)\n                    {\n                        return replace(replA1.Position, replA1.Element, replB1.ReplaceElement, merge(xs, ys, off));\n                    }\n                    else if (x is Edit<EqA, A>.Replace replA2 && yi is Edit<EqA, A>.Delete)\n                    {\n                        return Edit<EqA, A>.Delete.New(replA2.Position, replA2.Element).Cons(merge(xs, ys, off));\n                    }\n                    else if (x is Edit<EqA, A>.Insert ins3 && yi is Edit<EqA, A>.Replace replB2)\n                    {\n                        return Edit<EqA, A>.Insert.New(ins3.Position, replB2.ReplaceElement)\n                                           .Cons(merge(xs, ys, off + offset(x)));\n                    }\n                    else if (x is Edit<EqA, A>.Insert && yi is Edit<EqA, A>.Delete)\n                    {\n                        return merge(xs, ys, off + offset(x));\n                    }\n                    else\n                    {\n                        throw new NotSupportedException();\n                    }\n                }\n            }\n        }\n\n        int offset(Edit<EqA, A> edit) =>\n            edit is Edit<EqA, A>.Insert    ? -1\n            : edit is Edit<EqA, A>.Delete  ? 1\n            : edit is Edit<EqA, A>.Replace ? 0\n                                             : throw new NotSupportedException();\n\n        return new Patch<EqA, A>(merge(px.Edits, py.Edits, 0));\n    }\n\n    /// <summary>\n    /// Compute the inverse of a patch\n    /// </summary>\n    public Patch<EqA, A> Inverse() =>\n        Patch.inverse(this);\n\n    /// <summary>\n    /// Returns the delta of the document's size when a patch is applied.\n    /// Essentially the number of `Insert` minus the number of `Delete`\n    /// </summary>\n    public int SizeChange() =>\n        Patch.sizeChange(this);\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public Iterable<A> Apply(IEnumerable<A> va) =>\n        Patch.apply(this, va);\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public Seq<A> Apply(Seq<A> va) =>\n        Patch.apply(this, va);\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public Lst<A> Apply(Lst<A> va) =>\n        Patch.apply(this, va);\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public SpanArray<A> Apply(SpanArray<A> va) =>\n        Patch.apply(this, va);\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public Arr<A> Apply(Arr<A> va) =>\n        Patch.apply(this, va);\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public A[] Apply(A[] va) =>\n        Patch.apply(this, va);\n\n    /// <summary>\n    /// Apply a patch to a document, returning the transformed document.\n    /// </summary>\n    public List<A> Apply(List<A> va) =>\n        Patch.apply(this, va);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Patch/PatchParams.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Parameters for injecting the default behaviour for\n    /// building patches \n    /// </summary>\n    internal class PatchParams<V, O, C>\n    {\n        public readonly Func<V, V, bool> equivalent;\n        public readonly Func<int, V, O> delete;\n        public readonly Func<int, V, O> insert;\n        public readonly Func<int, V, V, O> substitute;\n        public readonly Func<O, C> cost;\n        public readonly Func<O, int> positionOffset;\n\n        public PatchParams(\n            Func<V, V, bool> equivalent,\n            Func<int, V, O> delete,\n            Func<int, V, O> insert,\n            Func<int, V, V, O> substitute,\n            Func<O, C> cost,\n            Func<O, int> positionOffset\n            )\n        {\n            this.equivalent = equivalent;\n            this.delete = delete;\n            this.insert = insert;\n            this.substitute = substitute;\n            this.cost = cost;\n            this.positionOffset = positionOffset;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Pure/Pure.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class PureExtensions\n{\n    extension<A>(Pure<A> lhs)\n    {\n        /// <summary>\n        /// Value extraction\n        /// </summary>\n        public static A operator >>(Pure<A> px, Lower _) =>\n            px.Value;\n    }\n\n    extension<A, B>(Pure<A> lhs)\n    {\n        /// <summary>\n        /// Function composition\n        /// </summary>\n        /// <param name=\"x\">Input</param>\n        /// <param name=\"f\">Function</param>\n        /// <returns>Result of invoking the function</returns>\n        public static Pure<B> operator >>(Pure<A> x, Func<A, B> f) =>\n            new (f(x.Value));\n    }   \n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    /// <param name=\"mma\">Nested `Pure` monad</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Flattened monad</returns>\n    public static Pure<A> Flatten<A>(this Pure<Pure<A>> mma) =>\n        mma.Value;\n\n    public static Validation<F, B> Bind<F, A, B>(this Pure<A> ma, Func<A, Validation<F, B>> bind)\n        where F : Monoid<F> =>\n        bind(ma.Value);\n\n    public static Validation<F, A> ToValidation<F, A>(this Pure<A> ma)\n        where F : Monoid<F> =>\n        Validation.Success<F, A>(ma.Value);\n\n    public static Validation<F, C> SelectMany<F, A, B, C>(\n        this Pure<A> ma,\n        Func<A, Validation<F, B>> bind,\n        Func<A, B, C> project)\n        where F : Monoid<F> =>\n        bind(ma.Value).Map(y => project(ma.Value, y));\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Pure/Pure.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents a pure value.  Usually understood to be the 'success' value.\n/// </summary>\n/// <remarks>\n/// On its own this doesn't do much, but  allows other monads to convert\n/// from it and provide binding extensions that mean it can be lifted into\n/// other monads without specifying lots of extra generic arguments.\n/// </remarks>\n/// <param name=\"Value\">Bound value</param>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic readonly record struct Pure<A>(A Value)\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Standard operators\n    //\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Result bound value type</typeparam>\n    /// <returns>Result of the applying the mapping function to the `Pure` value</returns>\n    public Pure<B> Map<B>(Func<A, B> f) =>\n        new (f(Value));\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    /// <typeparam name=\"B\">Result bound value type</typeparam>\n    /// <returns>Result of the applying the bind function to the `Pure` value</returns>\n    public Pure<B> Bind<B>(Func<A, Pure<B>> f) =>\n        f(Value);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    /// <typeparam name=\"L\">Result bound value type</typeparam>\n    /// <returns>Result of the applying the bind function to the `Pure` value</returns>\n    public Either<L, A> Bind<L>(Func<A, Fail<L>> f) =>\n        f(Value);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    /// <typeparam name=\"B\">Result bound value type</typeparam>\n    /// <returns>Result of the applying the bind function to the `Pure` value</returns>\n    public IO<B> Bind<B>(Func<A, IO<B>> f) =>\n        ToIO().Bind(f); \n\n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    /// <typeparam name=\"B\">Result of the bind operation bound value type</typeparam>\n    /// <typeparam name=\"C\">Result of the mapping operation bound value type</typeparam>\n    /// <returns>Result of the applying the bind and mapping function to the `Pure` value</returns>\n    public Pure<C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        new(project(Value, bind(Value).Value));\n\n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    /// <typeparam name=\"L\">Result of the bind operation bound value type</typeparam>\n    /// <typeparam name=\"C\">Result of the mapping operation bound value type</typeparam>\n    /// <returns>Result of the applying the bind and mapping function to the `Pure` value</returns>\n    public Either<L, C> SelectMany<L, C>(Func<A, Fail<L>> bind, Func<A, Unit, C> project) =>\n        bind(Value).Value;\n\n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    /// <typeparam name=\"B\">Result of the bind operation bound value type</typeparam>\n    /// <typeparam name=\"C\">Result of the mapping operation bound value type</typeparam>\n    /// <returns>Result of the applying the bind and mapping function to the `Pure` value</returns>\n    public IO<C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        ToIO().SelectMany(bind, project);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Conversion\n    //\n    \n    public Option<A> ToOption() =>\n        Value is null \n            ? Option<A>.None \n            : Option.Some(Value);\n    \n    public These<X, A> ToThese<X>() =>\n        These.That<X, A>(Value);\n    \n    public Either<L, A> ToEither<L>() =>\n        Either.Right<L, A>(Value);\n    \n    public Fin<A> ToFin() =>\n        Fin.Succ(Value);\n    \n    public Try<A> ToTry() =>\n        Try.Succ(Value);\n    \n    public IO<A> ToIO() =>\n        IO.pure(Value);\n    \n    public Eff<RT, A> ToEff<RT>() =>\n        Eff<RT, A>.Pure(Value);\n    \n    public Eff<A> ToEff() =>\n        Eff<A>.Pure(Value);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic binding\n    //\n\n    public Either<L, B> Bind<L, B>(Func<A, Either<L, B>> bind) =>\n        bind(Value);\n\n    public Fin<B> Bind<B>(Func<A, Fin<B>> bind) =>\n        bind(Value);\n\n    public Eff<RT, B> Bind<RT, B>(Func<A, Eff<RT, B>> bind) =>\n        bind(Value);\n\n    public Eff<B> Bind<B>(Func<A, Eff<B>> bind) =>\n        bind(Value);\n    \n    public K<M, B> Bind<M, B>(Func<A, K<M, B>> bind)\n        where M : Monad<M> =>\n        bind(Value);\n    \n    public Reader<Env, B> Bind<Env, B>(Func<A, Reader<Env, B>> bind) =>\n        bind(Value);\n    \n    public ReaderT<Env, M, B> Bind<Env, M, B>(Func<A, ReaderT<Env, M, B>> bind)\n        where M : Monad<M>, Alternative<M> =>\n        bind(Value);\n    \n    public State<S, B> Bind<S, B>(Func<A, State<S, B>> bind) =>\n        bind(Value);\n    \n    public StateT<S, M, B> Bind<S, M, B>(Func<A, StateT<S, M, B>> bind)\n        where M : Monad<M>, Alternative<M> =>\n        bind(Value);\n    \n    public OptionT<M, B> Bind<M, B>(Func<A, OptionT<M, B>> bind)\n        where M : Monad<M> =>\n        bind(Value);\n    \n    public Option<B> Bind<B>(Func<A, Option<B>> bind) =>\n        bind(Value);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic binding and projection\n    //\n\n    public Either<L, C> SelectMany<L, B, C>(Func<A, Either<L, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    public Fin<C> SelectMany<B, C>(Func<A, Fin<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    public Eff<RT, C> SelectMany<RT, B, C>(Func<A, Eff<RT, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    public Eff<C> SelectMany<B, C>(Func<A, Eff<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    public K<M, C> SelectMany<M, B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project)\n         where M : Monad<M> =>\n         Bind(x => M.Map(y => project(x, y), bind(x)));\n    \n    public Reader<Env, C> SelectMany<Env, B, C>(Func<A, Reader<Env, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    public Reader<Env, C> SelectMany<Env, B, C>(Func<A, K<Reader<Env>, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n    \n    public ReaderT<Env, M, C> SelectMany<Env, M, B, C>(Func<A, ReaderT<Env, M, B>> bind, Func<A, B, C> project)\n        where M : Monad<M>, Alternative<M> =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    public ReaderT<Env, M, C> SelectMany<Env, M, B, C>(Func<A, K<ReaderT<Env, M>, B>> bind, Func<A, B, C> project)\n        where M : Monad<M>, Alternative<M> =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n    \n    public State<S, C> SelectMany<S, B, C>(Func<A, State<S, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    public State<S, C> SelectMany<S, B, C>(Func<A, K<State<S>, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n    \n    public StateT<S, M, C> SelectMany<S, M, B, C>(Func<A, StateT<S, M, B>> bind, Func<A, B, C> project)\n        where M : Monad<M>, Alternative<M> =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    public StateT<S, M, C> SelectMany<S, M, B, C>(Func<A, K<StateT<S, M>, B>> bind, Func<A, B, C> project)\n        where M : Monad<M>, Alternative<M> =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n    \n    public OptionT<M, C> SelectMany<M, B, C>(Func<A, OptionT<M, B>> bind, Func<A, B, C> project)\n        where M : Monad<M> =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    public OptionT<M, C> SelectMany<M, B, C>(Func<A, K<OptionT<M>, B>> bind, Func<A, B, C> project)\n        where M : Monad<M> =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n\n    public Option<C> SelectMany<B, C>(Func<A, Option<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/README.md",
    "content": "These are all pure, immutable, data-types apart from `SpanArray`.  `SpanArray` does almost exactly what the .NET `Span<T>` does,\nhowever this came first, and so will remain supported.  It's not advised to use it.\n\n\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Range/Range.Extensions.cs",
    "content": "using System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class RangeExtensions\n{\n    /// <summary>\n    /// Convert kind to concrete type\n    /// </summary>\n    public static Range<A> As<A>(this K<Range, A> ma) =>  \n        (Range<A>)ma;\n    \n    /// <summary>\n    /// Returns true if the value provided is in range\n    /// </summary>\n    /// <param name=\"value\">Value to test</param>\n    /// <returns>True if the value provided is in range</returns>\n    [Pure]\n    public static bool InRange<A>(this K<Range, A> ma, A value)\n        where A : IComparisonOperators<A, A, bool>\n    {\n        var range = ma.As();\n        var from  = range.From > range.To ? range.To : range.From;\n        var to    = range.From > range.To ? range.From : range.To;\n        return value >= from && value <= to;\n    }\n\n    /// <summary>\n    /// Returns true if the range provided overlaps this range\n    /// </summary>\n    /// <param name=\"other\">The range to test</param>\n    /// <returns>True if the range provided overlaps this range</returns>\n    [Pure]\n    public static bool Overlaps<A>(this K<Range, A> ma, Range<A> other)\n        where A : IComparisonOperators<A, A, bool>\n    {\n        var range = ma.As();\n        var xfrom = range.From > range.To ? range.To : range.From;\n        var xto   = range.From > range.To ? range.From : range.To;\n        var yfrom = other.From > other.To ? other.To : other.From;\n        var yto   = other.From > other.To ? other.From : other.To;\n        return xfrom < yto && yfrom < xto;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Range/Range.Module.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\n\nnamespace LanguageExt;\n\npublic partial class Range\n{\n    /// <summary>\n    /// Zero range  \n    /// </summary>\n    public static Range<A> zero<A>() \n        where A : IAdditiveIdentity<A, A> =>\n        new(A.AdditiveIdentity, A.AdditiveIdentity, A.AdditiveIdentity, Iterable<A>.Empty);\n\n    /// <summary>\n    /// Construct a new range\n    /// </summary>\n    /// <param name=\"from\">The minimum value in the range</param>\n    /// <param name=\"to\">The maximum value in the range</param>\n    [Pure]\n    public static Range<A> fromMinMax<A>(A min, A max)\n        where A : \n            INumberBase<A>,\n            ISubtractionOperators<A, A, A>,\n            IComparisonOperators<A, A, bool>,     \n            IAdditionOperators<A, A, A>, \n            IEqualityOperators<A, A, bool> =>\n        fromMinMax(min, max, max >= min ? A.One : A.Zero - A.One);\n\n    /// <summary>\n    /// Construct a new range\n    /// </summary>\n    /// <param name=\"from\">The minimum value in the range</param>\n    /// <param name=\"to\">The maximum value in the range</param>\n    /// <param name=\"step\">The size of each step in the range</param>\n    [Pure]\n    public static Range<A> fromMinMax<A>(A min, A max, A step)\n        where A : \n        IAdditionOperators<A, A, A>, \n        IComparisonOperators<A, A, bool>\n    {\n        return min > max\n                   ? new(min, max, step, Backward())\n                   : new(min, max, step, Forward());\n\n        IEnumerable<A> Forward()\n        {\n            for (var x = min; x <= max; x += step)\n            {\n                yield return x;\n            }\n        }\n\n        IEnumerable<A> Backward()\n        {\n            for (var x = min; x >= max; x += step)\n            {\n                yield return x;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Construct a new range\n    /// </summary>\n    /// <param name=\"from\">The minimum value in the range</param>\n    /// <param name=\"count\">The number of items in the range</param>\n    [Pure]\n    public static Range<A> fromCount<A>(A min, A count)\n        where A : \n        IComparisonOperators<A, A, bool>,\n        INumberBase<A> =>\n        fromCount(min, count, A.One);\n\n    /// <summary>\n    /// Construct a new range\n    /// </summary>\n    /// <param name=\"from\">The minimum value in the range</param>\n    /// <param name=\"count\">The number of items in the range</param>\n    /// <param name=\"step\">The size of each step in the range</param>\n    [Pure]\n    public static Range<A> fromCount<A>(A min, A count, A step)\n        where A : INumberBase<A>,\n                  IComparisonOperators<A, A, bool>\n    {\n        var max = min + (count * step - step);\n        return new(min, max, step, Go());\n\n        IEnumerable<A> Go()\n        {\n            var c = count;\n            for (var x = min; c != A.Zero; x += step, c -= A.One)\n            {\n                yield return x;\n                if (x == max) yield break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Range/Range.Monad.cs",
    "content": "using System;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Range : Foldable<Range>\n{\n    static S Foldable<Range>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Range, A> ta)\n    {\n        foreach (var x in ta.As().runRange)\n        {\n            if (!predicate((state, x))) return state;\n            state = f(x)(state);\n        }\n        return state;\n    }\n    \n    static S Foldable<Range>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S state, \n        K<Range, A> ta)\n    {\n        foreach (var x in ta.As().runRange.Reverse())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(state)(x);\n        }\n        return state;\n    }\n\n    static Fold<A, S> Foldable<Range>.FoldStep<A, S>(K<Range, A> ta, S initialState) \n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n\n    static Fold<A, S> Foldable<Range>.FoldStepBack<A, S>(K<Range, A> ta, S initialState) \n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Range/Range.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System;\nusing System.Collections.Generic;\nusing System.Collections;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents a range of values\n/// </summary>\n/// <typeparam name=\"A\">Bound values type</typeparam>\n[Serializable]\npublic record Range<A>(A From, A To, A Step, IEnumerable<A> runRange) : \n    IEnumerable<A>, \n    K<Range, A>\n{\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    [Pure]\n    public object? Case =>\n        Prelude.Seq(this).Case;\n\n    [Pure]\n    public Seq<A> ToSeq() =>\n        Prelude.toSeq(AsIterable());\n\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        runRange.AsIterable();\n\n    /*\n    [Pure]\n    public StreamT<M, A> AsStream<M>() \n        where M : Monad<M> =>\n        StreamT<M>.lift(runRange);\n        */\n\n    [Pure]\n    public IEnumerator<A> GetEnumerator() => \n        // ReSharper disable once NotDisposedResourceIsReturned\n        runRange.GetEnumerator();\n\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        runRange.GetEnumerator();\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Ratio/Ratio.cs",
    "content": "﻿\nnamespace LanguageExt;\n\n/// <summary>\n/// A ratio between two values.\n/// </summary>\n/// <remarks>\n/// This is used in the definition of Fractional.\n/// </remarks>\npublic readonly struct Ratio<A> \n{\n    /// <summary>\n    /// The numerator of the ratio, in non-reduced form.\n    /// </summary>\n    public readonly A Numerator;\n\n    /// <summary>\n    /// The denominator of the ratio, in non-reduced form.\n    /// </summary>\n    public readonly A Denominator;\n\n    public Ratio(A num, A den)\n    {\n        Numerator = num;\n        Denominator = den;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Record/Attributes.cs",
    "content": "﻿using System;\nusing System.Reflection;\n\nnamespace LanguageExt;\n\npublic class NonRecordAttribute : Attribute;\n\npublic class NonStructuralAttribute : Attribute;\n\npublic class NonHashAttribute : Attribute;\n\npublic class NonEqAttribute : Attribute;\n\npublic class NonOrdAttribute : Attribute;\n\npublic class NonShowAttribute : Attribute;\n\npublic class EqAttribute : Attribute\n{\n    public EqAttribute(Type type)\n    {\n        if (!type.GetTypeInfo()\n                 .ImplementedInterfaces\n                 .AsIterable()     \n                 .Exists(i => i.ToString().StartsWith(\"LanguageExt.Traits.Eq`1\")))\n        {\n            throw new Exception(\"Eq attribute should have a struct type that derives from LanguageExt.Traits.Eq<> passed as its argument\");\n        }\n    }\n}\n\npublic class OrdAttribute : Attribute\n{\n    public OrdAttribute(Type type)\n    {\n        if (!type.GetTypeInfo()\n                 .ImplementedInterfaces\n                 .AsIterable()\n                 .Exists(i => i.ToString().StartsWith(\"LanguageExt.Traits.Ord`1\")))\n        {\n            throw new Exception(\"Ord attribute should have a struct type that derives from LanguageExt.Traits.Ord<> passed as its argument\");\n        }\n    }\n}\n\npublic class HashableAttribute : Attribute\n{\n    public HashableAttribute(Type type)\n    {\n        if (!type.GetTypeInfo()\n                 .ImplementedInterfaces\n                 .AsIterable()\n                 .Exists(i => i.ToString().StartsWith(\"LanguageExt.Traits.Hashable`1\")))\n        {\n            throw new Exception(\"Hashable attribute should have a struct type that derives from LanguageExt.Traits.Hashable<> passed as its argument\");\n        }\n    }\n}\n\n/// <summary>\n/// Stops the base type fields being used for any Record operations\n/// </summary>\n/// <remarks>This is *not* used for the [Record] code-gen</remarks>\npublic class IgnoreBaseAttribute : Attribute;\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Record/Record.cs",
    "content": "﻿using System;\nusing System.Runtime.Serialization;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Base class for types that are 'records'.  A record has a set of readonly *fields(\n/// that make up its data structure.  By deriving from this you get structural equality,\n/// structural ordering (`IComparable`), structural hashing (`GetHashCode`) as well as the\n/// operators `==`, `!=`, `〈`, `〈=`, `〉`, `〉=`, \n/// </summary>\n/// <typeparam name=\"RECORDTYPE\"></typeparam>\n[Serializable]\npublic abstract class Record<RECORDTYPE> : \n    IEquatable<RECORDTYPE>, IComparable<RECORDTYPE>, IComparable\n    where RECORDTYPE : Record<RECORDTYPE>\n{\n    protected Record() { }\n\n    protected Record(SerializationInfo info, StreamingContext context) =>\n        RecordType<RECORDTYPE>.SetObjectData((RECORDTYPE)this, info);\n\n    public static bool operator==(Record<RECORDTYPE> x, Record<RECORDTYPE> y) =>\n        RecordType<RECORDTYPE>.EqualityTyped((RECORDTYPE)x, (RECORDTYPE)y);\n\n    public static bool operator !=(Record<RECORDTYPE> x, Record<RECORDTYPE> y) =>\n        !(x == y);\n\n    public static bool operator >(Record<RECORDTYPE> x, Record<RECORDTYPE> y) =>\n        RecordType<RECORDTYPE>.Compare((RECORDTYPE)x, (RECORDTYPE)y) > 0;\n\n    public static bool operator >=(Record<RECORDTYPE> x, Record<RECORDTYPE> y) =>\n        RecordType<RECORDTYPE>.Compare((RECORDTYPE)x, (RECORDTYPE)y) >= 0;\n\n    public static bool operator <(Record<RECORDTYPE> x, Record<RECORDTYPE> y) =>\n        RecordType<RECORDTYPE>.Compare((RECORDTYPE)x, (RECORDTYPE)y) < 0;\n\n    public static bool operator <=(Record<RECORDTYPE> x, Record<RECORDTYPE> y) =>\n        RecordType<RECORDTYPE>.Compare((RECORDTYPE)x, (RECORDTYPE)y) <= 0;\n\n    public override int GetHashCode() =>\n        RecordType<RECORDTYPE>.Hash((RECORDTYPE)this);\n\n    public override bool Equals(object? obj) =>\n        obj is not null && \n        RecordType<RECORDTYPE>.Equality((RECORDTYPE)this, obj);\n\n    public virtual int CompareTo(RECORDTYPE? other) =>\n        other is null ? 1 : RecordType<RECORDTYPE>.Compare((RECORDTYPE)this, other);\n\n    public virtual bool Equals(RECORDTYPE? other) =>\n        other is not null && RecordType<RECORDTYPE>.EqualityTyped((RECORDTYPE)this, other);\n\n    public override string ToString() =>\n        RecordType<RECORDTYPE>.ToString((RECORDTYPE)this);\n\n    public virtual void GetObjectData(SerializationInfo info, StreamingContext context) =>\n        RecordType<RECORDTYPE>.GetObjectData((RECORDTYPE)this, info);\n\n    public int CompareTo(object? obj) =>\n        obj is RECORDTYPE rt ? CompareTo(rt) : 1;\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Record/RecordType.cs",
    "content": "﻿using System;\nusing System.Runtime.Serialization;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Supports the building of record types (classes with sets of readonly field values)\n/// Provides structural equality testing, ordering, and hashing\n/// </summary>\n/// <typeparam name=\"A\">Type to provide methods for</typeparam>\npublic static class RecordType<A>\n{\n    /// <summary>\n    /// General hash code function for record types\n    /// </summary>\n    public static Func<A, int> Hash => RecordTypeHash<A>.Hash;\n\n    /// <summary>\n    /// General equality function for record types\n    /// </summary>\n    public static Func<A, object, bool> Equality => RecordTypeEquality<A>.Equality;\n\n    /// <summary>\n    /// General typed equality function for record types\n    /// </summary>\n    public static Func<A, A, bool> EqualityTyped => RecordTypeEqualityTyped<A>.EqualityTyped;\n\n    /// <summary>\n    /// General typed comparison function for record types\n    /// </summary>\n    public static Func<A, A, int> Compare => RecordTypeCompare<A>.Compare;\n\n    /// <summary>\n    /// General ToString function\n    /// </summary>\n    public new static Func<A, string> ToString => RecordTypeToString<A>.ToString;\n\n    /// <summary>\n    /// De-serialise an A\n    /// </summary>\n    public static Action<A, SerializationInfo> SetObjectData => RecordTypeSetObjectData<A>.SetObjectData;\n\n    /// <summary>\n    /// Serialise an A\n    /// </summary>\n    public static Action<A, SerializationInfo> GetObjectData => RecordTypeGetObjectData<A>.GetObjectData;\n\n    [Obsolete(\"Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped\")]\n    public new static bool Equals(object objA, object objB) => \n        throw new InvalidOperationException(\"Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped\");\n}\n\ninternal static class RecordTypeIncludeBase<A>\n{\n    internal static readonly bool IncludeBase;\n    \n    static RecordTypeIncludeBase() =>\n        IncludeBase = !typeof(A).CustomAttributes\n                                .AsIterable() \n                                .Exists(a => a.AttributeType.Name == nameof(IgnoreBaseAttribute));\n}\n\ninternal static class RecordTypeHash<A>\n{\n    internal static readonly Func<A, int> Hash;\n    \n    static RecordTypeHash() => \n        Hash = IL.GetHashCode<A>(RecordTypeIncludeBase<A>.IncludeBase);\n}\n\ninternal static class RecordTypeEquality<A>\n{\n    internal static readonly Func<A, object, bool> Equality;\n    \n    static RecordTypeEquality() => \n        Equality = IL.Equals<A>(RecordTypeIncludeBase<A>.IncludeBase);\n}\n\ninternal static class RecordTypeEqualityTyped<A>\n{\n    internal static readonly Func<A, A, bool> EqualityTyped;\n    \n    static RecordTypeEqualityTyped() => \n        EqualityTyped = IL.EqualsTyped<A>(RecordTypeIncludeBase<A>.IncludeBase);\n}\n\ninternal static class RecordTypeCompare<A>\n{\n    internal static readonly Func<A, A, int> Compare;\n    \n    static RecordTypeCompare() => \n        Compare = IL.Compare<A>(RecordTypeIncludeBase<A>.IncludeBase);\n}\n\ninternal static class RecordTypeToString<A>\n{\n    internal new static readonly Func<A, string> ToString;\n    \n    static RecordTypeToString() => \n        ToString = IL.ToString<A>(RecordTypeIncludeBase<A>.IncludeBase);\n}\n\ninternal static class RecordTypeSetObjectData<A>\n{\n    internal static readonly Action<A, SerializationInfo> SetObjectData;\n    \n    static RecordTypeSetObjectData() => \n        SetObjectData = IL.SetObjectData<A>(RecordTypeIncludeBase<A>.IncludeBase);\n}\n\ninternal static class RecordTypeGetObjectData<A>\n{\n    internal static readonly Action<A, SerializationInfo> GetObjectData;\n    \n    static RecordTypeGetObjectData() => \n        GetObjectData = IL.GetObjectData<A>(RecordTypeIncludeBase<A>.IncludeBase);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Record/RecordTypeIgnoreBase.cs",
    "content": "﻿using System;\nusing System.Runtime.Serialization;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Supports the building of record types (classes with sets of readonly field values)\n/// Provides structural equality testing, ordering, and hashing\n/// </summary>\n/// <typeparam name=\"A\">Type to provide methods for</typeparam>\npublic static class RecordTypeIgnoreBase<A>\n{\n    static RecordTypeIgnoreBase()\n    {\n        Hash = IL.GetHashCode<A>(false);\n        Equality = IL.Equals<A>(false);\n        EqualityTyped = IL.EqualsTyped<A>(false);\n        Compare = IL.Compare<A>(false);\n        ToString = IL.ToString<A>(false);\n        SetObjectData = IL.SetObjectData<A>(false);\n        GetObjectData = IL.GetObjectData<A>(false);\n    }\n\n    /// <summary>\n    /// General hash code function for record types\n    /// </summary>\n    public static readonly Func<A, int> Hash;\n\n    /// <summary>\n    /// General equality function for record types\n    /// </summary>\n    public static readonly Func<A, object, bool> Equality;\n\n    /// <summary>\n    /// General typed equality function for record types\n    /// </summary>\n    public static readonly Func<A, A, bool> EqualityTyped;\n\n    /// <summary>\n    /// General typed comparison function for record types\n    /// </summary>\n    public static readonly Func<A, A, int> Compare;\n\n    /// <summary>\n    /// General ToString function\n    /// </summary>\n    public new static readonly Func<A, string> ToString;\n\n    /// <summary>\n    /// De-serialise an A\n    /// </summary>\n    public static readonly Action<A, SerializationInfo> SetObjectData;\n\n    /// <summary>\n    /// Serialise an A\n    /// </summary>\n    public static readonly Action<A, SerializationInfo> GetObjectData;\n\n    [Obsolete(\"Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped\")]\n    public new static bool Equals(object objA, object objB) => \n        throw new InvalidOperationException(\"Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped\");\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Record/TypeInfoExt.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Reflection;\n\nnamespace LanguageExt;\n\npublic static class TypeInfoAllMemberExtensions\n{\n    public static IEnumerable<ConstructorInfo> GetAllConstructors(this TypeInfo typeInfo, bool includeBase) => \n        GetAll(typeInfo, ti => ti.DeclaredConstructors, includeBase);\n\n    public static IEnumerable<EventInfo> GetAllEvents(this TypeInfo typeInfo, bool includeBase) => \n        GetAll(typeInfo, ti => ti.DeclaredEvents, includeBase);\n\n    public static IEnumerable<FieldInfo> GetAllFields(this TypeInfo typeInfo, bool includeBase) => \n        GetAll(typeInfo, ti => ti.DeclaredFields, includeBase);\n\n    public static IEnumerable<MemberInfo> GetAllMembers(this TypeInfo typeInfo, bool includeBase) => \n        GetAll(typeInfo, ti => ti.DeclaredMembers, includeBase);\n\n    public static IEnumerable<MethodInfo> GetAllMethods(this TypeInfo typeInfo, bool includeBase) => \n        GetAll(typeInfo, ti => ti.DeclaredMethods, includeBase);\n\n    public static IEnumerable<TypeInfo> GetAllNestedTypes(this TypeInfo typeInfo, bool includeBase) => \n        GetAll(typeInfo, ti => ti.DeclaredNestedTypes, includeBase);\n\n    public static IEnumerable<PropertyInfo> GetAllProperties(this TypeInfo typeInfo, bool includeBase) => \n        GetAll(typeInfo, ti => ti.DeclaredProperties, includeBase);\n\n    private static IEnumerable<T> GetAll<T>(TypeInfo typeInfo, Func<TypeInfo, IEnumerable<T>> accessor, bool includeBase)\n    {\n        if (includeBase)\n        {\n            var ti = typeInfo; \n            while (ti != null)\n            {\n                foreach (var t in accessor(ti))\n                {\n                    yield return t;\n                }\n                ti = ti.BaseType?.GetTypeInfo();\n            }\n        }\n        else\n        {\n            foreach (var t in accessor(typeInfo))\n            {\n                yield return t;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/SpanArray/SpanArray.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Collections;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents a *mutable* array type that can be sliced to return\n/// new versions of the array which represent subsections of the \n/// original but without copying to a new buffer.  This means the\n/// underlying array is shared and vulnerable to data race issues \n/// and the commonly known issues of mutable structures.  \n/// \n/// It is primarily to facilitate super-fast algorithms that work \n/// on collections.  The idea being that the algorithm knows about\n/// the issues of mutation and can avoid the problems whilst doing\n/// its thing, but also benefit from a more declarative style by\n/// using `Take`, `Skip`, `Slice`, `Head`, `Tail`, `Elem` etc.\n/// </summary>\npublic readonly struct SpanArray<A> : IEnumerable<A>\n{\n    public readonly A[] Data;\n    public readonly int Count;\n    readonly int Index;\n    readonly int EndIndex;\n\n    SpanArray(A[] data, int index, int count)\n    {\n        Data = data;\n        Index = index;\n        EndIndex = index + count;\n        Count = count;\n    }\n\n    public Option<A> Elem(int index) =>\n        index < 0 || index + Index >= EndIndex\n            ? None\n            : Some(Data[index + Index]);\n\n    public IEnumerator<A> GetEnumerator()\n    {\n        for (int i = Index; i < EndIndex; i++)\n        {\n            yield return Data[i];\n        }\n    }\n\n    public A this[int index]\n    {\n        get => index < 0 || index + Index >= EndIndex\n                   ? throw new IndexOutOfRangeException()\n                   : Data[index + Index];\n\n        set => Data[index + Index] =\n                   index < 0 || index + Index >= EndIndex\n                       ? throw new IndexOutOfRangeException()\n                       : value;\n    }\n\n    public static SpanArray<A> New(IEnumerable<A> sequence)\n    {\n        var data = sequence.ToArray();\n        return new SpanArray<A>(data, 0, data.Length);\n    }\n\n    public static SpanArray<A> New(A[] data) =>\n        new (data, 0, data.Length);\n\n    public static SpanArray<A> New(int n) =>\n        new (new A[n], 0, n);\n\n    public SpanArray<A> Slice(int index, int count)\n    {\n        if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));\n        var newIndex = Index + index;\n        if (newIndex > Index + Count) throw new ArgumentOutOfRangeException(nameof(index));\n        if (newIndex         + count > Index + Count) throw new ArgumentOutOfRangeException(nameof(count));\n        return new SpanArray<A>(Data, newIndex, count);\n    }\n\n    public SpanArray<A> Take(int n) =>\n        Slice(0, n);\n\n    public SpanArray<A> Skip(int n) =>\n        Slice(n, Count - n);\n\n    public SpanArray<A> Tail =>\n        Slice(1, Count - 1);\n\n    public A Head =>\n        this[0];\n\n    public A Last =>\n        this[Count - 1];\n\n    IEnumerator IEnumerable.GetEnumerator() =>\n        GetEnumerator();\n\n    public Unit UnsafeCopy(SpanArray<A> dest)\n    {\n        System.Array.Copy(Data, Index, dest.Data, dest.Index, Count);\n        return unit;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/StringM/OrdString.cs",
    "content": "// TODO: Work out where these types should live\n\nusing System;\nusing LanguageExt.Traits;\nusing LanguageExt.Traits.Domain;\n\nnamespace LanguageExt;\n\npublic interface HashableString<STRING> : Hashable<STRING>\n    where STRING : \n        HashableString<STRING>, \n        DomainType<STRING, string>\n{\n    public static abstract StringComparison Comparison { get; }\n    \n    static int Hashable<STRING>.GetHashCode(STRING x) =>\n        x.To().GetHashCode(STRING.Comparison);\n}\n\npublic interface EqString<STRING> : HashableString<STRING>, Eq<STRING>\n    where STRING : EqString<STRING>, \n    DomainType<STRING, string>\n{\n    static bool Eq<STRING>.Equals(STRING lhs, STRING rhs) =>\n        string.Equals(lhs.To(), rhs.To(), STRING.Comparison);\n}\n\npublic interface OrdString<STRING> : EqString<STRING>, Ord<STRING>\n    where STRING : \n        OrdString<STRING>,\n        DomainType<STRING, string>\n{\n    static int Ord<STRING>.Compare(STRING lhs, STRING rhs) =>\n        string.Compare(lhs.To(), rhs.To(), STRING.Comparison);\n}\n\npublic interface OrdinalIgnoreCase<STRING> : OrdString<STRING>\n    where STRING : \n        OrdinalIgnoreCase<STRING>,\n        DomainType<STRING, string>\n{\n    static StringComparison HashableString<STRING>.Comparison => \n        StringComparison.OrdinalIgnoreCase;\n}\n\npublic interface Ordinal<STRING> : OrdString<STRING>\n    where STRING : \n        Ordinal<STRING>,\n        DomainType<STRING, string>\n{\n    static StringComparison HashableString<STRING>.Comparison => \n        StringComparison.Ordinal;\n}\n\npublic interface CultureIgnoreCase<STRING> : OrdString<STRING>\n    where STRING : \n        CultureIgnoreCase<STRING>,\n        DomainType<STRING, string>\n{\n    static StringComparison HashableString<STRING>.Comparison => \n        StringComparison.CurrentCultureIgnoreCase;\n}\n\npublic interface Culture<STRING> : OrdString<STRING>\n    where STRING : \n        Culture<STRING>,\n        DomainType<STRING, string>\n{\n    static StringComparison HashableString<STRING>.Comparison => \n        StringComparison.CurrentCulture;\n}\n\npublic interface InvariantIgnoreCase<STRING> : OrdString<STRING>\n    where STRING : \n        InvariantIgnoreCase<STRING>,\n        DomainType<STRING, string>\n{\n    static StringComparison HashableString<STRING>.Comparison => \n        StringComparison.InvariantCultureIgnoreCase;\n}\n\npublic interface InvariantCulture<STRING> : OrdString<STRING>\n    where STRING : \n        InvariantCulture<STRING>,\n        DomainType<STRING, string>\n{\n    static StringComparison HashableString<STRING>.Comparison => \n        StringComparison.InvariantCulture;\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/StringM/StringM.Ord.cs",
    "content": "using System;\nusing LanguageExt.Traits.Domain;\n\nnamespace LanguageExt;\n\npublic readonly record struct StringOrdinalM(string Value) : StringM<StringOrdinalM>\n{\n    static Fin<StringOrdinalM> DomainType<StringOrdinalM, string>.From(string repr) =>\n        new StringOrdinalM(repr);\n\n    public static StringOrdinalM From(string repr) => \n        new (repr);\n\n    public string To() =>\n        Value;\n\n    public static StringComparison Comparison =>\n        StringComparison.Ordinal;\n    \n    public static implicit operator string(StringOrdinalM value) =>\n        value.Value;\n\n    public static implicit operator StringOrdinalM(string value) =>\n        new(value);\n\n}\n\npublic readonly record struct StringOrdinalIgnoreCaseM(string Value) : StringM<StringOrdinalIgnoreCaseM>\n{\n    static Fin<StringOrdinalIgnoreCaseM> DomainType<StringOrdinalIgnoreCaseM, string>.From(string repr) =>\n        new StringOrdinalIgnoreCaseM(repr);\n\n    public static StringInvariantM From(string repr) => \n        new (repr);\n\n    public string To() =>\n        Value;\n\n    public static StringComparison Comparison =>\n        StringComparison.OrdinalIgnoreCase;\n    \n    public static implicit operator string(StringOrdinalIgnoreCaseM value) =>\n        value.Value;\n\n    public static implicit operator StringOrdinalIgnoreCaseM(string value) =>\n        new(value);\n\n}\n\npublic readonly record struct StringCultureM(string Value) : StringM<StringCultureM>\n{\n    static Fin<StringCultureM> DomainType<StringCultureM, string>.From(string repr) =>\n        new StringCultureM(repr);\n\n    public static StringCultureM From(string repr) => \n        new (repr);\n\n    public string To() =>\n        Value;\n\n    public static StringComparison Comparison =>\n        StringComparison.CurrentCulture;\n    \n    public static implicit operator string(StringCultureM value) =>\n        value.Value;\n\n    public static implicit operator StringCultureM(string value) =>\n        new(value);\n\n}\n\npublic readonly record struct StringCultureIgnoreCaseM(string Value) : StringM<StringCultureIgnoreCaseM>\n{\n    static Fin<StringCultureIgnoreCaseM> DomainType<StringCultureIgnoreCaseM, string>.From(string repr) =>\n        new StringCultureIgnoreCaseM(repr);\n\n    public static StringCultureIgnoreCaseM From(string repr) => \n        new (repr);\n\n    public string To() =>\n        Value;\n\n    public static StringComparison Comparison =>\n        StringComparison.CurrentCultureIgnoreCase;\n    \n    public static implicit operator string(StringCultureIgnoreCaseM value) =>\n        value.Value;\n\n    public static implicit operator StringCultureIgnoreCaseM(string value) =>\n        new(value);\n}\n\npublic readonly record struct StringInvariantM(string Value) : StringM<StringInvariantM>\n{\n    public static Fin<StringInvariantM> From(string repr) =>\n        new StringInvariantM(repr);\n\n    public static StringInvariantM FromUnsafe(string repr) => \n        new (repr);\n\n    public string To() =>\n        Value;\n\n    public static StringComparison Comparison =>\n        StringComparison.InvariantCulture;\n\n    public static implicit operator string(StringInvariantM value) =>\n        value.Value;\n\n    public static implicit operator StringInvariantM(string value) =>\n        new(value);\n}\n\npublic readonly record struct StringInvariantIgnoreCaseM(string Value) : StringM<StringInvariantIgnoreCaseM>\n{\n    static Fin<StringInvariantIgnoreCaseM> DomainType<StringInvariantIgnoreCaseM, string>.From(string repr) =>\n        new StringInvariantIgnoreCaseM(repr);\n\n    public static StringInvariantIgnoreCaseM From(string repr) => \n        new (repr);\n\n    public string To() =>\n        Value;\n\n    public static StringComparison Comparison =>\n        StringComparison.InvariantCultureIgnoreCase;\n\n    public static implicit operator string(StringInvariantIgnoreCaseM value) =>\n        value.Value;\n\n    public static implicit operator StringInvariantIgnoreCaseM(string value) =>\n        new(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/StringM/StringM.Trait.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing LanguageExt.Traits.Domain;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Simple wrapper around String\n/// </summary>\n/// <param name=\"Value\">Contained value</param>\npublic interface StringM<SELF> :\n    DomainType<SELF, string>,\n    Identifier<SELF>,\n    IComparable<SELF>,\n    ISpanParsable<SELF>,\n    OrdString<SELF>,\n    Monoid<SELF>\n    where SELF : \n        StringM<SELF>,\n        Identifier<SELF>,\n        IComparable<SELF>,\n        ISpanParsable<SELF>,\n        OrdString<SELF>,\n        Monoid<SELF>\n{\n    /// <summary>\n    /// Monoid append\n    /// </summary>\n    SELF Semigroup<SELF>.Combine(SELF rhs) =>\n        SELF.FromUnsafe(To() + rhs.To()); \n\n    /// <summary>\n    /// Monoid empty\n    /// </summary>\n    static SELF Monoid<SELF>.Empty => SELF.FromUnsafe(string.Empty);\n\n    /// <summary>\n    /// Length of the string\n    /// </summary>\n    public int Length =>\n        To().Length;\n\n    /// <summary>\n    /// ToString override\n    /// </summary>\n    public string ToString() =>\n        To();\n\n    public int GetHashCode() =>\n        Hashable.code((SELF)this);\n    \n    bool IEquatable<SELF>.Equals(SELF? rhs) =>\n        rhs is not null && SELF.Equals((SELF)this, rhs);\n    \n    int IComparable<SELF>.CompareTo(SELF? rhs) =>\n        rhs is null \n            ? 1 \n            : SELF.Compare((SELF)this, rhs);\n\n    static SELF IParsable<SELF>.Parse(string s, IFormatProvider? provider) => \n        SELF.FromUnsafe(s);\n\n    static bool IParsable<SELF>.TryParse(string? s, IFormatProvider? provider, out SELF result)\n    {\n        result = SELF.FromUnsafe(s ?? \"\");\n        return s != null;\n    }\n\n    static SELF ISpanParsable<SELF>.Parse(ReadOnlySpan<char> s, IFormatProvider? provider)\n    {\n        // magic number from System.String\n        if (s.Length > 1073741791) throw new ArgumentException(nameof(s));\n        return SELF.FromUnsafe(s.ToString());\n    }\n\n    static bool ISpanParsable<SELF>.TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out SELF result)\n    {\n        if (s.Length <= 1073741791) // magic number from System.String\n        {\n            result = SELF.FromUnsafe(s.ToString());\n            return true;\n        }\n        result = default!;\n        return false;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/StringM/StringM.cs",
    "content": "using System;\nusing LanguageExt.Traits.Domain;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Simple wrapper around String\n/// </summary>\n/// <param name=\"Value\">Contained value</param>\npublic readonly record struct StringM(string Value) : StringM<StringM> \n{\n    static Fin<StringM> DomainType<StringM, string>.From(string repr) =>\n        new StringM(repr);\n\n    public static StringM From(string repr) => \n        new (repr);\n\n    public static StringM FromUnsafe(string repr) => \n        new (repr);\n\n    public string To() =>\n        Value;\n\n    public static StringComparison Comparison =>\n        StringComparison.Ordinal;\n\n    public static implicit operator string(StringM value) =>\n        value.Value;\n\n    public static implicit operator StringM(string value) =>\n        new(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Unit/Unit.Prelude.cs",
    "content": "﻿using System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Unit constructor\n    /// </summary>\n    public static Unit unit =>\n        Unit.Default;\n\n    /// <summary>\n    /// Takes any value, ignores it, returns a unit\n    /// </summary>\n    /// <param name=\"anything\">Value to ignore</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit ignore<A>(A anything) =>\n        default;\n\n    /// <summary>\n    /// Takes any value, ignores it, returns a unit\n    /// </summary>\n    /// <param name=\"anything\">Value to ignore</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit Ignore<A>(this A anything) =>\n        default;\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/Unit/Unit.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A unit type is a type that allows only one value (and thus can hold no information)\n/// </summary>\n[Serializable]\npublic readonly struct Unit : IEquatable<Unit>, IComparable<Unit>, Monoid<Unit>\n{\n    public static readonly Unit Default = default;\n\n    [Pure]\n    public override int GetHashCode() => \n        0;\n\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is Unit;\n\n    [Pure]\n    public override string ToString() => \n        \"()\";\n\n    [Pure]\n    public bool Equals(Unit other) =>\n        true;\n\n    [Pure]\n    public static bool operator ==(Unit lhs, Unit rhs) =>\n        true;\n\n    [Pure]\n    public static bool operator !=(Unit lhs, Unit rhs) =>\n        false;\n\n    [Pure]\n    public static bool operator >(Unit lhs, Unit rhs) =>\n        false;\n\n    [Pure]\n    public static bool operator >=(Unit lhs, Unit rhs) =>\n        true;\n\n    [Pure]\n    public static bool operator <(Unit lhs, Unit rhs) =>\n        false;\n\n    [Pure]\n    public static bool operator <=(Unit lhs, Unit rhs) =>\n        true;\n\n    /// <summary>\n    /// Provide an alternative value to unit\n    /// </summary>\n    /// <typeparam name=\"T\">Alternative value type</typeparam>\n    /// <param name=\"anything\">Alternative value</param>\n    /// <returns>Alternative value</returns>\n    [Pure]\n    public T Return<T>(T anything) => anything;\n\n    /// <summary>\n    /// Provide an alternative value to unit\n    /// </summary>\n    /// <typeparam name=\"T\">Alternative value type</typeparam>\n    /// <param name=\"anything\">Alternative value</param>\n    /// <returns>Alternative value</returns>\n    [Pure]\n    public T Return<T>(Func<T> anything) => anything();\n\n    /// <summary>\n    /// Always equal\n    /// </summary>\n    [Pure]\n    public int CompareTo(Unit other) =>\n        0;\n\n    [Pure]\n    public Unit Combine(Unit rhs) => \n        default;\n\n    [Pure]\n    public static Unit operator +(Unit a, Unit b) =>\n        Default;\n\n    [Pure]\n    public static implicit operator ValueTuple(Unit _) => \n        default;\n        \n    [Pure]\n    public static implicit operator Unit(ValueTuple _) => \n        default;\n        \n    [Pure]\n    public static implicit operator Unit(Seq<Unit> _) => \n        default;\n        \n    [Pure]\n    public static implicit operator Unit(Lst<Unit> _) => \n        default;\n        \n    [Pure]\n    public static implicit operator Unit(Iterable<Unit> _) => \n        default;\n\n    [Pure]\n    public static Unit Empty =>\n        default;\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple1/ValueTuple1.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\npublic static class ValueTuple1Extensions\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B) Add<A, B>(this ValueTuple<A> self, B second) =>\n        (self.Item1, second);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool Contains<EQ, A>(this ValueTuple<A> self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value);\n\n    /// <summary>\n    /// Map to R\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R> Map<A, R>(this ValueTuple<A> self, Func<A, R> map) =>\n        new(map(self.Item1));\n\n    /// <summary>\n    /// Map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R> Select<A, R>(this ValueTuple<A> self, Func<A, R> map) =>\n        new(map(self.Item1));\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A>(this ValueTuple<A> self, Action<A> func)\n    {\n        func(self.Item1);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S Fold<A, S>(this ValueTuple<A> self, S state, Func<S, A, S> fold) =>\n        fold(state, self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple1/ValueTuple1.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B) add<A, B>(ValueTuple<A> self, B second) =>\n        (self.Item1, second);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool contains<EQ, A>(ValueTuple<A> self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value);\n\n    /// <summary>\n    /// Map to R\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R> map<A, R>(ValueTuple<A> self, Func<A, R> map) =>\n        new(map(self.Item1));\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A>(ValueTuple<A> self, Action<A> func)\n    {\n        func(self.Item1);\n        return Unit.Default;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple2/ValueTuple2.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\n\npublic static class ValueTuple2Extensions\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C) Add<A, B, C>(this (A, B) self, C third) =>\n        (self.Item1, self.Item2, third);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static T1 Head<T1, T2>(this ValueTuple<T1, T2> self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static T2 Last<T1, T2>(this ValueTuple<T1, T2> self) =>\n        self.Item2;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T2> Tail<T1, T2>(this ValueTuple<T1, T2> self) =>\n        new (self.Item2);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, R>(this ValueTuple<A, B> self, Func<ValueTuple<A, B>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, R>(this ValueTuple<A, B> self, Func<A, B, R> map) =>\n        map(self.Item1, self.Item2);\n\n    /// <summary>\n    /// Bi-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, R2> BiMap<T1, T2, R1, R2>(this ValueTuple<T1, T2> self, Func<T1, R1> firstMap, Func<T2, R2> secondMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, T2> MapFirst<T1, T2, R1>(this ValueTuple<T1, T2> self, Func<T1, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T1, R2> MapSecond<T1, T2, R2>(this ValueTuple<T1, T2> self, Func<T2, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2));\n\n    /// <summary>\n    /// Map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, R2> Select<T1, T2, R1, R2>(this ValueTuple<T1, T2> self, Func<ValueTuple<T1, T2>, ValueTuple<R1, R2>> map) =>\n        map(self);\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<T1, T2>(this ValueTuple<T1, T2> self, Action<T1, T2> func)\n    {\n        func(self.Item1, self.Item2);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<T1, T2>(this ValueTuple<T1, T2> self, Action<T1> first, Action<T2> second)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S Fold<T1, T2, S>(this ValueTuple<T1, T2> self, S state, Func<S, T1, T2, S> fold) =>\n        fold(state, self.Item1, self.Item2);\n\n    /// <summary>\n    /// Bi-fold\n    /// </summary>\n    [Pure]\n    public static S BiFold<T1, T2, S>(this ValueTuple<T1, T2> self, S state, Func<S, T1, S> firstFold, Func<S, T2, S> secondFold) =>\n        secondFold(firstFold(state, self.Item1), self.Item2);\n\n    /// <summary>\n    /// Bi-fold\n    /// </summary>\n    [Pure]\n    public static S BiFoldBack<T1, T2, S>(this ValueTuple<T1, T2> self, S state, Func<S, T2, S> firstFold, Func<S, T1, S> secondFold) =>\n        secondFold(firstFold(state, self.Item2), self.Item1);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Arr<(C, D)> Traverse<A, B, C, D>(this (Arr<A> ma, Arr<B> mb) tuple, Func<(A a, B b), (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f((a, b))\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Arr<(C, D)> Traverse<A, B, C, D>(this (Arr<A> ma, Arr<B> mb) tuple, Func<A, B, (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f(a, b)\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Arr<(A, B)> Sequence<A, B>(this (Arr<A> ma, Arr<B> mb) tuple) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        select (a, b);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Either<L, (C, D)> Traverse<L, A, B, C, D>(this (Either<L, A> ma, Either<L, B> mb) tuple, Func<(A a, B b), (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f((a, b))\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Either<L, (C, D)> Traverse<L, A, B, C, D>(this (Either<L, A> ma, Either<L, B> mb) tuple, Func<A, B, (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f(a, b)\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Either<L, (A, B)> Sequence<L, A, B>(this (Either<L, A> ma, Either<L, B> mb) tuple) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        select (a, b);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static HashSet<(C, D)> Traverse<A, B, C, D>(this (HashSet<A> ma, HashSet<B> mb) tuple, Func<(A a, B b), (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f((a, b))\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static HashSet<(C, D)> Traverse<A, B, C, D>(this (HashSet<A> ma, HashSet<B> mb) tuple, Func<A, B, (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f(a, b)\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static HashSet<(A, B)> Sequence<A, B>(this (HashSet<A> ma, HashSet<B> mb) tuple) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        select (a, b);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Lst<(C, D)> Traverse<A, B, C, D>(this (Lst<A> ma, Lst<B> mb) tuple, Func<(A a, B b), (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f((a, b))\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Lst<(C, D)> Traverse<A, B, C, D>(this (Lst<A> ma, Lst<B> mb) tuple, Func<A, B, (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f(a, b)\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Lst<(A, B)> Sequence<A, B>(this (Lst<A> ma, Lst<B> mb) tuple) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        select (a, b);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Option<(C, D)> Traverse<A, B, C, D>(this (Option<A> ma, Option<B> mb) tuple, Func<(A a, B b), (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f((a, b))\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Option<(C, D)> Traverse<A, B, C, D>(this (Option<A> ma, Option<B> mb) tuple, Func<A, B, (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f(a, b)\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Option<(A, B)> Sequence<A, B>(this (Option<A> ma, Option<B> mb) tuple) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        select (a, b);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Set<(C, D)> Traverse<A, B, C, D>(this (Set<A> ma, Set<B> mb) tuple, Func<(A a, B b), (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f((a, b))\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Set<(C, D)> Traverse<A, B, C, D>(this (Set<A> ma, Set<B> mb) tuple, Func<A, B, (C c, D d)> f) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        let r = f(a, b)\n        select (r.Item1, r.Item2);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Set<(A, B)> Sequence<A, B>(this (Set<A> ma, Set<B> mb) tuple) =>\n        from a in tuple.ma\n        from b in tuple.mb\n        select (a, b);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Task<(C, D)> Traverse<A, B, C, D>(this (Task<A> ma, Task<B> mb) tuple, Func<(A a, B b), (C c, D d)> f) =>\n        apply((a, b) => f((a, b)), tuple.ma, tuple.mb);\n\n    /// <summary>\n    /// Flip the tuple monads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Task<(C, D)> Traverse<A, B, C, D>(this (Task<A> ma, Task<B> mb) tuple, Func<A, B, (C c, D d)> f) =>\n        apply((a, b) => f(a, b), tuple.ma, tuple.mb);\n\n    /// <summary>\n    /// Flip the tuads from inside the tuple to outside and apply a transformation function\n    /// </summary>\n    [Pure]\n    public static Task<(A, B)> Sequence<A, B>(this (Task<A> ma, Task<B> mb) tuple) =>\n        apply((a, b) => (a, b), tuple.ma, tuple.mb);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple2/ValueTuple2.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T1, T2, T3> ad<T1, T2, T3>(ValueTuple<T1, T2> self, T3 third) =>\n        self.Add(third);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static T1 head<T1, T2>(ValueTuple<T1, T2> self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static T2 last<T1, T2>(ValueTuple<T1, T2> self) =>\n        self.Item2;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T2> tail<T1, T2>(ValueTuple<T1, T2> self) =>\n        new(self.Item2);\n\n    /// <summary>\n    /// Sum of the items\n    /// </summary>\n    [Pure]\n    public static A sum<NUM, A>(this ValueTuple<A, A> self)\n        where NUM : Num<A> =>\n        NUM.Add(self.Item1, self.Item2);\n\n    /// <summary>\n    /// Product of the items\n    /// </summary>\n    [Pure]\n    public static A product<NUM, A>(this ValueTuple<A, A> self)\n        where NUM : Num<A> =>\n        NUM.Multiply(self.Item1, self.Item2);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool contains<EQ, A>(this ValueTuple<A, A> self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, R>(ValueTuple<A, B> self, Func<ValueTuple<A, B>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, R>(ValueTuple<A, B> self, Func<A, B, R> map) =>\n        map(self.Item1, self.Item2);\n\n    /// <summary>\n    /// Bi-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, R2> bimap<T1, T2, R1, R2>(ValueTuple<T1, T2> self, Func<T1, R1> firstMap, Func<T2, R2> secondMap) =>\n        self.BiMap(firstMap, secondMap);\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<T1, T2>(ValueTuple<T1, T2> self, Action<T1> first, Action<T2> second) =>\n        self.Iter(first, second);\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<T1, T2>(ValueTuple<T1, T2> self, Action<T1, T2> func)\n    {\n        func(self.Item1, self.Item2);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S fold<T1, T2, S>(ValueTuple<T1, T2> self, S state, Func<S, T1, T2, S> fold) =>\n        self.Fold(state, fold);\n\n    /// <summary>\n    /// Bi-fold\n    /// </summary>\n    [Pure]\n    public static S bifold<T1, T2, S>(ValueTuple<T1, T2> self, S state, Func<S, T1, S> firstFold, Func<S, T2, S> secondFold) =>\n        self.BiFold(state, firstFold, secondFold);\n\n    /// <summary>\n    /// Bi-fold back\n    /// </summary>\n    [Pure]\n    public static S bifoldBack<T1, T2, S>(ValueTuple<T1, T2> self, S state, Func<S, T2, S> firstFold, Func<S, T1, S> secondFold) =>\n        self.BiFoldBack(state, firstFold, secondFold);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple3/ValueTuple3.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\npublic static class ValueTuple3Extensions\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T1, T2, T3, T4> Add<T1, T2, T3, T4>(this ValueTuple<T1, T2, T3> self, T4 fourth) =>\n        (self.Item1, self.Item2, self.Item3, fourth);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static T1 Head<T1, T2, T3>(this ValueTuple<T1, T2, T3> self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static T3 Last<T1, T2, T3>(this ValueTuple<T1, T2, T3> self) =>\n        self.Item3;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T2, T3> Tail<T1, T2, T3>(this ValueTuple<T1, T2, T3> self) =>\n        (self.Item2, self.Item3);\n\n    /// <summary>\n    /// Sum of the items\n    /// </summary>\n    [Pure]\n    public static A Sum<NUM, A>(this ValueTuple<A, A, A> self)\n        where NUM : Num<A> =>\n        NUM.Add(self.Item1, NUM.Add(self.Item2, self.Item3));\n\n    /// <summary>\n    /// Product of the items\n    /// </summary>\n    [Pure]\n    public static A Product<NUM, A>(this ValueTuple<A, A, A> self)\n        where NUM : Num<A> =>\n        NUM.Multiply(self.Item1, NUM.Multiply(self.Item2, self.Item3));\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool Contains<EQ, A>(this ValueTuple<A, A, A> self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, R>(this ValueTuple<A, B, C> self, Func<ValueTuple<A, B, C>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, R>(this ValueTuple<A, B, C> self, Func<A, B, C, R> map) =>\n        map(self.Item1, self.Item2, self.Item3);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, R2, R3> Map<T1, T2, T3, R1, R2, R3>(this ValueTuple<T1, T2, T3> self, Func<T1, R1> firstMap, Func<T2, R2> secondMap, Func<T3, R3> thirdMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, T2, T3> MapFirst<T1, T2, T3, R1>(this ValueTuple<T1, T2, T3> self, Func<T1, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T1, R2, T3> MapSecond<T1, T2, T3, R2>(this ValueTuple<T1, T2, T3> self, Func<T2, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T1, T2, R3> MapThird<T1, T2, T3, R3>(this ValueTuple<T1, T2, T3> self, Func<T3, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3));\n\n    /// <summary>\n    /// Map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, R2, R3> Select<T1, T2, T3, R1, R2, R3>(this ValueTuple<T1, T2, T3> self, Func<ValueTuple<T1, T2, T3>, ValueTuple<R1, R2, R3>> map) =>\n        map(self);\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<T1, T2, T3>(this ValueTuple<T1, T2, T3> self, Action<T1, T2, T3> func)\n    {\n        func(self.Item1, self.Item2, self.Item3);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<T1, T2, T3>(this ValueTuple<T1, T2, T3> self, Action<T1> first, Action<T2> second, Action<T3> third)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S Fold<T1, T2, T3, S>(this ValueTuple<T1, T2, T3> self, S state, Func<S, T1, T2, T3, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3);\n\n    /// <summary>\n    /// Tri-fold\n    /// </summary>\n    [Pure]\n    public static S TriFold<T1, T2, T3, S>(this ValueTuple<T1, T2, T3> self, S state, Func<S, T1, S> firstFold, Func<S, T2, S> secondFold, Func<S, T3, S> thirdFold) =>\n        thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3);\n\n    /// <summary>\n    /// Tri-fold\n    /// </summary>\n    [Pure]\n    public static S TriFoldBack<T1, T2, T3, S>(this ValueTuple<T1, T2, T3> self, S state, Func<S, T3, S> firstFold, Func<S, T2, S> secondFold, Func<S, T1, S> thirdFold) =>\n        thirdFold(secondFold(firstFold(state, self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple3/ValueTuple3.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T1, T2, T3, T4> add<T1, T2, T3, T4>(ValueTuple<T1, T2, T3> self, T4 fourth) =>\n        (self.Item1, self.Item2, self.Item3, fourth);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static T1 head<T1, T2, T3>(ValueTuple<T1, T2, T3> self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static T3 last<T1, T2, T3>(ValueTuple<T1, T2, T3> self) =>\n        self.Item3;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T2, T3> tail<T1, T2, T3>(ValueTuple<T1, T2, T3> self) =>\n        (self.Item2, self.Item3);\n\n    /// <summary>\n    /// Sum of the items\n    /// </summary>\n    [Pure]\n    public static A sum<NUM, A>(ValueTuple<A, A, A> self)\n        where NUM : Num<A> =>\n        NUM.Add(self.Item1, NUM.Add(self.Item2, self.Item3));\n\n    /// <summary>\n    /// Product of the items\n    /// </summary>\n    [Pure]\n    public static A product<NUM, A>(ValueTuple<A, A, A> self)\n        where NUM : Num<A> =>\n        NUM.Multiply(self.Item1, NUM.Multiply(self.Item2, self.Item3));\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool contains<EQ, A>(ValueTuple<A, A, A> self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, R>(ValueTuple<A, B, C> self, Func<ValueTuple<A, B, C>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, R>(ValueTuple<A, B, C> self, Func<A, B, C, R> map) =>\n        map(self.Item1, self.Item2, self.Item3);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, R2, R3> trimap<T1, T2, T3, R1, R2, R3>(ValueTuple<T1, T2, T3> self, Func<T1, R1> firstMap, Func<T2, R2> secondMap, Func<T3, R3> thirdMap) =>\n        ValueTuple.Create(firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<R1, T2, T3> mapFirst<T1, T2, T3, R1>(ValueTuple<T1, T2, T3> self, Func<T1, R1> firstMap) =>\n        ValueTuple.Create(firstMap(self.Item1), self.Item2, self.Item3);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T1, R2, T3> mapSecond<T1, T2, T3, R2>(ValueTuple<T1, T2, T3> self, Func<T2, R2> secondMap) =>\n        ValueTuple.Create(self.Item1, secondMap(self.Item2), self.Item3);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static ValueTuple<T1, T2, R3> mapThird<T1, T2, T3, R3>(ValueTuple<T1, T2, T3> self, Func<T3, R3> thirdMap) =>\n        ValueTuple.Create(self.Item1, self.Item2, thirdMap(self.Item3));\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<T1, T2, T3>(ValueTuple<T1, T2, T3> self, Action<T1, T2, T3> func)\n    {\n        func(self.Item1, self.Item2, self.Item3);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<T1, T2, T3>(ValueTuple<T1, T2, T3> self, Action<T1> first, Action<T2> second, Action<T3> third)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S fold<T1, T2, T3, S>(ValueTuple<T1, T2, T3> self, S state, Func<S, T1, T2, T3, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3);\n\n    /// <summary>\n    /// Tri-fold\n    /// </summary>\n    [Pure]\n    public static S trifold<T1, T2, T3, S>(ValueTuple<T1, T2, T3> self, S state, Func<S, T1, S> firstFold, Func<S, T2, S> secondFold, Func<S, T3, S> thirdFold) =>\n        thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3);\n\n    /// <summary>\n    /// Tri-fold\n    /// </summary>\n    [Pure]\n    public static S trifoldBack<T1, T2, T3, S>(ValueTuple<T1, T2, T3> self, S state, Func<S, T3, S> firstFold, Func<S, T2, S> secondFold, Func<S, T1, S> thirdFold) =>\n        thirdFold(secondFold(firstFold(state, self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple4/ValueTuple4.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\npublic static class ValueTuple4Extensions\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E) Add<A, B, C, D, E>(this (A, B, C, D) self, E fifth) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, fifth);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static A Head<A, B, C, D>(this (A, B, C, D) self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static D Last<A, B, C, D>(this (A, B, C, D) self) =>\n        self.Item4;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static (B, C, D) Tail<A, B, C, D>(this(A, B, C, D) self) =>\n        (self.Item2, self.Item3, self.Item4);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool Contains<EQ, A>(this (A, A, A, A) self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value) ||\n        EQ.Equals(self.Item4, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, D, R>(this ValueTuple<A, B, C, D> self, Func<ValueTuple<A, B, C, D>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, D, R>(this ValueTuple<A, B, C, D> self, Func<A, B, C, D, R> map) =>\n        map(self.Item1, self.Item2, self.Item3, self.Item4);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static (W, X, Y, Z) Map<A, B, C, D, W, X, Y, Z>(this(A, B, C, D) self, Func<A, W> firstMap, Func<B, X> secondMap, Func<C, Y> thirdMap, Func<D, Z> fourthMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3), fourthMap(self.Item4));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (R1, B, C, D) MapFirst<A, B, C, D, R1>(this (A, B, C, D) self, Func<A, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3, self.Item4);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, R2, C, D) MapSecond<A, B, C, D, R2>(this (A, B, C, D) self, Func<B, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3, self.Item4);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, R3, D) MapThird<A, B, C, D, R3>(this (A, B, C, D) self, Func<C, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3), self.Item4);\n\n    /// <summary>\n    /// Fourth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, R4) MapFourth<A, B, C, D, R4>(this(A, B, C, D) self, Func<D, R4> fourthMap) =>\n        (self.Item1, self.Item2, self.Item3, fourthMap(self.Item4));\n\n    /// <summary>\n    /// Map to tuple\n    /// </summary>\n    [Pure]\n    public static (W, X, Y, Z) Select<A, B, C, D, W, X, Y, Z>(this (A, B, C, D) self, Func<(A, B, C, D), (W, X, Y, Z)> map) =>\n        map(self);\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A, B, C, D>(this (A, B, C, D) self, Action<A, B, C, D> func)\n    {\n        func(self.Item1, self.Item2, self.Item3, self.Item4);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A, B, C, D>(this (A, B, C, D) self, Action<A> first, Action<B> second, Action<C> third, Action<D> fourth)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        fourth(self.Item4);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S Fold<A, B, C, D, S>(this (A, B, C, D) self, S state, Func<S, A, B, C, D, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3, self.Item4);\n\n    /// <summary>\n    /// Quad-fold\n    /// </summary>\n    [Pure]\n    public static S QuadFold<A, B, C, D, S>(this(A, B, C, D) self, S state, Func<S, A, S> firstFold, Func<S, B, S> secondFold, Func<S, C, S> thirdFold, Func<S, D, S> fourthFold) =>\n        fourthFold(thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3), self.Item4);\n\n    /// <summary>\n    /// Quad-fold back\n    /// </summary>\n    [Pure]\n    public static S QuadFoldBack<A, B, C, D, S>(this (A, B, C, D) self, S state, Func<S, D, S> firstFold, Func<S, C, S> secondFold, Func<S, B, S> thirdFold, Func<S, A, S> fourthFold) =>\n        fourthFold(thirdFold(secondFold(firstFold(state, self.Item4), self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple4/ValueTuple4.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E) add<A, B, C, D, E>((A, B, C, D) self, E fifth) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, fifth);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static A head<A, B, C, D>((A, B, C, D) self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static D last<A, B, C, D>((A, B, C, D) self) =>\n        self.Item4;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static (B, C, D) tail<A, B, C, D>((A, B, C, D) self) =>\n        (self.Item2, self.Item3, self.Item4);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool contains<EQ, A>((A, A, A, A) self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value) ||\n        EQ.Equals(self.Item4, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, D, R>(ValueTuple<A, B, C, D> self, Func<ValueTuple<A, B, C, D>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, D, R>(ValueTuple<A, B, C, D> self, Func<A, B, C, D, R> map) =>\n        map(self.Item1, self.Item2, self.Item3, self.Item4);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static (W, X, Y, Z) map<A, B, C, D, W, X, Y, Z>((A, B, C, D) self, Func<A, W> firstMap, Func<B, X> secondMap, Func<C, Y> thirdMap, Func<D, Z> fourthMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3), fourthMap(self.Item4));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (R1, B, C, D) mapFirst<A, B, C, D, R1>((A, B, C, D) self, Func<A, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3, self.Item4);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, R2, C, D) mapSecond<A, B, C, D, R2>((A, B, C, D) self, Func<B, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3, self.Item4);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, R3, D) mapThird<A, B, C, D, R3>((A, B, C, D) self, Func<C, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3), self.Item4);\n\n    /// <summary>\n    /// Fourth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, R4) mapFourth<A, B, C, D, R4>((A, B, C, D) self, Func<D, R4> fourthMap) =>\n        (self.Item1, self.Item2, self.Item3, fourthMap(self.Item4));\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A, B, C, D>((A, B, C, D) self, Action<A, B, C, D> func)\n    {\n        func(self.Item1, self.Item2, self.Item3, self.Item4);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A, B, C, D>((A, B, C, D) self, Action<A> first, Action<B> second, Action<C> third, Action<D> fourth)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        fourth(self.Item4);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S fold<A, B, C, D, S>((A, B, C, D) self, S state, Func<S, A, B, C, D, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3, self.Item4);\n\n    /// <summary>\n    /// Quad-fold\n    /// </summary>\n    [Pure]\n    public static S quadFold<A, B, C, D, S>((A, B, C, D) self, S state, Func<S, A, S> firstFold, Func<S, B, S> secondFold, Func<S, C, S> thirdFold, Func<S, D, S> fourthFold) =>\n        fourthFold(thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3), self.Item4);\n\n    /// <summary>\n    /// Quad-fold back\n    /// </summary>\n    [Pure]\n    public static S quadFoldBack<A, B, C, D, S>((A, B, C, D) self, S state, Func<S, D, S> firstFold, Func<S, C, S> secondFold, Func<S, B, S> thirdFold, Func<S, A, S> fourthFold) =>\n        fourthFold(thirdFold(secondFold(firstFold(state, self.Item4), self.Item3), self.Item2), self.Item1);\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple5/ValueTuple5.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\npublic static class ValueTuple5Extensions\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, F) Add<A, B, C, D, E, F>(this (A, B, C, D, E) self, F sixth) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, sixth);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static A Head<A, B, C, D, E>(this (A, B, C, D, E) self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static E Last<A, B, C, D, E>(this (A, B, C, D, E) self) =>\n        self.Item5;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static (B, C, D, E) Tail<A, B, C, D, E>(this(A, B, C, D, E) self) =>\n        (self.Item2, self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool Contains<EQ, A>(this (A, A, A, A, A) self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value) ||\n        EQ.Equals(self.Item4, value) ||\n        EQ.Equals(self.Item5, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, D, E, R>(this ValueTuple<A, B, C, D, E> self, Func<ValueTuple<A, B, C, D, E>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, D, E, R>(this ValueTuple<A, B, C, D, E> self, Func<A, B, C, D, E, R> map) =>\n        map(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static (V, W, X, Y, Z) Map<A, B, C, D, E, V, W, X, Y, Z>(this(A, B, C, D, E) self, Func<A, V> firstMap, Func<B, W> secondMap, Func<C, X> thirdMap, Func<D, Y> fourthMap, Func<E, Z> fifthMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3), fourthMap(self.Item4), fifthMap(self.Item5));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (R1, B, C, D, E) MapFirst<A, B, C, D, E, R1>(this (A, B, C, D, E) self, Func<A, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, R2, C, D, E) MapSecond<A, B, C, D, E, R2>(this (A, B, C, D, E) self, Func<B, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, R3, D, E) MapThird<A, B, C, D, E, R3>(this (A, B, C, D, E) self, Func<C, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3), self.Item4, self.Item5);\n\n    /// <summary>\n    /// Fourth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, R4, E) MapFourth<A, B, C, D, E, R4>(this(A, B, C, D, E) self, Func<D, R4> fourthMap) =>\n        (self.Item1, self.Item2, self.Item3, fourthMap(self.Item4), self.Item5);\n\n    /// <summary>\n    /// Fifth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, R5) MapFifth<A, B, C, D, E, R5>(this(A, B, C, D, E) self, Func<E, R5> fifthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, fifthMap(self.Item5));\n\n    /// <summary>\n    /// Map to tuple\n    /// </summary>\n    [Pure]\n    public static (V, W, X, Y, Z) Select<A, B, C, D, E, V, W, X, Y, Z>(this (A, B, C, D, E) self, Func<(A, B, C, D, E), (V, W, X, Y, Z)> map) =>\n        map(self);\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A, B, C, D, E>(this (A, B, C, D, E) self, Action<A, B, C, D, E> func)\n    {\n        func(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A, B, C, D, E>(this (A, B, C, D, E) self, Action<A> first, Action<B> second, Action<C> third, Action<D> fourth, Action<E> fifth)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        fourth(self.Item4);\n        fifth(self.Item5);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S Fold<A, B, C, D, E, S>(this (A, B, C, D, E) self, S state, Func<S, A, B, C, D, E, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S QuintFold<A, B, C, D, E, S>(this(A, B, C, D, E) self, S state, Func<S, A, S> firstFold, Func<S, B, S> secondFold, Func<S, C, S> thirdFold, Func<S, D, S> fourthFold, Func<S, E, S> fifthFold) =>\n        fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3), self.Item4), self.Item5);\n\n    /// <summary>\n    /// Fold back\n    /// </summary>\n    [Pure]\n    public static S QuintFoldBack<A, B, C, D, E, S>(this (A, B, C, D, E) self, S state, Func<S, E, S> firstFold, Func<S, D, S> secondFold, Func<S, C, S> thirdFold, Func<S, B, S> fourthFold, Func<S, A, S> fifthFold) =>\n        fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item5), self.Item4), self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple5/ValueTuple5.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, F) add<A, B, C, D, E, F>(this(A, B, C, D, E) self, F sixth) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, sixth);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static A head<A, B, C, D, E>((A, B, C, D, E) self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static E last<A, B, C, D, E>((A, B, C, D, E) self) =>\n        self.Item5;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static (B, C, D, E) tail<A, B, C, D, E>((A, B, C, D, E) self) =>\n        (self.Item2, self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool contains<EQ, A>((A, A, A, A, A) self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value) ||\n        EQ.Equals(self.Item4, value) ||\n        EQ.Equals(self.Item5, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, D, E, R>(ValueTuple<A, B, C, D, E> self, Func<ValueTuple<A, B, C, D, E>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, D, E, R>(ValueTuple<A, B, C, D, E> self, Func<A, B, C, D, E, R> map) =>\n        map(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static (V, W, X, Y, Z) map<A, B, C, D, E, V, W, X, Y, Z>((A, B, C, D, E) self, Func<A, V> firstMap, Func<B, W> secondMap, Func<C, X> thirdMap, Func<D, Y> fourthMap, Func<E, Z> fifthMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3), fourthMap(self.Item4), fifthMap(self.Item5));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (R1, B, C, D, E) mapFirst<A, B, C, D, E, R1>((A, B, C, D, E) self, Func<A, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, R2, C, D, E) mapSecond<A, B, C, D, E, R2>((A, B, C, D, E) self, Func<B, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, R3, D, E) mapThird<A, B, C, D, E, R3>((A, B, C, D, E) self, Func<C, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3), self.Item4, self.Item5);\n\n    /// <summary>\n    /// Fourth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, R4, E) mapFourth<A, B, C, D, E, R4>((A, B, C, D, E) self, Func<D, R4> fourthMap) =>\n        (self.Item1, self.Item2, self.Item3, fourthMap(self.Item4), self.Item5);\n\n    /// <summary>\n    /// Fifth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, R5) mapFifth<A, B, C, D, E, R5>((A, B, C, D, E) self, Func<E, R5> fifthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, fifthMap(self.Item5));\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A, B, C, D, E>((A, B, C, D, E) self, Action<A, B, C, D, E> func)\n    {\n        func(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A, B, C, D, E>((A, B, C, D, E) self, Action<A> first, Action<B> second, Action<C> third, Action<D> fourth, Action<E> fifth)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        fourth(self.Item4);\n        fifth(self.Item5);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S fold<A, B, C, D, E, S>((A, B, C, D, E) self, S state, Func<S, A, B, C, D, E, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3, self.Item4, self.Item5);\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S quintFold<A, B, C, D, E, S>((A, B, C, D, E) self, S state, Func<S, A, S> firstFold, Func<S, B, S> secondFold, Func<S, C, S> thirdFold, Func<S, D, S> fourthFold, Func<S, E, S> fifthFold) =>\n        fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3), self.Item4), self.Item5);\n\n    /// <summary>\n    /// Fold back\n    /// </summary>\n    [Pure]\n    public static S quintFoldBack<A, B, C, D, E, S>((A, B, C, D, E) self, S state, Func<S, E, S> firstFold, Func<S, D, S> secondFold, Func<S, C, S> thirdFold, Func<S, B, S> fourthFold, Func<S, A, S> fifthFold) =>\n        fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item5), self.Item4), self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple6/ValueTuple6.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\npublic static class ValueTuple6Extensions\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, F, G) Add<A, B, C, D, E, F, G>(this (A, B, C, D, E, F) self, G seventh) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, seventh);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static A Head<A, B, C, D, E, F>(this (A, B, C, D, E, F) self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static F Last<A, B, C, D, E, F>(this (A, B, C, D, E, F) self) =>\n        self.Item6;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static (B, C, D, E, F) Tail<A, B, C, D, E, F>(this(A, B, C, D, E, F) self) =>\n        (self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool Contains<EQ, A>(this (A, A, A, A, A, A) self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value) ||\n        EQ.Equals(self.Item4, value) ||\n        EQ.Equals(self.Item5, value) ||\n        EQ.Equals(self.Item6, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, D, E, F, R>(this ValueTuple<A, B, C, D, E, F> self, Func<ValueTuple<A, B, C, D, E, F>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, D, E, F, R>(this ValueTuple<A, B, C, D, E, F> self, Func<A, B, C, D, E, F, R> map) =>\n        map(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static (U, V, W, X, Y, Z) Map<A, B, C, D, E, F, U, V, W, X, Y, Z>(this(A, B, C, D, E, F) self, Func<A, U> firstMap, Func<B, V> secondMap, Func<C, W> thirdMap, Func<D, X> fourthMap, Func<E, Y> fifthMap, Func<F, Z> sixthMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3), fourthMap(self.Item4), fifthMap(self.Item5), sixthMap(self.Item6));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (R1, B, C, D, E, F) MapFirst<A, B, C, D, E, F, R1>(this (A, B, C, D, E, F) self, Func<A, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, R2, C, D, E, F) MapSecond<A, B, C, D, E, F, R2>(this (A, B, C, D, E, F) self, Func<B, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, R3, D, E, F) MapThird<A, B, C, D, E, F, R3>(this (A, B, C, D, E, F) self, Func<C, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3), self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Fourth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, R4, E, F) MapFourth<A, B, C, D, E, F, R4>(this(A, B, C, D, E, F) self, Func<D, R4> fourthMap) =>\n        (self.Item1, self.Item2, self.Item3, fourthMap(self.Item4), self.Item5, self.Item6);\n\n    /// <summary>\n    /// Fifth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, R5, F) MapFifth<A, B, C, D, E, F, R5>(this(A, B, C, D, E, F) self, Func<E, R5> fifthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, fifthMap(self.Item5), self.Item6);\n\n    /// <summary>\n    /// Sixth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, R6) MapSixth<A, B, C, D, E, F, R6>(this(A, B, C, D, E, F) self, Func<F, R6> sixthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, sixthMap(self.Item6));\n\n    /// <summary>\n    /// Map to tuple\n    /// </summary>\n    [Pure]\n    public static (U, V, W, X, Y, Z) Select<A, B, C, D, E, F, U, V, W, X, Y, Z>(this (A, B, C, D, E, F) self, Func<(A, B, C, D, E, F), (U, V, W, X, Y, Z)> map) =>\n        map(self);\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A, B, C, D, E, F>(this (A, B, C, D, E, F) self, Action<A, B, C, D, E, F> func)\n    {\n        func(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A, B, C, D, E, F>(this (A, B, C, D, E, F) self, Action<A> first, Action<B> second, Action<C> third, Action<D> fourth, Action<E> fifth, Action<F> sixth)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        fourth(self.Item4);\n        fifth(self.Item5);\n        sixth(self.Item6);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S Fold<A, B, C, D, E, F, S>(this (A, B, C, D, E, F) self, S state, Func<S, A, B, C, D, E, F, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S SextFold<A, B, C, D, E, F, S>(this(A, B, C, D, E, F) self, S state, Func<S, A, S> firstFold, Func<S, B, S> secondFold, Func<S, C, S> thirdFold, Func<S, D, S> fourthFold, Func<S, E, S> fifthFold, Func<S, F, S> sixthFold) =>\n        sixthFold(fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3), self.Item4), self.Item5), self.Item6);\n\n    /// <summary>\n    /// Fold back\n    /// </summary>\n    [Pure]\n    public static S SextFoldBack<A, B, C, D, E, F, S>(this (A, B, C, D, E, F) self, S state, Func<S, F, S> firstFold, Func<S, E, S> secondFold, Func<S, D, S> thirdFold, Func<S, C, S> fourthFold, Func<S, B, S> fifthFold, Func<S, A, S> sixthFold) =>\n        sixthFold(fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item6), self.Item5), self.Item4), self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple6/ValueTuple6.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, F, G) add<A, B, C, D, E, F, G>((A, B, C, D, E, F) self, G seventh) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, seventh);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static A head<A, B, C, D, E, F>((A, B, C, D, E, F) self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static F last<A, B, C, D, E, F>((A, B, C, D, E, F) self) =>\n        self.Item6;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static (B, C, D, E, F) tail<A, B, C, D, E, F>((A, B, C, D, E, F) self) =>\n        (self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool contains<EQ, A>((A, A, A, A, A, A) self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value) ||\n        EQ.Equals(self.Item4, value) ||\n        EQ.Equals(self.Item5, value) ||\n        EQ.Equals(self.Item6, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, D, E, F, R>(ValueTuple<A, B, C, D, E, F> self, Func<ValueTuple<A, B, C, D, E, F>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, D, E, F, R>(ValueTuple<A, B, C, D, E, F> self, Func<A, B, C, D, E, F, R> map) =>\n        map(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static (U, V, W, X, Y, Z) map<A, B, C, D, E, F, U, V, W, X, Y, Z>((A, B, C, D, E, F) self, Func<A, U> firstMap, Func<B, V> secondMap, Func<C, W> thirdMap, Func<D, X> fourthMap, Func<E, Y> fifthMap, Func<F, Z> sixthMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3), fourthMap(self.Item4), fifthMap(self.Item5), sixthMap(self.Item6));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (R1, B, C, D, E, F) mapFirst<A, B, C, D, E, F, R1>((A, B, C, D, E, F) self, Func<A, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, R2, C, D, E, F) mapSecond<A, B, C, D, E, F, R2>((A, B, C, D, E, F) self, Func<B, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, R3, D, E, F) mapThird<A, B, C, D, E, F, R3>((A, B, C, D, E, F) self, Func<C, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3), self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Fourth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, R4, E, F) mapFourth<A, B, C, D, E, F, R4>((A, B, C, D, E, F) self, Func<D, R4> fourthMap) =>\n        (self.Item1, self.Item2, self.Item3, fourthMap(self.Item4), self.Item5, self.Item6);\n\n    /// <summary>\n    /// Fifth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, R5, F) mapFifth<A, B, C, D, E, F, R5>((A, B, C, D, E, F) self, Func<E, R5> fifthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, fifthMap(self.Item5), self.Item6);\n\n    /// <summary>\n    /// Sixth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, R6) mapSixth<A, B, C, D, E, F, R6>((A, B, C, D, E, F) self, Func<F, R6> sixthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, sixthMap(self.Item6));\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A, B, C, D, E, F>((A, B, C, D, E, F) self, Action<A, B, C, D, E, F> func)\n    {\n        func(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A, B, C, D, E, F>((A, B, C, D, E, F) self, Action<A> first, Action<B> second, Action<C> third, Action<D> fourth, Action<E> fifth, Action<F> sixth)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        fourth(self.Item4);\n        fifth(self.Item5);\n        sixth(self.Item6);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S fold<A, B, C, D, E, F, S>((A, B, C, D, E, F) self, S state, Func<S, A, B, C, D, E, F, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6);\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S sextFold<A, B, C, D, E, F, S>((A, B, C, D, E, F) self, S state, Func<S, A, S> firstFold, Func<S, B, S> secondFold, Func<S, C, S> thirdFold, Func<S, D, S> fourthFold, Func<S, E, S> fifthFold, Func<S, F, S> sixthFold) =>\n        sixthFold(fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3), self.Item4), self.Item5), self.Item6);\n\n    /// <summary>\n    /// Fold back\n    /// </summary>\n    [Pure]\n    public static S sextFoldBack<A, B, C, D, E, F, S>((A, B, C, D, E, F) self, S state, Func<S, F, S> firstFold, Func<S, E, S> secondFold, Func<S, D, S> thirdFold, Func<S, C, S> fourthFold, Func<S, B, S> fifthFold, Func<S, A, S> sixthFold) =>\n        sixthFold(fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item6), self.Item5), self.Item4), self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple7/ValueTuple7.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\npublic static class ValueTuple7Extensions\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, F, G, H) Add<A, B, C, D, E, F, G, H>(this (A, B, C, D, E, F, G) self, H eighth) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7, eighth);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static A Head<A, B, C, D, E, F, G>(this (A, B, C, D, E, F, G) self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static G Last<A, B, C, D, E, F, G>(this (A, B, C, D, E, F, G) self) =>\n        self.Item7;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static (B, C, D, E, F, G) Tail<A, B, C, D, E, F, G>(this(A, B, C, D, E, F, G) self) =>\n        (self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool Contains<EQ, A>(this (A, A, A, A, A, A, A) self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value) ||\n        EQ.Equals(self.Item4, value) ||\n        EQ.Equals(self.Item5, value) ||\n        EQ.Equals(self.Item6, value) ||\n        EQ.Equals(self.Item7, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, D, E, F, G, R>(this ValueTuple<A, B, C, D, E, F, G> self, Func<ValueTuple<A, B, C, D, E, F, G>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R Map<A, B, C, D, E, F, G, R>(this ValueTuple<A, B, C, D, E, F, G> self, Func<A, B, C, D, E, F, G, R> map) =>\n        map(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static (T, U, V, W, X, Y, Z) Map<A, B, C, D, E, F, G, T, U, V, W, X, Y, Z>(this(A, B, C, D, E, F, G) self, Func<A, T> firstMap, Func<B, U> secondMap, Func<C, V> thirdMap, Func<D, W> fourthMap, Func<E, X> fifthMap, Func<F, Y> sixthMap, Func<G, Z> seventhMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3), fourthMap(self.Item4), fifthMap(self.Item5), sixthMap(self.Item6), seventhMap(self.Item7));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (R1, B, C, D, E, F, G) MapFirst<A, B, C, D, E, F, G, R1>(this (A, B, C, D, E, F, G) self, Func<A, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, R2, C, D, E, F, G) MapSecond<A, B, C, D, E, F, G, R2>(this (A, B, C, D, E, F, G) self, Func<B, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, R3, D, E, F, G) MapThird<A, B, C, D, E, F, G, R3>(this (A, B, C, D, E, F, G) self, Func<C, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3), self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Fourth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, R4, E, F, G) MapFourth<A, B, C, D, E, F, G, R4>(this(A, B, C, D, E, F, G) self, Func<D, R4> fourthMap) =>\n        (self.Item1, self.Item2, self.Item3, fourthMap(self.Item4), self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Fifth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, R5, F, G) MapFifth<A, B, C, D, E, F, G, R5>(this(A, B, C, D, E, F, G) self, Func<E, R5> fifthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, fifthMap(self.Item5), self.Item6, self.Item7);\n\n    /// <summary>\n    /// Sixth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, R6, G) MapSixth<A, B, C, D, E, F, G, R6>(this(A, B, C, D, E, F, G) self, Func<F, R6> sixthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, sixthMap(self.Item6), self.Item7);\n\n    /// <summary>\n    /// Sixth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, F, R7) MapSeventh<A, B, C, D, E, F, G, R7>(this(A, B, C, D, E, F, G) self, Func<G, R7> seventhMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, seventhMap(self.Item7));\n\n    /// <summary>\n    /// Map to tuple\n    /// </summary>\n    [Pure]\n    public static (U, V, W, X, Y, Z) Select<A, B, C, D, E, F, G, U, V, W, X, Y, Z>(this (A, B, C, D, E, F, G) self, Func<(A, B, C, D, E, F, G), (U, V, W, X, Y, Z)> map) =>\n        map(self);\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A, B, C, D, E, F, G>(this (A, B, C, D, E, F, G) self, Action<A, B, C, D, E, F, G> func)\n    {\n        func(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit Iter<A, B, C, D, E, F, G>(this (A, B, C, D, E, F, G) self, Action<A> first, Action<B> second, Action<C> third, Action<D> fourth, Action<E> fifth, Action<F> sixth, Action<G> seventh)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        fourth(self.Item4);\n        fifth(self.Item5);\n        sixth(self.Item6);\n        seventh(self.Item7);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S Fold<A, B, C, D, E, F, G, S>(this (A, B, C, D, E, F, G) self, S state, Func<S, A, B, C, D, E, F, G, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S SeptFold<A, B, C, D, E, F, G, S>(this(A, B, C, D, E, F, G) self, S state, Func<S, A, S> firstFold, Func<S, B, S> secondFold, Func<S, C, S> thirdFold, Func<S, D, S> fourthFold, Func<S, E, S> fifthFold, Func<S, F, S> sixthFold, Func<S, G, S> seventhFold) =>\n        seventhFold(sixthFold(fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3), self.Item4), self.Item5), self.Item6), self.Item7);\n\n    /// <summary>\n    /// Fold back\n    /// </summary>\n    [Pure]\n    public static S SeptFoldBack<A, B, C, D, E, F, G, S>(this (A, B, C, D, E, F, G) self, S state, Func<S, G, S> firstFold, Func<S, F, S> secondFold, Func<S, E, S> thirdFold, Func<S, D, S> fourthFold, Func<S, C, S> fifthFold, Func<S, B, S> sixthFold, Func<S, A, S> seventhFold) =>\n        seventhFold(sixthFold(fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item7), self.Item6), self.Item5), self.Item4), self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/DataTypes/ValueTuple/Tuple7/ValueTuple7.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Append an extra item to the tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, F, G, H) add<A, B, C, D, E, F, G, H>((A, B, C, D, E, F, G) self, H eighth) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7, eighth);\n\n    /// <summary>\n    /// Take the first item\n    /// </summary>\n    [Pure]\n    public static A head<A, B, C, D, E, F, G>((A, B, C, D, E, F, G) self) =>\n        self.Item1;\n\n    /// <summary>\n    /// Take the last item\n    /// </summary>\n    [Pure]\n    public static G last<A, B, C, D, E, F, G>((A, B, C, D, E, F, G) self) =>\n        self.Item7;\n\n    /// <summary>\n    /// Take the second item onwards and build a new tuple\n    /// </summary>\n    [Pure]\n    public static (B, C, D, E, F, G) tail<A, B, C, D, E, F, G>((A, B, C, D, E, F, G) self) =>\n        (self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// One of the items matches the value passed\n    /// </summary>\n    [Pure]\n    public static bool contains<EQ, A>((A, A, A, A, A, A, A) self, A value)\n        where EQ : Eq<A> =>\n        EQ.Equals(self.Item1, value) ||\n        EQ.Equals(self.Item2, value) ||\n        EQ.Equals(self.Item3, value) ||\n        EQ.Equals(self.Item4, value) ||\n        EQ.Equals(self.Item5, value) ||\n        EQ.Equals(self.Item6, value) ||\n        EQ.Equals(self.Item7, value);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, D, E, F, G, R>(ValueTuple<A, B, C, D, E, F, G> self, Func<ValueTuple<A, B, C, D, E, F, G>, R> map) =>\n        map(self);\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    public static R map<A, B, C, D, E, F, G, R>(ValueTuple<A, B, C, D, E, F, G> self, Func<A, B, C, D, E, F, G, R> map) =>\n        map(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Tri-map to tuple\n    /// </summary>\n    [Pure]\n    public static (T, U, V, W, X, Y, Z) map<A, B, C, D, E, F, G, T, U, V, W, X, Y, Z>((A, B, C, D, E, F, G) self, Func<A, T> firstMap, Func<B, U> secondMap, Func<C, V> thirdMap, Func<D, W> fourthMap, Func<E, X> fifthMap, Func<F, Y> sixthMap, Func<G, Z> seventhMap) =>\n        (firstMap(self.Item1), secondMap(self.Item2), thirdMap(self.Item3), fourthMap(self.Item4), fifthMap(self.Item5), sixthMap(self.Item6), seventhMap(self.Item7));\n\n    /// <summary>\n    /// First item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (R1, B, C, D, E, F, G) mapFirst<A, B, C, D, E, F, G, R1>((A, B, C, D, E, F, G) self, Func<A, R1> firstMap) =>\n        (firstMap(self.Item1), self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Second item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, R2, C, D, E, F, G) mapSecond<A, B, C, D, E, F, G, R2>((A, B, C, D, E, F, G) self, Func<B, R2> secondMap) =>\n        (self.Item1, secondMap(self.Item2), self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Third item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, R3, D, E, F, G) mapThird<A, B, C, D, E, F, G, R3>((A, B, C, D, E, F, G) self, Func<C, R3> thirdMap) =>\n        (self.Item1, self.Item2, thirdMap(self.Item3), self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Fourth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, R4, E, F, G) mapFourth<A, B, C, D, E, F, G, R4>((A, B, C, D, E, F, G) self, Func<D, R4> fourthMap) =>\n        (self.Item1, self.Item2, self.Item3, fourthMap(self.Item4), self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Fifth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, R5, F, G) mapFifth<A, B, C, D, E, F, G, R5>((A, B, C, D, E, F, G) self, Func<E, R5> fifthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, fifthMap(self.Item5), self.Item6, self.Item7);\n\n    /// <summary>\n    /// Sixth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, R6, G) mapSixth<A, B, C, D, E, F, G, R6>((A, B, C, D, E, F, G) self, Func<F, R6> sixthMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, sixthMap(self.Item6), self.Item7);\n\n    /// <summary>\n    /// Sixth item-map to tuple\n    /// </summary>\n    [Pure]\n    public static (A, B, C, D, E, F, R7) mapSeventh<A, B, C, D, E, F, G, R7>((A, B, C, D, E, F, G) self, Func<G, R7> seventhMap) =>\n        (self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, seventhMap(self.Item7));\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A, B, C, D, E, F, G>((A, B, C, D, E, F, G) self, Action<A, B, C, D, E, F, G> func)\n    {\n        func(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Iterate\n    /// </summary>\n    public static Unit iter<A, B, C, D, E, F, G>((A, B, C, D, E, F, G) self, Action<A> first, Action<B> second, Action<C> third, Action<D> fourth, Action<E> fifth, Action<F> sixth, Action<G> seventh)\n    {\n        first(self.Item1);\n        second(self.Item2);\n        third(self.Item3);\n        fourth(self.Item4);\n        fifth(self.Item5);\n        sixth(self.Item6);\n        seventh(self.Item7);\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S fold<A, B, C, D, E, F, G, S>((A, B, C, D, E, F, G) self, S state, Func<S, A, B, C, D, E, F, G, S> fold) =>\n        fold(state, self.Item1, self.Item2, self.Item3, self.Item4, self.Item5, self.Item6, self.Item7);\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    public static S septFold<A, B, C, D, E, F, G, S>((A, B, C, D, E, F, G) self, S state, Func<S, A, S> firstFold, Func<S, B, S> secondFold, Func<S, C, S> thirdFold, Func<S, D, S> fourthFold, Func<S, E, S> fifthFold, Func<S, F, S> sixthFold, Func<S, G, S> seventhFold) =>\n        seventhFold(sixthFold(fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item1), self.Item2), self.Item3), self.Item4), self.Item5), self.Item6), self.Item7);\n\n    /// <summary>\n    /// Fold back\n    /// </summary>\n    [Pure]\n    public static S septFoldBack<A, B, C, D, E, F, G, S>((A, B, C, D, E, F, G) self, S state, Func<S, G, S> firstFold, Func<S, F, S> secondFold, Func<S, E, S> thirdFold, Func<S, D, S> fourthFold, Func<S, C, S> fifthFold, Func<S, B, S> sixthFold, Func<S, A, S> seventhFold) =>\n        seventhFold(sixthFold(fifthFold(fourthFold(thirdFold(secondFold(firstFold(state, self.Item7), self.Item6), self.Item5), self.Item4), self.Item3), self.Item2), self.Item1);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Alternative.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    public interface Alternative<Supertype, Subtype> :\n        Alternative<Supertype>,\n        Choice<Supertype, Subtype>,\n        Applicative<Supertype, Subtype>\n        where Supertype : Alternative<Supertype, Subtype>\n        where Subtype : Alternative<Subtype>;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derived applicative functor implementation\n    /// </summary>\n    /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n    /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n    public interface Applicative<Supertype, Subtype> :\n        Applicative<Supertype>,\n        Functor<Supertype, Subtype>\n        where Subtype : Applicative<Subtype>\n        where Supertype : Applicative<Supertype, Subtype>\n    {\n        static K<Supertype, A> Applicative<Supertype>.Pure<A>(A value) => \n            Supertype.CoTransform(Subtype.Pure(value));\n\n        static K<Supertype, B> Applicative<Supertype>.Action<A, B>(K<Supertype, A> ma, K<Supertype, B> mb) => \n            Supertype.CoTransform(Subtype.Action(Supertype.Transform(ma), Supertype.Transform(mb)));\n\n        static K<Supertype, B> Applicative<Supertype>.Apply<A, B>(K<Supertype, Func<A, B>> mf, K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.Apply(Supertype.Transform(mf), Supertype.Transform(ma)));\n\n        static K<Supertype, B> Applicative<Supertype>.Apply<A, B>(K<Supertype, Func<A, B>> mf, Memo<Supertype, A> ma) => \n            Supertype.CoTransform(Subtype.Apply(Supertype.Transform(mf), Memo.transform<Supertype, Subtype, A>(ma)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Choice.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// A semigroup on applicative functors\n    /// </summary>\n    public interface Choice<Supertype, Subtype> :\n        Choice<Supertype>,\n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Supertype : Choice<Supertype, Subtype>\n        where Subtype : Choice<Subtype>\n    {\n        /// <summary>\n        /// Where `Supertype` defines some notion of failure or choice, this function picks\n        /// the first argument that succeeds.  So, if `fa` succeeds, then `fa` is returned;\n        /// if it fails, then `fb` is returned.\n        /// </summary>\n        /// <param name=\"fa\">First structure to test</param>\n        /// <param name=\"fb\">Second structure to return if the first one fails</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>First argument to succeed</returns>\n        static K<Supertype, A> Choice<Supertype>.Choose<A>(K<Supertype, A> fa, K<Supertype, A> fb) =>\n            Supertype.CoTransform(Subtype.Choose(Supertype.Transform(fa), Supertype.Transform(fb)));\n\n        /// <summary>\n        /// Where `Supertype` defines some notion of failure or choice, this function picks\n        /// the first argument that succeeds.  So, if `fa` succeeds, then `fa` is returned;\n        /// if it fails, then `fb` is returned.\n        /// </summary>\n        /// <param name=\"fa\">First structure to test</param>\n        /// <param name=\"fb\">Second structure to return if the first one fails</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>First argument to succeed</returns>\n        static K<Supertype, A> Choice<Supertype>.Choose<A>(K<Supertype, A> fa, Memo<Supertype, A> fb) =>\n            Supertype.CoTransform(Subtype.Choose(Supertype.Transform(fa), Memo.transform<Supertype, Subtype, A>(fb)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Cofunctor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derive the class of contravariant functors.\n    /// \n    /// Whereas one can think of a `Functor` as containing or producing values, a contravariant functor is a functor that\n    /// can be thought of as consuming values.\n    /// \n    /// Contravariant functors are referred to colloquially as Cofunctor, even though the dual of a `Functor` is just\n    /// a `Functor`. \n    /// </summary>\n    /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n    /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n    public interface Cofunctor<Supertype, Subtype> : \n        Cofunctor<Supertype>, \n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Subtype : Cofunctor<Subtype>\n        where Supertype : Cofunctor<Supertype, Subtype>\n    {\n        static K<Supertype, A> Cofunctor<Supertype>.Comap<A, B>(Func<A, B> f, K<Supertype, B> fb) =>\n            Supertype.CoTransform(Subtype.Comap(f, Supertype.Transform(fb)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Decidable.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derive a `Decidable` contravariant functor that is the contravariant analogue of `Alternative`.\n    /// \n    /// Noting the superclass constraint that `f` must also be `Divisible`, a `Decidable` functor has the ability to\n    /// \"fan out\" input, under the intuition that contravariant functors consume input.\n    /// </summary>\n    /// <typeparam name=\"F\">Self referring type</typeparam>\n    public interface Decidable<Supertype, Subtype> : \n        Divisible<Supertype, Subtype>, \n        Decidable<Supertype>\n        where Subtype : Decidable<Subtype>\n        where Supertype : Decidable<Supertype, Subtype>\n    {\n        static K<Supertype, A> Decidable<Supertype>.Lose<A>(Func<A, Void> f) => \n            Supertype.CoTransform(Subtype.Lose(f));\n\n        static K<Supertype, A> Decidable<Supertype>.Route<A, B, C>(\n            Func<A, Either<B, C>> f, \n            K<Supertype, B> fb, \n            K<Supertype, C> fc) => \n            Supertype.CoTransform(Subtype.Route(f, Supertype.Transform(fb), Supertype.Transform(fc)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Divisible.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    public interface Divisible<Supertype, Subtype> : \n        Cofunctor<Supertype, Subtype>, \n        Divisible<Supertype>\n        where Subtype : Decidable<Subtype>\n        where Supertype : Decidable<Supertype, Subtype>\n    {\n        static K<Supertype, A> Divisible<Supertype>.Divide<A, B, C>(\n            Func<A, (B Left, C Right)> f, \n            K<Supertype, B> fb, \n            K<Supertype, C> fc) => \n            Supertype.CoTransform(Subtype.Divide(f, Supertype.Transform(fb), Supertype.Transform(fc)));\n\n        static K<Supertype, A> Divisible<Supertype>.Conquer<A>() => \n            Supertype.CoTransform(Subtype.Conquer<A>());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Fallible.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Trait for higher-kinded structures that have a failure state `E`\n    /// </summary>\n    public interface Fallible<E, Supertype, Subtype> : \n        Traits.Fallible<E, Supertype>\n        where Supertype :\n            Fallible<E, Supertype, Subtype>, \n            Traits.Fallible<E, Supertype>,\n            Traits.Natural<Supertype, Subtype>,\n            Traits.CoNatural<Supertype, Subtype>\n        where Subtype : Traits.Fallible<E, Subtype>\n    {\n        /// <summary>\n        /// Raise a failure state in the `Fallible` structure `F`\n        /// </summary>\n        /// <param name=\"error\">Error value</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns></returns>\n        static K<Supertype, A> Traits.Fallible<E, Supertype>.Fail<A>(E error) =>\n            Supertype.CoTransform(Subtype.Fail<A>(error));\n\n        /// <summary>\n        /// Run the `Fallible` structure.  If in a failed state, test the failure value\n        /// against the predicate.  If, it returns `true`, run the `Fail` function with\n        /// the failure value.\n        /// </summary>\n        /// <param name=\"fa\">`Fallible` structure</param>\n        /// <param name=\"Predicate\">Predicate to test any failure values</param>\n        /// <param name=\"Fail\">Handler when in failed state</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n        /// predicate returns true for the failure value</returns>\n        static K<Supertype, A> Traits.Fallible<E, Supertype>.Catch<A>(\n            K<Supertype, A> fa,\n            Func<E, bool> Predicate,\n            Func<E, K<Supertype, A>> Fail) =>\n            Supertype.CoTransform(Subtype.Catch(Supertype.Transform(fa), Predicate, e => Supertype.Transform(Fail(e))));\n    }\n\n    /// <summary>\n    /// Trait for higher-kinded structures that have a failure state `E`\n    /// </summary>\n    public interface Fallible<Supertype, Subtype> : \n        Fallible<Error, Supertype, Subtype> \n        where Supertype : \n            Fallible<Error, Supertype, Subtype>, \n            Traits.Natural<Supertype, Subtype>, \n            Traits.CoNatural<Supertype, Subtype>\n        where Subtype : Traits.Fallible<Error, Subtype>;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Final.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derives `finally` in a `try/finally` operation\n    /// </summary>\n    public interface Final<Supertype, Subtype> : \n        Final<Supertype>,\n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Supertype : Final<Supertype>, Final<Supertype, Subtype>\n        where Subtype : Final<Subtype>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the `fa` operation regardless of whether `fa` succeeds or not.\n        /// </summary>\n        /// <param name=\"fa\">Primary operation</param>\n        /// <param name=\"finally\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        static K<Supertype, A> Final<Supertype>.Finally<X, A>(K<Supertype, A> fa, K<Supertype, X> @finally) =>\n            Supertype.CoTransform(Subtype.Finally(Supertype.Transform(fa), Supertype.Transform(@finally)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Foldable.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    public interface Foldable<Supertype, Subtype> :\n        Foldable<Supertype>,\n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Supertype : Foldable<Supertype>, Foldable<Supertype, Subtype>\n        where Subtype : Foldable<Subtype>\n    {\n        /// <summary>\n        /// Same behaviour as `Fold` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair \n        /// </summary>\n        static S Foldable<Supertype>.FoldWhile<A, S>(\n            Func<A, Func<S, S>> f,\n            Func<(S State, A Value), bool> predicate,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldWhile(f, predicate, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair \n        /// </summary>\n        static S Foldable<Supertype>.FoldBackWhile<A, S>(\n            Func<S, Func<A, S>> f,\n            Func<(S State, A Value), bool> predicate,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldBackWhile(f, predicate, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Fold until the `Option` returns `None`\n        /// </summary>\n        /// <param name=\"f\">Fold function</param>\n        /// <param name=\"initialState\">Initial state for the fold</param>\n        /// <param name=\"ta\">Foldable structure</param>\n        /// <typeparam name=\"A\">Value type</typeparam>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <returns>Aggregated value</returns>\n        static S Foldable<Supertype>.FoldMaybe<A, S>(\n            Func<S, Func<A, Option<S>>> f,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldMaybe(f, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Fold until the `Option` returns `None`\n        /// </summary>\n        /// <param name=\"f\">Fold function</param>\n        /// <param name=\"initialState\">Initial state for the fold</param>\n        /// <param name=\"ta\">Foldable structure</param>\n        /// <typeparam name=\"A\">Value type</typeparam>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <returns>Aggregated value</returns>\n        static S Foldable<Supertype>.FoldBackMaybe<A, S>(\n            Func<A, Func<S, Option<S>>> f,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldBackMaybe(f, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        static K<M, S> Foldable<Supertype>.FoldWhileM<A, M, S>(\n            Func<A, Func<S, K<M, S>>> f,\n            Func<(S State, A Value), bool> predicate,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldWhileM(f, predicate, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        static K<M, S> Foldable<Supertype>.FoldBackWhileM<A, M, S>(\n            Func<S, Func<A, K<M, S>>> f,\n            Func<(S State, A Value), bool> predicate,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldBackWhileM(f, predicate, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Same behaviour as `Fold` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair\n        /// </summary>\n        static S Foldable<Supertype>.FoldUntil<A, S>(\n            Func<A, Func<S, S>> f,\n            Func<(S State, A Value), bool> predicate,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldUntil(f, predicate, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        static K<M, S> Foldable<Supertype>.FoldUntilM<A, M, S>(\n            Func<A, Func<S, K<M, S>>> f,\n            Func<(S State, A Value), bool> predicate,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldUntilM(f, predicate, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair\n        /// </summary>\n        static S Foldable<Supertype>.FoldBackUntil<A, S>(\n            Func<S, Func<A, S>> f,\n            Func<(S State, A Value), bool> predicate,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldBackUntil(f, predicate, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        static K<M, S> Foldable<Supertype>.FoldBackUntilM<A, M, S>(\n            Func<S, Func<A, K<M, S>>> f,\n            Func<(S State, A Value), bool> predicate,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldBackUntilM(f, predicate, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Right-associative fold of a structure, lazy in the accumulator.\n        ///\n        /// In the case of lists, 'Fold', when applied to a binary operator, a\n        /// starting value (typically the right-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from right to left.\n        /// </summary>\n        static S Foldable<Supertype>.Fold<A, S>(Func<A, Func<S, S>> f, S initialState, K<Supertype, A> ta) =>\n            Subtype.Fold(f, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Right-associative fold of a structure, lazy in the accumulator.\n        ///\n        /// In the case of lists, 'Fold', when applied to a binary operator, a\n        /// starting value (typically the right-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from right to left.\n        /// </summary>\n        static K<M, S> Foldable<Supertype>.FoldM<A, M, S>(\n            Func<A, Func<S, K<M, S>>> f,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldM(f, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Left-associative fold of a structure, lazy in the accumulator.  This\n        /// is rarely what you want, but can work well for structures with efficient\n        /// right-to-left sequencing and an operator that is lazy in its left\n        /// argument.\n        /// \n        /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n        /// starting value (typically the left-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from left to right\n        /// </summary>\n        /// <remarks>\n        /// Note that to produce the outermost application of the operator the\n        /// entire input list must be traversed.  Like all left-associative folds,\n        /// `FoldBack` will diverge if given an infinite list.\n        /// </remarks>\n        static S Foldable<Supertype>.FoldBack<A, S>(Func<S, Func<A, S>> f, S initialState, K<Supertype, A> ta) =>\n            Subtype.FoldBack(f, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Left-associative fold of a structure, lazy in the accumulator.  This\n        /// is rarely what you want, but can work well for structures with efficient\n        /// right-to-left sequencing and an operator that is lazy in its left\n        /// argument.\n        /// \n        /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n        /// starting value (typically the left-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from left to right\n        /// </summary>\n        /// <remarks>\n        /// Note that to produce the outermost application of the operator the\n        /// entire input list must be traversed.  Like all left-associative folds,\n        /// `FoldBack` will diverge if given an infinite list.\n        /// </remarks>\n        static K<M, S> Foldable<Supertype>.FoldBackM<A, M, S>(\n            Func<S, Func<A, K<M, S>>> f,\n            S initialState,\n            K<Supertype, A> ta) =>\n            Subtype.FoldBackM(f, initialState, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        static A Foldable<Supertype>.Fold<A>(K<Supertype, A> tm) =>\n            Subtype.Fold(Supertype.Transform(tm));\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        static A Foldable<Supertype>.FoldWhile<A>(Func<(A State, A Value), bool> predicate, K<Supertype, A> tm) =>\n            Subtype.FoldWhile(predicate, Supertype.Transform(tm));\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        static A Foldable<Supertype>.FoldUntil<A>(Func<(A State, A Value), bool> predicate, K<Supertype, A> tm) =>\n            Subtype.FoldUntil(predicate, Supertype.Transform(tm));\n\n        /// <summary>\n        /// Map each element of the structure into a monoid, and combine the\n        /// results with `Append`.  This fold is right-associative and lazy in the\n        /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n        /// instead.\n        /// </summary>\n        static B Foldable<Supertype>.FoldMap<A, B>(Func<A, B> f, K<Supertype, A> ta) =>\n            Subtype.FoldMap(f, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Map each element of the structure into a monoid, and combine the\n        /// results with `Append`.  This fold is right-associative and lazy in the\n        /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n        /// instead.\n        /// </summary>\n        static B Foldable<Supertype>.FoldMapWhile<A, B>(\n            Func<A, B> f, Func<(B State, A Value), bool> predicate,\n            K<Supertype, A> ta) =>\n            Subtype.FoldMapWhile(f, predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Map each element of the structure into a monoid, and combine the\n        /// results with `Append`.  This fold is right-associative and lazy in the\n        /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n        /// instead.\n        /// </summary>\n        static B Foldable<Supertype>.FoldMapUntil<A, B>(\n            Func<A, B> f, Func<(B State, A Value), bool> predicate,\n            K<Supertype, A> ta) =>\n            Subtype.FoldMapUntil(f, predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// A left-associative variant of 'FoldMap' that is strict in the\n        /// accumulator.  Use this method for strict reduction when partial\n        /// results are merged via `Append`.\n        /// </summary>\n        static B Foldable<Supertype>.FoldMapBack<A, B>(Func<A, B> f, K<Supertype, A> ta) =>\n            Subtype.FoldMapBack(f, Supertype.Transform(ta));\n\n        /// <summary>\n        /// A left-associative variant of 'FoldMap' that is strict in the\n        /// accumulator.  Use this method for strict reduction when partial\n        /// results are merged via `Append`.\n        /// </summary>\n        static B Foldable<Supertype>.FoldMapWhileBack<A, B>(\n            Func<A, B> f, Func<(B State, A Value), bool> predicate,\n            K<Supertype, A> ta) =>\n            Subtype.FoldMapWhileBack(f, predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// A left-associative variant of 'FoldMap' that is strict in the\n        /// accumulator.  Use this method for strict reduction when partial\n        /// results are merged via `Append`.\n        /// </summary>\n        static B Foldable<Supertype>.FoldMapUntilBack<A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate,\n                                                            K<Supertype, A> ta) =>\n            Subtype.FoldMapUntilBack(f, predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        static Seq<A> Foldable<Supertype>.ToSeq<A>(K<Supertype, A> ta) =>\n            Subtype.ToSeq(Supertype.Transform(ta));\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        static Lst<A> Foldable<Supertype>.ToLst<A>(K<Supertype, A> ta) =>\n            Subtype.ToLst(Supertype.Transform(ta));\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        static Arr<A> Foldable<Supertype>.ToArr<A>(K<Supertype, A> ta) =>\n            Subtype.ToArr(Supertype.Transform(ta));\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        static Iterable<A> Foldable<Supertype>.ToIterable<A>(K<Supertype, A> ta) =>\n            Subtype.ToIterable(Supertype.Transform(ta));\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        static bool Foldable<Supertype>.IsEmpty<A>(K<Supertype, A> ta) =>\n            Subtype.IsEmpty(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Returns the size/length of a finite structure as an `int`.  The\n        /// default implementation just counts elements starting with the leftmost.\n        /// \n        /// Instances for structures that can compute the element count faster\n        /// than via element-by-element counting, should provide a specialised\n        /// implementation.\n        /// </summary>\n        static int Foldable<Supertype>.Count<A>(K<Supertype, A> ta) =>\n            Subtype.Count(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Does an element that fits the predicate occur in the structure?\n        /// </summary>\n        static bool Foldable<Supertype>.Exists<A>(Func<A, bool> predicate, K<Supertype, A> ta) =>\n            Subtype.Exists(predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Does the predicate hold for all elements in the structure?\n        /// </summary>\n        static bool Foldable<Supertype>.ForAll<A>(Func<A, bool> predicate, K<Supertype, A> ta) =>\n            Subtype.ForAll(predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Does the element exist in the structure?\n        /// </summary>\n        static bool Foldable<Supertype>.Contains<EqA, A>(A value, K<Supertype, A> ta) =>\n            Subtype.Contains(value, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Does the element exist in the structure?\n        /// </summary>\n        static bool Foldable<Supertype>.Contains<A>(A value, K<Supertype, A> ta) =>\n            Subtype.Contains(value, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the first element that match the predicate\n        /// </summary>\n        static Option<A> Foldable<Supertype>.Find<A>(Func<A, bool> predicate, K<Supertype, A> ta) =>\n            Subtype.Find(predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the last element that match the predicate\n        /// </summary>\n        static Option<A> Foldable<Supertype>.FindBack<A>(Func<A, bool> predicate, K<Supertype, A> ta) =>\n            Subtype.FindBack(predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the elements that match the predicate\n        /// </summary>\n        static Iterable<A> Foldable<Supertype>.FindAll<A>(Func<A, bool> predicate, K<Supertype, A> ta) =>\n            Subtype.FindAll(predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the elements that match the predicate\n        /// </summary>\n        static Iterable<A> Foldable<Supertype>.FindAllBack<A>(Func<A, bool> predicate, K<Supertype, A> ta) =>\n            Subtype.FindAllBack(predicate, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Computes the sum of the numbers of a structure.\n        /// </summary>\n        static A Foldable<Supertype>.Sum<A>(K<Supertype, A> ta) =>\n            Subtype.Sum(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Computes the product of the numbers of a structure.\n        /// </summary>\n        static A Foldable<Supertype>.Product<A>(K<Supertype, A> ta) =>\n            Subtype.Product(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Get the head item in the foldable or `None`\n        /// </summary>\n        static Option<A> Foldable<Supertype>.Head<A>(K<Supertype, A> ta) =>\n            Subtype.Head(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Get the head item in the foldable or `None`\n        /// </summary>\n        static Option<A> Foldable<Supertype>.Last<A>(K<Supertype, A> ta) =>\n            Subtype.Last(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Map each element of a structure to an 'Applicative' action, evaluate these\n        /// actions from left to right, and ignore the results.  For a version that\n        /// doesn't ignore the results see `Traversable.traverse`.\n        /// </summary>\n        static K<F, Unit> Foldable<Supertype>.Iter<F, A, B>(Func<A, K<F, B>> f, K<Supertype, A> ta) =>\n            Subtype.Iter(f, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Map each element of a structure to an action, evaluate these\n        /// actions from left to right, and ignore the results.  For a version that\n        /// doesn't ignore the results see `Traversable.traverse`.\n        /// </summary>\n        static Unit Foldable<Supertype>.Iter<A>(Action<A> f, K<Supertype, A> ta) =>\n            Subtype.Iter(f, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Map each element of a structure to an action, evaluate these\n        /// actions from left to right, and ignore the results.  For a version that\n        /// doesn't ignore the results see `Traversable.traverse`.\n        /// </summary>\n        static Unit Foldable<Supertype>.Iter<A>(Action<int, A> f, K<Supertype, A> ta) =>\n            Subtype.Iter(f, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the minimum value in the structure\n        /// </summary>\n        static Option<A> Foldable<Supertype>.Min<OrdA, A>(K<Supertype, A> ta) =>\n            Subtype.Min<OrdA, A>(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the minimum value in the structure\n        /// </summary>\n        static Option<A> Foldable<Supertype>.Min<A>(K<Supertype, A> ta) =>\n            Subtype.Min(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the maximum value in the structure\n        /// </summary>\n        static Option<A> Foldable<Supertype>.Max<OrdA, A>(K<Supertype, A> ta) =>\n            Subtype.Max<OrdA, A>(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the maximum value in the structure\n        /// </summary>\n        static Option<A> Foldable<Supertype>.Max<A>(K<Supertype, A> ta) =>\n            Subtype.Max(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the minimum value in the structure\n        /// </summary>\n        static A Foldable<Supertype>.Min<OrdA, A>(K<Supertype, A> ta, A initialMin) =>\n            Subtype.Min<OrdA, A>(Supertype.Transform(ta), initialMin);\n\n        /// <summary>\n        /// Find the minimum value in the structure\n        /// </summary>\n        static A Foldable<Supertype>.Min<A>(K<Supertype, A> ta, A initialMin) =>\n            Subtype.Min(Supertype.Transform(ta), initialMin);\n\n        /// <summary>\n        /// Find the maximum value in the structure\n        /// </summary>\n        static A Foldable<Supertype>.Max<OrdA, A>(K<Supertype, A> ta, A initialMax) =>\n            Subtype.Max<OrdA, A>(Supertype.Transform(ta), initialMax);\n\n        /// <summary>\n        /// Find the maximum value in the structure\n        /// </summary>\n        static A Foldable<Supertype>.Max<A>(K<Supertype, A> ta, A initialMax) =>\n            Subtype.Max(Supertype.Transform(ta), initialMax);\n\n        /// <summary>\n        /// Find the average of all the values in the structure\n        /// </summary>\n        static A Foldable<Supertype>.Average<A>(K<Supertype, A> ta) =>\n            Subtype.Average(Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the average of all the values in the structure\n        /// </summary>\n        static B Foldable<Supertype>.Average<A, B>(Func<A, B> f, K<Supertype, A> ta) =>\n            Subtype.Average(f, Supertype.Transform(ta));\n\n        /// <summary>\n        /// Find the element at the specified index or `None` if out of range\n        /// </summary>\n        static Option<A> Foldable<Supertype>.At<A>(K<Supertype, A> ta, Index index) =>\n            Subtype.At(Supertype.Transform(ta), index);\n\n        /// <summary>\n        /// Partition a foldable into two sequences based on a predicate\n        /// </summary>\n        /// <param name=\"f\">Predicate function</param>\n        /// <param name=\"ta\">Foldable structure</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>Partitioned structure</returns>\n        static (Seq<A> True, Seq<A> False) Foldable<Supertype>.Partition<A>(Func<A, bool> f, K<Supertype, A> ta) =>\n            Subtype.Partition(f, Supertype.Transform(ta));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derived functor implementation\n    /// </summary>\n    /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n    /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n    public interface Functor<Supertype, Subtype> : \n        Functor<Supertype>, \n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Subtype : Functor<Subtype>\n        where Supertype : Functor<Supertype, Subtype>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <param name=\"f\">Mapping function</param>\n        /// <param name=\"ma\">Functor structure to map</param>\n        /// <typeparam name=\"A\">Input bound value type</typeparam>\n        /// <typeparam name=\"B\">Output bound value type</typeparam>\n        /// <returns>Mapped functor</returns>\n        static K<Supertype, B> Functor<Supertype>.Map<A, B>(Func<A, B> f, K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.Map(f, Supertype.Transform(ma)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Maybe/MonadIO.cs",
    "content": "/*\nusing System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    public static partial class Maybe\n    {\n        /// <summary>\n        /// Derived `MonadIO` implementation\n        /// </summary>\n        /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n        /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n        // ReSharper disable once MemberHidesStaticFromOuterClass\n        public interface MonadIO<Supertype, Subtype> :\n            Monad<Supertype, Subtype>,\n            MonadIO<Supertype>\n            where Subtype : Traits.Maybe.MonadIO<Subtype>, Monad<Subtype>\n            where Supertype : MonadIO<Supertype, Subtype>, Monad<Supertype>\n        {\n            /// <summary>\n            /// Lift an IO operation into the `Self` monad\n            /// </summary>\n            /// <param name=\"ma\">IO structure to lift</param>\n            /// <typeparam name=\"A\">Bound value type</typeparam>\n            /// <returns>Monad with an `IO` structure lifted into it</returns>\n            /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n            /// the inner monad or any monad in the stack on the way to the inner monad,\n            /// then it will throw an exception.</exception>\n            static K<Supertype, A> Traits.Maybe.MonadIO<Supertype>.LiftIO<A>(K<IO, A> ma) =>\n                Supertype.CoTransform(Subtype.LiftIO(ma));\n\n            /// <summary>\n            /// Lift an IO operation into the `Self` monad\n            /// </summary>\n            /// <param name=\"ma\">IO structure to lift</param>\n            /// <typeparam name=\"A\">Bound value type</typeparam>\n            /// <returns>Monad with an `IO` structure lifted into it</returns>\n            /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n            /// the inner monad or any monad in the stack on the way to the inner monad,\n            /// then it will throw an exception.</exception>\n            static K<Supertype, A> Traits.Maybe.MonadIO<Supertype>.LiftIO<A>(IO<A> ma) =>\n                Supertype.CoTransform(Subtype.LiftIO(ma));\n        }\n    }\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Maybe/MonadUnliftIO.cs",
    "content": "/*\nusing System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    public static partial class Maybe\n    {\n        /// <summary>\n        /// Derived `MonadIO` implementation\n        /// </summary>\n        /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n        /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n        // ReSharper disable once MemberHidesStaticFromOuterClass\n        public interface MonadUnliftIO<Supertype, Subtype> :\n            MonadIO<Supertype, Subtype>,\n            MonadUnliftIO<Supertype>\n            where Subtype : Traits.Maybe.MonadUnliftIO<Subtype>, MonadIO<Subtype>\n            where Supertype : MonadUnliftIO<Supertype, Subtype>, \n                              MonadIO<Supertype>\n        {\n            /// <summary>\n            /// Extract the inner `IO` monad from the `Self` structure provided\n            /// </summary>\n            /// <param name=\"ma\">`Self` structure to extract the `IO` monad from</param>\n            /// <typeparam name=\"A\">Bound value type</typeparam>\n            /// <returns>`Self` structure with the `IO` structure as the bound value</returns>\n            static K<Supertype, IO<A>> Traits.Maybe.MonadUnliftIO<Supertype>.ToIO<A>(K<Supertype, A> ma) =>\n                Supertype.CoTransform(Subtype.ToIO(Supertype.Transform(ma)));\n\n            /// <summary>\n            /// Map the inner `IO` monad within the `Self` structure provided\n            /// </summary>\n            /// <param name=\"ma\">`Self` structure to extract the `IO` monad from</param>\n            /// <param name=\"f\">`IO` structure mapping function</param>\n            /// <typeparam name=\"A\">Input bound value type</typeparam>\n            /// <typeparam name=\"B\">Output bound value type</typeparam>\n            /// <returns>`Self` structure that has had its inner `IO` monad mapped</returns>\n            /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n            /// the inner monad or any monad in the stack on the way to the inner monad\n            /// then it will throw an exception.</exception>\n            static K<Supertype, B> Traits.Maybe.MonadUnliftIO<Supertype>.MapIO<A, B>(K<Supertype, A> ma, Func<IO<A>, IO<B>> f) =>\n                Supertype.CoTransform(Subtype.MapIO(Supertype.Transform(ma), f));\n        }\n    }\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derived monad implementation\n    /// </summary>\n    /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n    /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n    public interface Monad<Supertype, Subtype> :\n        Applicative<Supertype, Subtype>,\n        Monad<Supertype>\n        where Subtype : Monad<Subtype>\n        where Supertype : Monad<Supertype, Subtype>\n    {\n        /// <summary>\n        /// Monad bind operation.  Chains two operations together in sequence.\n        /// </summary>\n        /// <param name=\"ma\">First monad to run</param>\n        /// <param name=\"f\">Bind function that yields the second monad to run</param>\n        /// <typeparam name=\"A\">Input bound value type</typeparam>\n        /// <typeparam name=\"B\">Output bound value type</typeparam>\n        /// <returns>Composed chained monad operation</returns>\n        static K<Supertype, B> Monad<Supertype>.Bind<A, B>(K<Supertype, A> ma, Func<A, K<Supertype, B>> f) => \n            Supertype.CoTransform(Subtype.Bind(Supertype.Transform(ma), x => Supertype.Transform(f(x))));\n\n        static K<Supertype, A> Monad<Supertype>.Flatten<A>(K<Supertype, K<Supertype, A>> mma) => \n            Supertype.CoTransform(Subtype.Flatten(Supertype.Transform(mma.Map(Supertype.Transform))));\n\n        static K<Supertype, B> Monad<Supertype>.Recur<A, B>(\n            A value, Func<A, K<Supertype, Next<A, B>>> f) => \n            Supertype.CoTransform(Subtype.Recur(value, x => Supertype.Transform(f(x))));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/MonadIO.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derived `MonadIO` implementation\n    /// </summary>\n    /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n    /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n    public interface MonadIO<Supertype, Subtype> :\n        Monad<Supertype, Subtype>,\n        MonadIO<Supertype>\n        where Subtype : MonadIO<Subtype>, Monad<Subtype>\n        where Supertype : MonadIO<Supertype, Subtype>, Monad<Supertype>\n    {\n        /// <summary>\n        /// Lift an IO operation into the `Self` monad\n        /// </summary>\n        /// <param name=\"ma\">IO structure to lift</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>Monad with an `IO` structure lifted into it</returns>\n        /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n        /// the inner monad or any monad in the stack on the way to the inner monad\n        /// then it will throw an exception.</exception>\n        static K<Supertype, A> Traits.MonadIO<Supertype>.LiftIO<A>(K<IO, A> ma) =>\n            Supertype.CoTransform(Subtype.LiftIO(ma));\n\n        /// <summary>\n        /// Lift an IO operation into the `Self` monad\n        /// </summary>\n        /// <param name=\"ma\">IO structure to lift</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>Monad with an `IO` structure lifted into it</returns>\n        /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n        /// the inner monad or any monad in the stack on the way to the inner monad\n        /// then it will throw an exception.</exception>\n        static K<Supertype, A> Traits.MonadIO<Supertype>.LiftIO<A>(IO<A> ma) =>\n            Supertype.CoTransform(Subtype.LiftIO(ma));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/MonadT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derived monad-transformer implementation\n    /// </summary>\n    /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n    /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n    public interface MonadT<Supertype, Subtype, out M> :\n        Monad<Supertype, Subtype>,\n        MonadT<Supertype, M>\n        where Subtype : MonadT<Subtype, M>\n        where Supertype : MonadT<Supertype, Subtype, M>, MonadT<Supertype, M>\n        where M : Monad<M>\n    {\n        static K<Supertype, A> MonadT<Supertype, M>.Lift<A>(K<M, A> ma) => \n            Supertype.CoTransform(Subtype.Lift(ma));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/MonadUnliftIO.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derived `MonadUnliftIO` implementation\n    /// </summary>\n    /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n    /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n    public interface MonadUnliftIO<Supertype, Subtype> : \n        MonadIO<Supertype, Subtype>,\n        MonadUnliftIO<Supertype>\n        where Subtype : MonadUnliftIO<Subtype>, MonadIO<Subtype>\n        where Supertype : MonadUnliftIO<Supertype, Subtype>, Monad<Supertype>\n    {\n        /// <summary>\n        /// Extract the inner `IO` monad from the `Self` structure provided\n        /// </summary>\n        /// <param name=\"ma\">`Self` structure to extract the `IO` monad from</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>`Self` structure with the `IO` structure as the bound value</returns>\n        static K<Supertype, IO<A>> Traits.MonadUnliftIO<Supertype>.ToIO<A>(K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.ToIO(Supertype.Transform(ma)));\n\n        /// <summary>\n        /// Map the inner `IO` monad within the `Self` structure provided\n        /// </summary>\n        /// <param name=\"ma\">`Self` structure to extract the `IO` monad from</param>\n        /// <param name=\"f\">`IO` structure mapping function</param>\n        /// <typeparam name=\"A\">Input bound value type</typeparam>\n        /// <typeparam name=\"B\">Output bound value type</typeparam>\n        /// <returns>`Self` structure that has had its inner `IO` monad mapped</returns>\n        /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n        /// the inner monad or any monad in the stack on the way to the inner-monad\n        /// then it will throw an exception.</exception>\n        static K<Supertype, B> Traits.MonadUnliftIO<Supertype>.MapIO<A, B>(K<Supertype, A> ma, Func<IO<A>, IO<B>> f) =>\n            Supertype.CoTransform(Subtype.MapIO(Supertype.Transform(ma), f));        \n        \n        /// <summary>\n        /// Creates a local cancellation environment\n        /// </summary>\n        /// <remarks>\n        /// A local cancellation environment stops other IO computations, that rely on the same\n        /// environmental cancellation token, from being taken down by a regional cancellation.\n        ///\n        /// If an `IO.cancel` is invoked locally then it will still create an exception that\n        /// propagates upwards and so catching cancellations is still important. \n        /// </remarks>\n        /// <param name=\"ma\">Computation to run within the local context</param>\n        /// <typeparam name=\"A\">Bound value</typeparam>\n        /// <returns>Result of the computation</returns>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.LocalIO<A>(K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.LocalIO(Supertype.Transform(ma)));\n\n        /// <summary>\n        /// Make this IO computation run on the `SynchronizationContext` that was captured at the start\n        /// of the IO chain (i.e. the one embedded within the `EnvIO` environment that is passed through\n        /// all IO computations)\n        /// </summary>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.PostIO<A>(K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.PostIO(Supertype.Transform(ma)));\n\n        /// <summary>\n        /// Timeout operation if it takes too long\n        /// </summary>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.TimeoutIO<A>(K<Supertype, A> ma, TimeSpan timeout) =>\n            Supertype.CoTransform(Subtype.TimeoutIO(Supertype.Transform(ma), timeout));\n\n        /// <summary>\n        /// The IO monad tracks resources automatically; this creates a local resource environment\n        /// to run this computation in.  Once the computation is completed, any resources acquired\n        /// are automatically released.  Imagine this as the ultimate `using` statement.\n        /// </summary>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.BracketIO<A>(K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.BracketIO(Supertype.Transform(ma)));\n\n        /// <summary>\n        /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n        /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n        /// in between.\n        /// </summary>\n        /// <param name=\"Acq\">Resource acquisition</param>\n        /// <param name=\"Use\">Function to use the acquired resource</param>\n        /// <param name=\"Fin\">Function to invoke to release the resource</param>\n        static K<Supertype, C> MonadUnliftIO<Supertype>.BracketIO<A, B, C>(\n            K<Supertype, A> Acq,\n            Func<A, IO<C>> Use,\n            Func<A, IO<B>> Fin) =>\n            Supertype.CoTransform(Subtype.BracketIO(Supertype.Transform(Acq), Use, Fin));\n\n        /// <summary>\n        /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n        /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n        /// in between.\n        /// </summary>\n        /// <param name=\"Acq\">Resource acquisition</param>\n        /// <param name=\"Use\">Function to use the acquired resource</param>\n        /// <param name=\"Catch\">Function to run to handle any exceptions</param>\n        /// <param name=\"Fin\">Function to invoke to release the resource</param>\n        static K<Supertype, C> MonadUnliftIO<Supertype>.BracketIO<A, B, C>(\n            K<Supertype, A> Acq,\n            Func<A, IO<C>> Use,\n            Func<Error, IO<C>> Catch,\n            Func<A, IO<B>> Fin) =>\n            Supertype.CoTransform(Subtype.BracketIO(Supertype.Transform(Acq), Use, Catch, Fin));\n\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n        //\n        //  Repeating the effect\n        //\n\n        /// <summary>\n        /// Keeps repeating the computation forever, or until an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <returns>The result of the last invocation</returns>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RepeatIO<A>(K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.RepeatIO(Supertype.Transform(ma)));\n\n        /// <summary>\n        /// Keeps repeating the computation until the scheduler expires, or an error occurs  \n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <returns>The result of the last invocation</returns>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RepeatIO<A>(\n            K<Supertype, A> ma,\n            Schedule schedule) =>\n            Supertype.CoTransform(Subtype.RepeatIO(Supertype.Transform(ma), schedule));\n\n        /// <summary>\n        /// Keeps repeating the computation until the predicate returns false, or an error occurs \n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RepeatWhileIO<A>(\n            K<Supertype, A> ma,\n            Func<A, bool> predicate) =>\n            Supertype.CoTransform(Subtype.RepeatWhileIO(Supertype.Transform(ma), predicate));\n\n        /// <summary>\n        /// Keeps repeating the computation until the scheduler expires, or the predicate returns false, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RepeatWhileIO<A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            Func<A, bool> predicate) =>\n            Supertype.CoTransform(Subtype.RepeatWhileIO(Supertype.Transform(ma), schedule, predicate));\n\n        /// <summary>\n        /// Keeps repeating the computation until the predicate returns true, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RepeatUntilIO<A>(\n            K<Supertype, A> ma,\n            Func<A, bool> predicate) =>\n            Supertype.CoTransform(Subtype.RepeatUntilIO(Supertype.Transform(ma), predicate));\n\n        /// <summary>\n        /// Keeps repeating the computation until the scheduler expires, or the predicate returns true, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RepeatUntilIO<A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            Func<A, bool> predicate) =>\n            Supertype.CoTransform(Subtype.RepeatUntilIO(Supertype.Transform(ma), schedule, predicate));\n\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n        //\n        //  Retrying the effect when it fails\n        //\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will retry forever\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RetryIO<A>(K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.RetryIO(Supertype.Transform(ma)));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will retry until the schedule expires\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RetryIO<A>(\n            K<Supertype, A> ma,\n            Schedule schedule) =>\n            Supertype.CoTransform(Subtype.RetryIO(Supertype.Transform(ma), schedule));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n        /// at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RetryWhileIO<A>(\n            K<Supertype, A> ma,\n            Func<Error, bool> predicate) =>\n            Supertype.CoTransform(Subtype.RetryWhileIO(Supertype.Transform(ma), predicate));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n        /// or, until the schedule expires; at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RetryWhileIO<A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            Func<Error, bool> predicate) =>\n            Supertype.CoTransform(Subtype.RetryWhileIO(Supertype.Transform(ma), schedule, predicate));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n        /// at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RetryUntilIO<A>(\n            K<Supertype, A> ma,\n            Func<Error, bool> predicate) =>\n            Supertype.CoTransform(Subtype.RetryUntilIO(Supertype.Transform(ma), predicate));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n        /// or, until the schedule expires; at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        static K<Supertype, A> MonadUnliftIO<Supertype>.RetryUntilIO<A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            Func<Error, bool> predicate) =>\n            Supertype.CoTransform(Subtype.RetryUntilIO(Supertype.Transform(ma), schedule, predicate));\n\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n        // \n        //  Folding\n        //\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldIO<S, A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder) =>\n            Supertype.CoTransform(Subtype.FoldIO(Supertype.Transform(ma), schedule, initialState, folder));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldIO<S, A>(\n            K<Supertype, A> ma,\n            S initialState,\n            Func<S, A, S> folder) =>\n            Supertype.CoTransform(Subtype.FoldIO(Supertype.Transform(ma), initialState, folder));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldWhileIO<S, A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<S, bool> stateIs) =>\n            Supertype.CoTransform(Subtype.FoldWhileIO(Supertype.Transform(ma), schedule, initialState, folder, stateIs));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldWhileIO<S, A>(\n            K<Supertype, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<S, bool> stateIs) =>\n            Supertype.CoTransform(Subtype.FoldWhileIO(Supertype.Transform(ma), initialState, folder, stateIs));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldWhileIO<S, A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<A, bool> valueIs) =>\n            Supertype.CoTransform(Subtype.FoldWhileIO(Supertype.Transform(ma), schedule, initialState, folder, valueIs));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldWhileIO<S, A>(\n            K<Supertype, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<A, bool> valueIs) =>\n            Supertype.CoTransform(Subtype.FoldWhileIO(Supertype.Transform(ma), initialState, folder, valueIs));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldWhileIO<S, A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<(S State, A Value), bool> predicate) =>\n            Supertype.CoTransform(Subtype.FoldWhileIO(Supertype.Transform(ma), schedule, initialState, folder, predicate));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldWhileIO<S, A>(\n            K<Supertype, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<(S State, A Value), bool> predicate) =>\n            Supertype.CoTransform(Subtype.FoldWhileIO(Supertype.Transform(ma), initialState, folder, predicate));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldUntilIO<S, A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<S, bool> stateIs) =>\n            Supertype.CoTransform(Subtype.FoldUntilIO(Supertype.Transform(ma), schedule, initialState, folder, stateIs));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldUntilIO<S, A>(\n            K<Supertype, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<S, bool> stateIs) =>\n            Supertype.CoTransform(Subtype.FoldUntilIO(Supertype.Transform(ma), initialState, folder, stateIs));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldUntilIO<S, A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<A, bool> valueIs) =>\n            Supertype.CoTransform(Subtype.FoldUntilIO(Supertype.Transform(ma), schedule, initialState, folder, valueIs));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldUntilIO<S, A>(\n            K<Supertype, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<A, bool> valueIs) =>\n            Supertype.CoTransform(Subtype.FoldUntilIO(Supertype.Transform(ma), initialState, folder, valueIs));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldUntilIO<S, A>(\n            K<Supertype, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<(S State, A Value), bool> predicate) =>\n            Supertype.CoTransform(Subtype.FoldUntilIO(Supertype.Transform(ma), initialState, folder, predicate));\n\n        static K<Supertype, S> MonadUnliftIO<Supertype>.FoldUntilIO<S, A>(\n            K<Supertype, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<(S State, A Value), bool> predicate) =>\n            Supertype.CoTransform(Subtype.FoldUntilIO(Supertype.Transform(ma), schedule, initialState, folder, predicate));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/MonoidK.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// A monoid for higher-kinds\n    /// </summary>\n    /// <typeparam name=\"M\">Higher kind</typeparam>\n    public interface MonoidK<Supertype, Subtype> :\n        MonoidK<Supertype>,\n        SemigroupK<Supertype, Subtype>\n        where Supertype : MonoidK<Supertype, Subtype>\n        where Subtype : MonoidK<Subtype>\n    {\n        /// <summary>\n        /// Identity\n        /// </summary>\n        static K<Supertype, A> MonoidK<Supertype>.Empty<A>() =>\n            Supertype.CoTransform(Subtype.Empty<A>());\n    }\n}\n\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Readable.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derived `Readable` implementation\n    /// </summary>\n    /// <typeparam name=\"Supertype\">Super-type wrapper around the subtype</typeparam>\n    /// <typeparam name=\"Env\">Reader environment</typeparam>\n    /// <typeparam name=\"Subtype\">The subtype that the supertype type 'wraps'</typeparam>\n    public interface Readable<Supertype, Env, Subtype> : \n        Readable<Supertype, Env>,\n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Supertype : Readable<Supertype, Env, Subtype>, Readable<Supertype, Env>\n        where Subtype : Readable<Subtype, Env>\n    {\n        static K<Supertype, Env> Readable<Supertype, Env>.Ask => \n            Supertype.CoTransform(Subtype.Ask);\n\n        static K<Supertype, A> Readable<Supertype, Env>.Asks<A>(Func<Env, A> f) => \n            Supertype.CoTransform(Subtype.Asks(f));\n\n        static K<Supertype, A> Readable<Supertype, Env>.Local<A>(Func<Env, Env> f, K<Supertype, A> ma) => \n            Supertype.CoTransform(Supertype.Transform(ma).Local(f));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/SemigroupK.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Derived equivalent of semigroups for working with higher-kinded types\n    /// </summary>\n    public interface SemigroupK<Supertype, Subtype> :\n        SemigroupK<Supertype>,\n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Supertype : SemigroupK<Supertype, Subtype>\n        where Subtype : SemigroupK<Subtype>\n    {\n        /// <summary>\n        /// An associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">The first operand to the operation</param>\n        /// <param name=\"rhs\">The second operand to the operation</param>\n        /// <returns>The result of the operation</returns>\n        static K<Supertype, A> SemigroupK<Supertype>.Combine<A>(K<Supertype, A> lhs, K<Supertype, A> rhs) => \n            Supertype.CoTransform(Supertype.Transform(lhs).Combine(Supertype.Transform(rhs)));\n    }\n}\n\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Stateful.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    public interface Stateful<Supertype, Subtype, S> :\n        Stateful<Supertype, S>,\n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Supertype : Stateful<Supertype, Subtype, S>, Stateful<Supertype, S>\n        where Subtype : Stateful<Subtype, S>\n    {\n        static K<Supertype, Unit> Stateful<Supertype, S>.Put(S value) =>\n            Supertype.CoTransform(Subtype.Put(value));\n\n        static K<Supertype, Unit> Stateful<Supertype, S>.Modify(Func<S, S> modify) =>\n            Supertype.CoTransform(Subtype.Modify(modify));\n\n        static K<Supertype, A> Stateful<Supertype, S>.Gets<A>(Func<S, A> f) =>\n            Supertype.CoTransform(Subtype.Gets(f));\n\n        static K<Supertype, S> Stateful<Supertype, S>.Get => \n            Supertype.CoTransform(Subtype.Get);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Traversable.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    /// <summary>\n    /// Functors representing data structures that can be transformed to structures of the same\n    /// shape by performing an `Applicative` (or, therefore, `Monad`) action on each element from\n    /// left to right.\n    ///\n    /// A more detailed description of what same shape means, the various methods, how traversals\n    /// are constructed, and example advanced use-cases can be found in the Overview section of Data.Traversable.\n    /// </summary>\n    public interface Traversable<Supertype, Subtype> : \n        Functor<Supertype, Subtype>, \n        Foldable<Supertype, Subtype>,\n        Traversable<Supertype>\n        where Supertype : \n            Traversable<Supertype, Subtype>, \n            Traversable<Supertype>\n        where Subtype :\n            Traversable<Subtype>\n    {\n        static K<F, K<Supertype, B>> Traversable<Supertype>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Supertype, A> ta) => \n            Subtype.Traverse(f, Supertype.Transform(ta)).Map(Supertype.CoTransform);\n\n        static K<M, K<Supertype, B>> Traversable<Supertype>.TraverseM<M, A, B>(Func<A, K<M, B>> f, K<Supertype, A> ta) => \n            Subtype.TraverseM(f, Supertype.Transform(ta)).Map(Supertype.CoTransform);\n\n        static K<F, K<Supertype, A>> Traversable<Supertype>.Sequence<F, A>(K<Supertype, K<F, A>> ta) => \n            Subtype.Sequence(Supertype.Transform(ta)).Map(Supertype.CoTransform);\n\n        static K<F, K<Supertype, A>> Traversable<Supertype>.SequenceM<F, A>(K<Supertype, K<F, A>> ta) => \n            Subtype.SequenceM(Supertype.Transform(ta)).Map(Supertype.CoTransform);\n\n        static K<F, K<Supertype, B>> Traversable<Supertype>.TraverseDefault<F, A, B>(Func<A, K<F, B>> f, K<Supertype, A> ta) => \n            Subtype.TraverseDefault(f, Supertype.Transform(ta)).Map(Supertype.CoTransform);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Deriving/Writable.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Deriving\n{\n    public interface Writable<Supertype, Subtype, W> :\n        Writable<Supertype, W>,\n        Traits.Natural<Supertype, Subtype>,\n        Traits.CoNatural<Supertype, Subtype>\n        where Supertype : Writable<Supertype, Subtype, W>, Writable<Supertype, W>\n        where Subtype : Writable<Subtype, W>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Tell is an action that produces the writer output\n        /// </summary>\n        /// <param name=\"item\">Item to tell</param>\n        /// <typeparam name=\"W\">Writer type</typeparam>\n        /// <returns>Structure with the told item</returns>\n        static K<Supertype, Unit> Writable<Supertype, W>.Tell(W item) =>\n            Supertype.CoTransform(Subtype.Tell(item));\n\n        /// <summary>\n        /// Writes an item and returns a value at the same time\n        /// </summary>\n        static K<Supertype, (A Value, W Output)> Writable<Supertype, W>.Listen<A>(K<Supertype, A> ma) =>\n            Supertype.CoTransform(Subtype.Listen(Supertype.Transform(ma)));\n        \n        /// <summary>\n        /// `Pass` is an action that executes the `action`, which returns a value and a\n        /// function; it then returns the value with the output having been applied to\n        /// the function.\n        /// </summary>\n        /// <remarks>\n        /// For usage, see `Writer.censor` for how it's used to filter the output.\n        /// </remarks>\n        static K<Supertype, A> Writable<Supertype, W>.Pass<A>(K<Supertype, (A Value, Func<W, W> Function)> action) =>\n            Supertype.CoTransform(Subtype.Pass(Supertype.Transform(action)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Eff.Module.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing System.Threading.Tasks;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class Eff\n{\n    /// <summary>\n    /// Construct a successful effect with a pure value\n    /// </summary>\n    /// <param name=\"value\">Pure value to construct the monad with</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Synchronous IO monad that captures the pure value</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Success<A>(A value) =>\n        Eff<A>.Pure(value);\n\n    /// <summary>\n    /// Construct a failed effect\n    /// </summary>\n    /// <param name=\"error\">Error that represents the failure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Synchronous IO monad that captures the failure</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Fail<A>(Error error) =>\n        Eff<A>.Fail(error);\n\n    /// <summary>\n    /// Unit effect\n    /// </summary>\n    public static Eff<Unit> unit() =>\n        unitEff;\n\n    /// <summary>\n    /// Create a new cancellation context and run the provided Aff in that context\n    /// </summary>\n    /// <param name=\"ma\">Operation to run in the next context</param>\n    /// <typeparam name=\"RT\">Runtime environment</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>An asynchronous effect that captures the operation running in context</returns>\n    public static Eff<A> localCancel<A>(Eff<A> ma) =>\n        ma.LocalIO().As();\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Lifting\n    //\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<Either<Error, A>> f) =>\n        Eff<A>.Lift(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<Fin<A>> f) =>\n        Eff<A>.Lift(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<EnvIO, Fin<A>> f) =>\n        +envIO.Bind(e => Eff<A>.Lift(() => f(e)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<A> f) =>\n        Eff<A>.Lift(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<EnvIO, A> f) =>\n        +envIO.Bind(e => Eff<A>.Lift(() => f(e)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<Task<A>> f) =>\n        Eff<A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<EnvIO, Task<A>> f) =>\n        +envIO.Bind(e => Eff<A>.LiftIO(() => f(e)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<Task<Fin<A>>> f) =>\n        Eff<A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(Func<EnvIO, Task<Fin<A>>> f) =>\n        +envIO.Bind(e => Eff<A>.LiftIO(() => f(e)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> lift<A>(IO<A> ma) =>\n        Eff<A>.LiftIO(ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Eff.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Async.Linq;\nusing LanguageExt.Common;\nusing LanguageExt.Effects;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Eff : \n    MonadUnliftIO<Eff>,\n    Final<Eff>,\n    Fallible<Eff>,\n    Readable<Eff, MinRT>,\n    MonoidK<Eff>,\n    Alternative<Eff>,\n    Natural<Eff, Eff<MinRT>>,\n    CoNatural<Eff, Eff<MinRT>>\n{\n    static K<Eff, B> Monad<Eff>.Bind<A, B>(K<Eff, A> ma, Func<A, K<Eff, B>> f) =>\n        new Eff<B>(ma.As().effect.Bind(f));\n\n    static K<Eff, B> Monad<Eff>.Recur<A, B>(A value, Func<A, K<Eff, Next<A, B>>> f) =>\n        lift<B>(async env =>\n                {\n                    while (true)\n                    {\n                        var mnext = await f(value).As().RunAsync(env);\n                        if (mnext.IsFail) return Fin.Fail<B>(mnext.FailValue);\n                        var next = (Next<A, B>)mnext;\n                        if (next.IsDone) return Fin.Succ(next.Done);\n                        value = next.Loop;\n                    }\n                });\n\n    static K<Eff, B> Functor<Eff>.Map<A, B>(Func<A, B> f, K<Eff, A> ma) => \n        new Eff<B>(ma.As().effect.Map(f));\n\n    static K<Eff, A> Applicative<Eff>.Pure<A>(A value) => \n        Eff<A>.Pure(value);\n\n    static K<Eff, B> Applicative<Eff>.Apply<A, B>(K<Eff, Func<A, B>> mf, K<Eff, A> ma) => \n        new Eff<B>(mf.As().effect.Apply(ma.As().effect));\n\n    static K<Eff, B> Applicative<Eff>.Apply<A, B>(K<Eff, Func<A, B>> mf, Memo<Eff, A> ma) =>\n        new Eff<B>(mf.As().effect.Apply(Memo.transform<Eff, Eff<MinRT>, A>(ma)).As());\n\n    static K<Eff, A> Applicative<Eff>.Actions<A>(IterableNE<K<Eff, A>> fas) => \n        new Eff<A>(fas.Map(fa => fa.As().effect.Kind()).Actions().As()); \n\n    static K<Eff, A> MonoidK<Eff>.Empty<A>() => \n        Eff<A>.Fail(Errors.None);\n\n    static K<Eff, A> Alternative<Eff>.Empty<A>() => \n        Eff<A>.Fail(Errors.None);\n\n    static K<Eff, A> Choice<Eff>.Choose<A>(K<Eff, A> ma, K<Eff, A> mb) => \n        new Eff<A>(ma.As().effect.Choose(mb.As().effect).As());\n\n    static K<Eff, A> Choice<Eff>.Choose<A>(K<Eff, A> ma, Memo<Eff, A> mb) => \n        new Eff<A>(ma.As().effect.Choose(Memo.transform<Eff, Eff<MinRT>, A>(mb)).As());\n\n    static K<Eff, A> Readable<Eff, MinRT>.Asks<A>(Func<MinRT, A> f) => \n        new Eff<A>(Readable.asks<Eff<MinRT>, MinRT, A>(f).As());\n\n    static K<Eff, A> Readable<Eff, MinRT>.Local<A>(Func<MinRT, MinRT> f, K<Eff, A> ma) => \n        new Eff<A>(Readable.local(f, ma.As().effect).As());\n\n    static K<Eff, A> MonadIO<Eff>.LiftIO<A>(IO<A> ma) =>\n        Eff<A>.LiftIO(ma);\n\n    static K<Eff, IO<A>> MonadUnliftIO<Eff>.ToIO<A>(K<Eff, A> ma) =>\n        new Eff<IO<A>>(ma.As().effect.ToIO().As());\n\n    static K<Eff, B> MonadUnliftIO<Eff>.MapIO<A, B>(K<Eff, A> ma, Func<IO<A>, IO<B>> f) =>\n        new Eff<B>(ma.As().effect.MapIO(f).As());\n    \n    static K<Eff, A> Fallible<Error, Eff>.Fail<A>(Error error) =>\n        Eff<A>.Fail(error);\n\n    static K<Eff, A> Fallible<Error, Eff>.Catch<A>(\n        K<Eff, A> fa, Func<Error, bool> Predicate,\n        Func<Error, K<Eff, A>> Fail) =>\n        new Eff<A>(fa.As().effect.Catch(Predicate, e => Fail(e).As().effect).As());\n\n    static K<Eff, A> SemigroupK<Eff>.Combine<A>(K<Eff, A> lhs, K<Eff, A> rhs) => \n        lhs.Choose(rhs);\n\n    static K<Eff, A> Final<Eff>.Finally<X, A>(K<Eff, A> fa, K<Eff, X> @finally) =>\n        new Eff<A>(fa.As().effect.Finally(@finally.As().effect).As());\n\n    static K<Eff<MinRT>, A> Natural<Eff, Eff<MinRT>>.Transform<A>(K<Eff, A> fa) => \n        fa.As().effect;\n\n    static K<Eff, A> CoNatural<Eff, Eff<MinRT>>.CoTransform<A>(K<Eff<MinRT>, A> fa) => \n        new Eff<A>(fa.As());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Eff.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing LanguageExt.Common;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\nusing LanguageExt.Effects;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// This monad is used to encapsulate side effects and exception capture \n/// </summary>\n/// <typeparam name=\"RT\">Runtime type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record Eff<A>(Eff<MinRT, A> effect) :\n    Fallible<Eff<A>>,\n    K<Eff, A>,\n    Alternative<Eff<A>>,\n    MonoidK<Eff<A>>,\n    Final<Eff<A>>,\n    Deriving.Readable<Eff<A>, A, ReaderT<A, IO>>,\n    Deriving.MonadUnliftIO<Eff<A>, ReaderT<A, IO>>,\n    Natural<Eff<MinRT>, Eff>,\n    CoNatural<Eff<MinRT>, Eff>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Lifting\n    //\n\n    /// <summary>\n    /// Lift a value into the `Eff` monad \n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Pure(A value) =>\n        new(Eff<MinRT, A>.Pure(value));\n\n    /// <summary>\n    /// Lift a failure into the `Eff` monad \n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Fail(Error error) =>\n        new(Eff<MinRT, A>.Fail(error));\n\n    /// <summary>\n    /// Convert to an `Eff` monad with a runtime\n    /// </summary>\n    public Eff<RT, A> WithRuntime<RT>() =>\n        MonadIO.liftIO<Eff<RT>, A>(effect.RunIO(new MinRT())).As();\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Lift(Func<MinRT, Either<Error, A>> f) =>\n        new(Eff<MinRT, A>.Lift(f));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Lift(Func<MinRT, Fin<A>> f) =>\n        new(Eff<MinRT, A>.Lift(f));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Lift(Func<MinRT, A> f) =>\n        new(Eff<MinRT, A>.Lift(f));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> LiftIO(Func<MinRT, Task<A>> f) =>\n        new(Eff<MinRT, A>.LiftIO(f));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> LiftIO(Func<MinRT, Task<Fin<A>>> f) =>\n        new(Eff<MinRT, A>.LiftIO(rt => f(rt).Map(r => r.ThrowIfFail())));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> LiftIO(Func<MinRT, IO<A>> f) =>\n        new(Eff<MinRT, A>.LiftIO(f));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> LiftIO(IO<A> ma) =>\n        new(Eff<MinRT, A>.LiftIO(ma));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Lift(Func<Either<Error, A>> f) =>\n        new(Eff<MinRT, A>.Lift(_ => f()));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Lift(Func<Fin<A>> f) =>\n        new(Eff<MinRT, A>.Lift(_ => f()));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Lift(Func<A> f) =>\n        new(Eff<MinRT, A>.Lift(_ => f()));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> LiftIO(Func<Task<A>> f) =>\n        new(Eff<MinRT, A>.LiftIO(_ => f()));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> LiftIO(Func<Task<Fin<A>>> f) =>\n        new(Eff<MinRT, A>.LiftIO(_ => f().Map(r => r.ThrowIfFail())));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Map and map-left\n    //\n\n    /// <summary>\n    /// Maps the `Eff` monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> Map<B>(Func<A, B> f) =>\n        new(effect.Map(f));\n\n    /// <summary>\n    /// Maps the `Eff` monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> Select<B>(Func<A, B> f) =>\n        new(effect.Map(f));\n\n    /// <summary>\n    /// Maps the `Eff` monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<A> MapFail(Func<Error, Error> f) =>\n        this.Catch(f).As();\n\n    /// <summary>\n    /// Maps the inner IO monad\n    /// </summary>\n    /// <param name=\"f\">Function to map with</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> MapIO<B>(Func<IO<A>, IO<B>> f) =>\n        new(effect.MapIO(f));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Bi-map\n    //\n\n    /// <summary>\n    /// Mapping of either the Success state or the Failure state depending on what\n    /// state this `Eff` monad is in.  \n    /// </summary>\n    /// <param name=\"Succ\">Mapping to use if the `Eff` monad if in a success state</param>\n    /// <param name=\"Fail\">Mapping to use if the `Eff` monad if in a failure state</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> BiMap<B>(Func<A, B> Succ, Func<Error, Error> Fail) =>\n        Map(Succ).Catch(Fail).As();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Matching\n    //\n\n    /// <summary>\n    /// Pattern match the success or failure values and collapse them down to a success value\n    /// </summary>\n    /// <param name=\"Succ\">Success value mapping</param>\n    /// <param name=\"Fail\">Failure value mapping</param>\n    /// <returns>IO in a success state</returns>\n    [Pure]\n    public Eff<B> Match<B>(Func<A, B> Succ, Func<Error, B> Fail) =>\n        Map(Succ).Catch(Fail).As();\n\n    /// <summary>\n    /// Map the failure to a success value\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO in a success state</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<A> IfFail(Func<Error, A> Fail) =>\n        this.Catch(Fail).As();\n\n    /// <summary>\n    /// Map the failure to a new IO effect\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO that encapsulates that IfFail</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<A> IfFailEff(Func<Error, Eff<A>> Fail) =>\n        this.Catch(Fail).As();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Filter\n    //\n\n    /// <summary>\n    /// Only allow values through the effect if the predicate returns `true` for the bound value\n    /// </summary>\n    /// <param name=\"predicate\">Predicate to apply to the bound value></param>\n    /// <returns>Filtered IO</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<A> Filter(Func<A, bool> predicate) =>\n        new(effect.Filter(predicate));\n\n    /// <summary>\n    /// Only allow values through the effect if the predicate returns `true` for the bound value\n    /// </summary>\n    /// <param name=\"predicate\">Predicate to apply to the bound value></param>\n    /// <returns>Filtered IO</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<A> Where(Func<A, bool> predicate) =>\n        new(effect.Where(predicate));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic binding\n    //\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> Bind<B>(Func<A, Eff<B>> f) =>\n        new(effect.Bind(x => f(x).effect));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> Bind<B>(Func<A, IO<B>> f) =>\n        new(effect.Bind(f));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> Bind<B>(Func<A, Ask<MinRT, B>> f) =>\n        new(effect.Bind(f));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<RT, B>(Func<A, Eff<RT, B>> f) =>\n        WithRuntime<RT>().Bind(f);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<RT, B>(Func<A, K<Eff<RT>, B>> f) =>\n        Bind(a => f(a).As());\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> Bind<B>(Func<A, K<Eff, B>> f) =>\n        Bind(a => f(a).As());\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(x => f(x).Value);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<A> Bind(Func<A, Fail<Error>> f) =>\n        Bind(x => Fail(f(x).Value));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic binding and projection\n    //\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<C> SelectMany<B, C>(Func<A, Eff<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<RT, B, C>(Func<A, Eff<RT, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<RT, B, C>(Func<A, K<Eff<RT>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<C> SelectMany<B, C>(Func<A, K<Eff, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        new(effect.SelectMany(bind, project));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        new(effect.SelectMany(bind, project));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<C> SelectMany<B, C>(Func<A, Ask<MinRT, B>> bind, Func<A, B, C> project) =>\n        new(effect.SelectMany(bind, project));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<C> SelectMany<B, C>(Func<A, Fail<Error>> bind, Func<A, B, C> project) =>\n        SelectMany(x => Eff<B>.Fail(bind(x).Value), project);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<C> SelectMany<C>(Func<A, Guard<Error, Unit>> bind, Func<A, Unit, C> project) =>\n        new(effect.SelectMany(bind, project));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<C> SelectMany<C>(Func<A, Guard<Fail<Error>, Unit>> bind, Func<A, Unit, C> project) =>\n        new(effect.SelectMany(bind, project));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Conversion operators\n    //\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(Pure<A> ma) =>\n        ma.ToEff();\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(Fail<Error> ma) =>\n        ma.ToEff<A>();\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(in Lift<A> ma) =>\n        Lift(ma.Function);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(in Lift<Fin<A>> ma) =>\n        Lift(ma.Function);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(in Lift<MinRT, A> ma) =>\n        Lift(ma.Function);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(in Lift<MinRT, Fin<A>> ma) =>\n        Lift(ma.Function);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(in Either<Error, A> ma) =>\n        ma.Match(Left: Fail, Right: Pure);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(in Fin<A> ma) =>\n        ma.Match(Succ: Pure, Fail: Fail);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(in IO<A> ma) =>\n        LiftIO(ma);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<A>(in Error fail) => \n        Fail(fail);\n\n    public override string ToString() => \n        \"Eff\";\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Trait implementations for `Eff<RT, A>`\n    //\n    // It's important to remember that the code below is the trait implementations for `Eff<RT, A>`, and not\n    // related to `Eff<A>` in any way at all.  `A` in this instance is the `RT` in `Eff<RT, A>`.  \n    //\n    // It is this way to make it easier to work with Eff traits, even if this is a bit ugly.\n    //\n\n    static K<Eff<A>, T> Fallible<Error, Eff<A>>.Fail<T>(Error error) => \n        FailEff<A, T>(error);\n\n    static K<Eff<A>, T> Fallible<Error, Eff<A>>.Catch<T>(\n        K<Eff<A>, T> ma,\n        Func<Error, bool> pred,\n        Func<Error, K<Eff<A>, T>> f) =>\n        new Eff<A, T>(\n            new ReaderT<A, IO, T>(\n                env => ma.As().RunIO(env).Catch(pred, e => f(e).As().effect.Run(env))));\n\n    static K<Eff<A>, T> Final<Eff<A>>.Finally<X, T>(K<Eff<A>, T> fa, K<Eff<A>, X> @finally) => \n        new Eff<A, T>(\n            new ReaderT<A, IO, T>(\n                env => fa.As().RunIO(env).Finally(@finally.As().effect.Run(env))));\n    \n    static K<Eff<A>, T> Applicative<Eff<A>>.Actions<T>(IterableNE<K<Eff<A>, T>> fas) =>\n        new Eff<A, T>(\n            new ReaderT<A, IO, T>(\n                rt => fas.Select(fa => fa.RunIO(rt).Kind()).Actions())); \n    \n    static K<Eff<A>, T> MonoidK<Eff<A>>.Empty<T>() =>\n        Eff<A, T>.Fail(Errors.None);\n\n    static K<ReaderT<A, IO>, A1> Natural<Eff<A>, ReaderT<A, IO>>.Transform<A1>(K<Eff<A>, A1> fa) =>\n        fa.As().effect;\n\n    static K<Eff<A>, T> CoNatural<Eff<A>, ReaderT<A, IO>>.CoTransform<T>(K<ReaderT<A, IO>, T> fa) => \n        new Eff<A, T>(fa.As());\n    \n    static K<Eff<A>, A1> SemigroupK<Eff<A>>.Combine<A1>(K<Eff<A>, A1> lhs, K<Eff<A>, A1> rhs) => \n        lhs.Catch(e1 => rhs.Catch(e2 => e1 + e2));\n\n    static K<Eff<A>, A1> Choice<Eff<A>>.Choose<A1>(K<Eff<A>, A1> lhs, K<Eff<A>, A1> rhs) => \n        lhs.Catch(rhs);\n\n    static K<Eff<A>, A1> Choice<Eff<A>>.Choose<A1>(K<Eff<A>, A1> lhs, Memo<Eff<A>, A1> rhs) => \n        lhs.Catch(_ => rhs.Value);\n\n    static K<Eff<A>, T> Alternative<Eff<A>>.Empty<T>() => \n        Eff<A, T>.Fail(Errors.None);\n\n    static K<Eff, T> Natural<Eff<MinRT>, Eff>.Transform<T>(K<Eff<MinRT>, T> fa) => \n        new Eff<T>(fa.As());\n\n    static K<Eff<MinRT>, T> CoNatural<Eff<MinRT>, Eff>.CoTransform<T>(K<Eff, T> fa) =>\n        fa.As().effect;\n\n    static K<Eff<A>, B> Monad<Eff<A>>.Recur<X, B>(X value, Func<X, K<Eff<A>, Next<X, B>>> f) =>\n        Eff.lift<A, B>(async (env, rt) =>\n                      {\n                          while (true)\n                          {\n                              var mnext = await f(value).As().RunAsync(rt, env);\n                              if (mnext.IsFail) return Fin.Fail<B>(mnext.FailValue);\n                              var next = (Next<X, B>)mnext;\n                              if (next.IsDone) return Fin.Succ(next.Done);\n                              value = next.Loop;\n                          }\n                      });\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Transformer helpers\n    //\n\n    internal static ReaderT<A, IO, X> getsM<X>(Func<A, IO<X>> f) =>\n        from e in ReaderT.ask<IO, A>()\n        from r in ReaderT.liftIO<A, IO, X>(IO.lift(() => f(e)).Flatten())\n        select r;\n\n    internal static ReaderT<A, IO, X> getsIO<X>(Func<A, Task<X>> f) =>\n        from e in ReaderT.ask<IO, A>()\n        from r in ReaderT.liftIO<A, IO, X>(IO.liftAsync(() => f(e)))\n        select r;\n\n    internal static ReaderT<A, IO, X> gets<X>(Func<A, X> f) =>\n        from e in ReaderT.ask<IO, A>()\n        from r in ReaderT.liftIO<A, IO, X>(IO.lift(() => f(e)))\n        select r;\n\n    internal static ReaderT<A, IO, X> gets<X>(Func<A, Fin<X>> f) =>\n        from e in ReaderT.ask<IO, A>()\n        from r in ReaderT.liftIO<A, IO, X>(IO.lift(() => f(e)))\n        select r;\n\n    internal static ReaderT<A, IO, X> gets<X>(Func<A, Either<Error, X>> f) =>\n        from e in ReaderT.ask<IO, A>()\n        from r in ReaderT.liftIO<A, IO, X>(IO.lift(() => f(e)))\n        select r;\n\n    internal static ReaderT<A, IO, X> fail<X>(Error value) =>\n        ReaderT.liftIO<A, IO, X>(IO.fail<X>(value));\n\n    internal static ReaderT<A, IO, X> pure<X>(X value) =>\n        ReaderT<A, IO, X>.Pure(value);\n\n    internal static readonly ReaderT<A, IO, (A Runtime, EnvIO EnvIO)> getState = \n        from rt in ReaderT.ask<IO, A>()\n        from io in IO.env\n        select (rt, io);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Obsolete\n    //\n\n    /// <summary>\n    /// Lift a value into the `Eff` monad\n    /// </summary>\n    [Obsolete(\"Use either: `Prelude.Pure` or `Eff<A>.Pure`\")]\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Success(A value) =>\n        Pure(value);\n\n    /// <summary>\n    /// Lift a synchronous effect into the `Eff` monad\n    /// </summary>\n    [Obsolete(\"Use either: `Prelude.lift` or `Eff<A>.Lift`\")]\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> Effect(Func<A> f) =>\n        Lift(_ => f());\n\n    /// <summary>\n    /// Lift a synchronous effect into the `Eff` monad\n    /// </summary>\n    [Obsolete(\"Use either: `Prelude.lift` or `Eff<A>.Lift`\")]\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> EffectMaybe(Func<Fin<A>> f) =>\n        Lift(_ => f());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Extensions/Eff.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Eff<B> Map<A, B>(this Func<A, B> f, K<Eff, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Eff<B> Map<A, B>(this Func<A, B> f, Eff<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Eff<B> Action<A, B>(this Eff<A> ma, K<Eff, B> mb) =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Eff<B> Action<A, B>(this K<Eff, A> ma, K<Eff, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Eff<B> Apply<A, B>(this Eff<Func<A, B>> mf, K<Eff, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Eff<B> Apply<A, B>(this K<Eff, Func<A, B>> mf, K<Eff, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Extensions/Eff.Extensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Effects;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    /// <summary>\n    /// Cast type to its Kind\n    /// </summary>\n    public static Eff<A> As<A>(this K<Eff, A> ma) =>\n        (Eff<A>)ma;\n\n    /// <summary>\n    /// Cast type to its Kind\n    /// </summary>\n    public static Eff<A> As<A>(this Eff<MinRT, A> ma) =>\n        new(ma);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Invoking\n    //\n\n    /// <summary>\n    /// Invoke the effect\n    /// </summary>\n    /// <remarks>\n    /// Returns the result value only \n    /// </remarks>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Fin<A> Run<A>(this K<Eff, A> ma) =>\n        ma.As().effect.Run(default);\n\n    /// <summary>\n    /// Invoke the effect\n    /// </summary>\n    /// <remarks>\n    /// Returns the result value only \n    /// </remarks>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Fin<A> Run<A>(this K<Eff, A> ma, EnvIO envIO) =>\n        ma.As().effect.Run(default, envIO);\n    \n    /// <summary>\n    /// Invoke the effect\n    /// </summary>\n    /// <remarks>\n    /// This is labelled 'unsafe' because it can throw an exception, whereas\n    /// `Run` will capture any errors and return a `Fin` type.\n    /// </remarks>\n    [Pure, MethodImpl(Opt.Default)]\n    public static A RunUnsafe<A>(this K<Eff, A> ma) =>\n        ma.As().effect.RunUnsafe(default);\n\n    /// <summary>\n    /// Invoke the effect\n    /// </summary>\n    /// <remarks>\n    /// This is labelled 'unsafe' because it can throw an exception, whereas\n    /// `Run` will capture any errors and return a `Fin` type.\n    /// </remarks>\n    [Pure, MethodImpl(Opt.Default)]\n    public static A RunUnsafe<A>(this K<Eff, A> ma, EnvIO envIO) =>\n        ma.As().effect.RunUnsafe(default, envIO);\n\n    /// <summary>\n    /// Invoke the effect to leave the inner IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static IO<A> RunIO<A>(this K<Eff, A> ma) =>\n        ma.As().effect.RunIO(default);\n\n    /// <summary>\n    /// Invoke the effect\n    /// </summary>\n    /// <remarks>\n    /// Returns the result value only \n    /// </remarks>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Task<Fin<A>> RunAsync<A>(this K<Eff, A> ma) =>\n        ma.As().effect.RunAsync(default);\n\n    /// <summary>\n    /// Invoke the effect\n    /// </summary>\n    /// <remarks>\n    /// Returns the result value only \n    /// </remarks>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Task<Fin<A>> RunAsync<A>(this K<Eff, A> ma, EnvIO envIO) =>\n        ma.As().effect.RunAsync(default, envIO);\n    \n    /// <summary>\n    /// Invoke the effect\n    /// </summary>\n    /// <remarks>\n    /// This is labelled 'unsafe' because it can throw an exception, whereas\n    /// `Run` will capture any errors and return a `Fin` type.\n    /// </remarks>\n    [Pure, MethodImpl(Opt.Default)]\n    public static ValueTask<A> RunUnsafeAsync<A>(this K<Eff, A> ma) =>\n        ma.As().effect.RunUnsafeAsync(default);\n\n    /// <summary>\n    /// Invoke the effect\n    /// </summary>\n    /// <remarks>\n    /// This is labelled 'unsafe' because it can throw an exception, whereas\n    /// `Run` will capture any errors and return a `Fin` type.\n    /// </remarks>\n    [Pure, MethodImpl(Opt.Default)]\n    public static ValueTask<A> RunUnsafeAsync<A>(this K<Eff, A> ma, EnvIO envIO) =>\n        ma.As().effect.RunUnsafeAsync(default, envIO);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic join\n    //\n\n    /// <summary>\n    /// Monadic join operator \n    /// </summary>\n    /// <remarks>\n    /// Collapses a nested IO monad so there is no nesting.\n    /// </remarks>\n    /// <param name=\"mma\">Nest IO monad to flatten</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Flattened IO monad</returns>\n    public static Eff<A> Flatten<A>(this K<Eff, K<Eff, A>> mma) =>\n        mma.As().Bind(ma => ma);\n\n    /// <summary>\n    /// Monadic join operator \n    /// </summary>\n    /// <remarks>\n    /// Collapses a nested IO monad so there is no nesting.\n    /// </remarks>\n    /// <param name=\"mma\">Nest IO monad to flatten</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Flattened IO monad</returns>\n    public static Eff<A> Flatten<A>(this K<Eff, Eff<A>> mma) =>\n        mma.As().Bind(ma => ma);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany extensions\n    //\n\n    /// <summary>\n    /// Monadic bind and project with paired IO monads\n    /// </summary>\n    public static Eff<D> SelectMany<A, B, C, D>(\n        this (K<Eff, A> First, K<Eff, B> Second) self,\n        Func<(A First, B Second), K<Eff, C>> bind,\n        Func<(A First, B Second), C, D> project) =>\n        self.Zip().Bind(ab => bind(ab).Map(c => project(ab, c))).As();\n\n    /// <summary>\n    /// Monadic bind and project with paired IO monads\n    /// </summary>\n    public static Eff<D> SelectMany<A, B, C, D>(\n        this K<Eff, A> self,\n        Func<A, (K<Eff, B> First, K<Eff, C> Second)> bind,\n        Func<A, (B First, C Second), D> project) =>\n        self.As().Bind(a => bind(a).Zip().Map(cd => project(a, cd)));\n\n    /// <summary>\n    /// Monadic bind and project with paired IO monads\n    /// </summary>\n    public static Eff<E> SelectMany<A, B, C, D, E>(\n        this (K<Eff, A> First, K<Eff, B> Second, K<Eff, C> Third) self,\n        Func<(A First, B Second, C Third), K<Eff, D>> bind,\n        Func<(A First, B Second, C Third), D, E> project) =>\n        self.Zip().Bind(ab => bind(ab).Map(c => project(ab, c))).As();\n\n    /// <summary>\n    /// Monadic bind and project with paired IO monads\n    /// </summary>\n    public static Eff<E> SelectMany<A, B, C, D, E>(\n        this K<Eff, A> self,\n        Func<A, (K<Eff, B> First, K<Eff, C> Second, K<Eff, D> Third)> bind,\n        Func<A, (B First, C Second, D Third), E> project) =>\n        self.As().Bind(a => bind(a).Zip().Map(cd => project(a, cd)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Extensions/Eff.Guard.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EffGuardExtensions\n{\n    /// <summary>\n    /// Natural transformation to `Eff`\n    /// </summary>\n    public static Eff<Unit> ToEff(this Guard<Error, Unit> guard) =>\n        guard.Flag\n            ? Pure(unit)\n            : Fail(guard.OnFalse());\n\n    /// <summary>\n    /// Monadic binding support for `Eff`\n    /// </summary>\n    public static Eff<B> Bind<B>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, Eff<B>> f) =>\n        guard.Flag\n            ? f(default).As()\n            : Fail(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `Eff`\n    /// </summary>\n    public static Eff<C> SelectMany<B, C>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, Eff<B>> bind, \n        Func<Unit, B, C> project) =>\n        guard.Flag\n            ? bind(default).As().Map(b => project(default, b))\n            : Fail(guard.OnFalse());    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Operators/Eff.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<A, B>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Eff<B> operator >>> (K<Eff, A> ma, K<Eff, B> mb) =>\n            ma.Action(mb).As();\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<B> operator * (K<Eff, Func<A, B>> mf, K<Eff, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<B> operator * (K<Eff, A> ma, K<Eff, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n\n    extension<A, B, C>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, C>> operator * (\n            K<Eff, Func<A, B, C>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, C>> operator * (\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<A, B, C, D>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, D>>> operator * (\n            K<Eff, Func<A, B, C, D>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, D>>> operator * (\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Eff, Func<A, B, C, D, E>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Eff, Func<A, B, C, D, E, F>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Eff, Func<A, B, C, D, E, F, G>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G, H>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Eff, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Eff, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Eff, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Eff, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Eff, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Eff, A> ma,\n            K<Eff, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Operators/Eff.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<A>(K<Eff, A> self)\n    {\n        public static Eff<A> operator |(K<Eff, A> lhs, K<Eff, A> rhs) =>\n            lhs.Choose(rhs).As();\n\n        public static Eff<A> operator |(K<Eff, A> lhs, Pure<A> rhs) =>\n            lhs.Choose(rhs.ToEff()).As();\n    }\n\n    extension<RT, A>(K<Eff, A> self)\n    {\n        public static Eff<RT, A> operator |(K<Eff, A> lhs, K<Eff<RT>, A> rhs) =>\n            lhs.As().WithRuntime<RT>().Choose(rhs).As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Operators/Eff.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<A>(K<Eff, A> self)\n    {\n        public static Eff<A> operator |(K<Eff, A> lhs, CatchM<Error, Eff, A> rhs) =>\n            lhs.Catch(rhs).As();\n\n        public static Eff<A> operator |(K<Eff, A> lhs, Fail<Error> rhs) =>\n            lhs.Catch(rhs).As();\n\n        public static Eff<A> operator |(K<Eff, A> lhs, Error rhs) =>\n            lhs.Catch(rhs).As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Operators/Eff.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static partial class EffExtensions\n{\n    extension<X, A>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static Eff<A> operator |(K<Eff, A> lhs, Finally<Eff, X> rhs) =>\n            lhs.Finally(rhs.Operation).As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Operators/Eff.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<A, B>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<B> operator *(Func<A, B> f, K<Eff, A> ma) =>\n            ma.Map(f).As();\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<B> operator *(K<Eff, A> ma, Func<A, B> f) =>\n            ma.Map(f).As();\n    }\n    \n    extension<A, B, C>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, C>> operator * (\n            K<Eff, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<A, B, C, D>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, D>>> operator * (\n            K<Eff, A> ma, \n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Eff, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Eff, A> ma, \n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Eff, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Eff, A> ma, \n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Eff, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Eff, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Eff, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Eff, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Operators/Eff.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<A, B>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Eff<B> operator >> (K<Eff, A> ma, Func<A, K<Eff, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Eff<B> operator >> (K<Eff, A> lhs, K<Eff, B> rhs) =>\n            lhs >> (_ => rhs);\n\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Eff<B> operator >> (K<Eff, A> ma, Func<A, K<IO, B>> f) =>\n            +ma.Bind(x => Eff.lift(+f(x)));\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Eff<B> operator >> (K<Eff, A> lhs, K<IO, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<A>(K<Eff, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Eff<A> operator >> (K<Eff, A> lhs, K<Eff, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n        \n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Eff<A> operator >> (K<Eff, A> lhs, K<IO, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Operators/Eff.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<A>(K<Eff, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Eff<A> operator +(K<Eff, A> ma) =>\n            (Eff<A>)ma;\n        \n        public static Eff<A> operator >> (K<Eff, A> ma, Lower lower) =>\n            (Eff<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Prelude/Eff.Prelude.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing System.Threading.Tasks;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.Effects;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Effect that always returns `unit`.\n    /// </summary>\n    public static readonly Eff<Unit> unitEff = Pure(unit);\n    \n    /// <summary>\n    /// Timeout operation if it takes too long\n    /// </summary>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static Eff<A> timeout<A>(TimeSpan timeout, Eff<A> ma) =>\n        ma.MapIO(io => io.Timeout(timeout));\n    \n    /// <summary>\n    /// Construct an successful effect with a pure value\n    /// </summary>\n    /// <param name=\"value\">Pure value to construct the monad with</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Synchronous IO monad that captures the pure value</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> SuccessEff<A>(A value) => \n        LanguageExt.Eff<A>.Pure(value);\n\n    /// <summary>\n    /// Construct a failed effect\n    /// </summary>\n    /// <param name=\"error\">Error that represents the failure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Synchronous IO monad that captures the failure</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> FailEff<A>(Error error) => \n        LanguageExt.Eff<A>.Fail(error);    \n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Runtime helpers\n    //\n\n    /// <summary>\n    /// Make the runtime into the bound value\n    /// </summary>\n    [Pure]\n    internal static Eff<MinRT> runtimeMinRT =>\n        LanguageExt.Eff<MinRT>.Lift(rt => rt);\n\n    /// <summary>\n    /// Create a new cancellation context and run the provided Aff in that context\n    /// </summary>\n    /// <param name=\"ma\">Operation to run in the next context</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>An asynchronous effect that captures the operation running in context</returns>\n    public static Eff<A> localCancel<A>(Eff<A> ma) =>\n        localCancel(ma.effect).As();\n\n    /// <summary>\n    /// Cancellation token\n    /// </summary>\n    /// <returns>CancellationToken</returns>\n    public static Eff<CancellationToken> cancelTokenEff =>\n        IO.token;\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic join\n    //\n\n    /// <summary>\n    /// Monadic join operator \n    /// </summary>\n    /// <remarks>\n    /// Collapses a nested IO monad so there is no nesting.\n    /// </remarks>\n    /// <param name=\"mma\">Nest IO monad to flatten</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Flattened IO monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> flatten<A>(Eff<Eff<A>> mma) =>\n        mma.Flatten(); \n            \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Lifting\n    //\n\n    /// <summary>\n    /// Lift a synchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<Unit> liftEff(Action action) =>\n        LanguageExt.Eff<Unit>.Lift(() => { action(); return unit; });\n\n    /// <summary>\n    /// Lift a synchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<A> f) =>\n        LanguageExt.Eff<A>.Lift(f);\n    \n    /// <summary>\n    /// Lift a synchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<Either<Error, A>> f) =>\n        LanguageExt.Eff<A>.Lift(f);\n\n    /// <summary>\n    /// Lift a synchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<Fin<A>> f) =>\n        LanguageExt.Eff<A>.Lift(f);\n\n    /// <summary>\n    /// Lift a synchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<MinRT, Either<Error, A>> f) =>\n        LanguageExt.Eff<A>.Lift(f);\n\n    /// <summary>\n    /// Lift a synchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<MinRT, A> f) =>\n        LanguageExt.Eff<A>.Lift(f);\n\n    /// <summary>\n    /// Lift a synchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<MinRT, Fin<A>> f) =>\n        LanguageExt.Eff<A>.Lift(f);\n\n    /// <summary>\n    /// Lift a asynchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<MinRT, Task<A>> f) =>\n        LanguageExt.Eff<A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift a asynchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<MinRT, Task<Fin<A>>> f) =>\n        LanguageExt.Eff<A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift a asynchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<Task<A>> f) =>\n        LanguageExt.Eff<A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift a asynchronous effect into the IO monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> liftEff<A>(Func<Task<Fin<A>>> f) =>\n        LanguageExt.Eff<A>.LiftIO(f);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Map and map-left\n    //\n\n    /// <summary>\n    /// Maps the IO monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped IO monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<B> map<A, B>(Eff<A> ma, Func<A, B> f) =>\n        ma.Map(f);\n\n    /// <summary>\n    /// Maps the IO monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped IO monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> mapFail<A>(Eff<A> ma, Func<Error, Error> f) =>\n        ma.MapFail(f);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Bi-map\n    //\n\n    /// <summary>\n    /// Mapping of either the Success state or the Failure state depending on what\n    /// state this IO monad is in.  \n    /// </summary>\n    /// <param name=\"Succ\">Mapping to use if the IO monad is in a success state</param>\n    /// <param name=\"Fail\">Mapping to use if the IO monad is in a failure state</param>\n    /// <returns>Mapped IO monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<B> bimap<A, B>(Eff<A> ma, Func<A, B> Succ, Func<Error, Error> Fail) =>\n        ma.BiMap(Succ, Fail);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Matching\n    //\n\n    /// <summary>\n    /// Pattern match the success or failure values and collapse them down to a success value\n    /// </summary>\n    /// <param name=\"Succ\">Success value mapping</param>\n    /// <param name=\"Fail\">Failure value mapping</param>\n    /// <returns>IO in a success state</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<B> match<A, B>(Eff<A> ma, Func<A, B> Succ, Func<Error, B> Fail) =>\n        ma.Match(Succ, Fail);\n\n    /// <summary>\n    /// Map the failure to a success value\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO in a success state</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> ifFail<A>(Eff<A> ma, Func<Error, A> Fail) =>\n        ma.IfFail(Fail);\n\n    /// <summary>\n    /// Map the failure to a new IO effect\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO that encapsulates that IfFail</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> ifFailEff<A>(Eff<A> ma, Func<Error, Eff<A>> Fail) =>\n        ma.IfFailEff(Fail);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Filter\n    //\n\n    /// <summary>\n    /// Only allow values through the effect if the predicate returns `true` for the bound value\n    /// </summary>\n    /// <param name=\"predicate\">Predicate to apply to the bound value></param>\n    /// <returns>Filtered IO</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<A> filter<A>(Eff<A> ma, Func<A, bool> predicate) =>\n        ma.Filter(predicate);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff no runtime/Prelude/Eff.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Eff<B> map<A, B>(Func<A, B> f, K<Eff, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Eff<B> action<A, B>(K<Eff, A> ma, K<Eff, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Eff<B> apply<A, B>(K<Eff, Func<A, B>> mf, K<Eff, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Eff.Module.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing System.Threading.Tasks;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class Eff\n{\n    /// <summary>\n    /// Construct a successful effect with a pure value\n    /// </summary>\n    /// <param name=\"value\">Pure value to construct the monad with</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Synchronous IO monad that captures the pure value</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Success<RT, A>(A value) =>\n        Eff<RT, A>.Pure(value);\n\n    /// <summary>\n    /// Construct a failed effect\n    /// </summary>\n    /// <param name=\"error\">Error that represents the failure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Synchronous IO monad that captures the failure</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Fail<RT, A>(Error error) =>\n        Eff<RT, A>.Fail(error);\n\n    /// <summary>\n    /// Unit effect\n    /// </summary>\n    public static Eff<RT, Unit> unit<RT>() =>\n        Success<RT, Unit>(default);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Runtime helpers\n    //\n\n    /// <summary>\n    /// Make the runtime into the bound value\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, RT> runtime<RT>() =>\n        liftEff<RT, RT>(identity);\n\n    /// <summary>\n    /// Get all the internal state of the `Eff`\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, (RT Runtime, EnvIO EnvIO)> getState<RT>() =>\n        new(Eff<RT>.getState);\n\n    /// <summary>\n    /// Create a new cancellation context and run the provided Aff in that context\n    /// </summary>\n    /// <param name=\"ma\">Operation to run in the next context</param>\n    /// <typeparam name=\"RT\">Runtime environment</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>An asynchronous effect that captures the operation running in context</returns>\n    public static Eff<RT, A> localCancel<RT, A>(Eff<RT, A> ma) =>\n        ma.LocalIO().As();\n\n    /// <summary>\n    /// Create a new local context for the environment by mapping the outer environment and then\n    /// using the result as a new context when running the IO monad provided\n    /// </summary>\n    /// <param name=\"f\">Function to map the outer environment into a new one to run `ma`</param>\n    /// <param name=\"ma\">IO monad to run in the new context</param>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<OuterRT, A> local<OuterRT, InnerRT, A>(Func<OuterRT, InnerRT> f, Eff<InnerRT, A> ma) =>\n         // Get the current state of the Eff  \n         from st in getState<OuterRT>()\n\n         // Run the local operation\n         from rs in IO.local(ma.effect.Run(f(st.Runtime))).As()\n         \n         // Ignore any changes to the state and just return the result of the local operation\n         select rs;\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Lifting\n    //\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<EnvIO, RT, Either<Error, A>> f) =>\n        +envIO.Bind(e => Eff<RT, A>.Lift(rt => f(e, rt)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<RT, Fin<A>> f) =>\n        Eff<RT, A>.Lift(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<EnvIO, RT, Fin<A>> f) =>\n        +envIO.Bind(e => Eff<RT, A>.Lift(rt => f(e, rt)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<RT, A> f) =>\n        Eff<RT, A>.Lift(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<EnvIO, RT, A> f) =>\n        +envIO.Bind(e => Eff<RT, A>.Lift(rt => f(e, rt)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<RT, Task<A>> f) =>\n        Eff<RT, A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<EnvIO, RT, Task<A>> f) =>\n        +envIO.Bind(e => Eff<RT, A>.LiftIO(rt => f(e, rt)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<RT, Task<Fin<A>>> f) =>\n        Eff<RT, A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(Func<EnvIO, RT, Task<Fin<A>>> f) =>\n        +envIO.Bind(e => Eff<RT, A>.LiftIO(rt => f(e, rt)));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> lift<RT, A>(IO<A> ma) =>\n        Eff<RT, A>.LiftIO(ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Eff.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// This monad is used to encapsulate side effects, exception capture, and dependency-injection via the `RT` runtime. \n/// </summary>\n/// <typeparam name=\"RT\">Runtime type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record Eff<RT, A>(ReaderT<RT, IO, A> effect) : \n    K<Eff<RT>, A>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Constructors\n    //\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(Opt.Default)]\n    internal Eff(Func<RT, Task<A>> effect)\n        : this(Eff<RT>.getsIO(effect))\n    { }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(Opt.Default)]\n    Eff(A value) \n        : this(Eff<RT>.pure(value))\n    { }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(Opt.Default)]\n    Eff(Error value) \n        : this(Eff<RT>.fail<A>(value))\n    { }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(Opt.Default)]\n    Eff(Func<RT, A> effect) \n        : this(Eff<RT>.gets(effect))\n    { }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(Opt.Default)]\n    Eff(Func<RT, Fin<A>> effect)\n        : this(Eff<RT>.gets(effect))\n    {\n    }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(Opt.Default)]\n    Eff(Func<RT, Either<Error, A>> effect) \n        : this(Eff<RT>.gets(effect))\n    { }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(Opt.Default)]\n    Eff(IO<A> effect) \n        : this(ReaderT.liftIO<RT, IO, A>(effect))\n    { }\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Lifting\n    //\n    \n    /// <summary>\n    /// Lift a value into the `Eff` monad \n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Pure(A value) =>\n        new(value);\n\n    /// <summary>\n    /// Lift a failure into the `Eff` monad \n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Fail(Error error) =>\n        new(error);\n    \n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Lift(Func<RT, Either<Error, A>> f) =>\n        new (f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Lift(Func<RT, Fin<A>> f) =>\n        new (f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Lift(Func<RT, A> f) =>\n        new (f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> LiftIO(Func<RT, Task<A>> f) =>\n        new (f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> LiftIO(Func<RT, Task<Fin<A>>> f) =>\n        new (rt => f(rt).Map(r => r.ThrowIfFail()));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> LiftIO(Func<RT, IO<A>> f) =>\n        new(Eff<RT>.getsM(f));\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Lift(Func<Either<Error, A>> f) =>\n        new (_ => f());    \n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Lift(Func<Fin<A>> f) =>\n        new (_ => f());    \n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Lift(Func<A> f) =>\n        new (_ => f());    \n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> LiftIO(Func<Task<A>> f) =>\n        new (_ => f());\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> LiftIO(Func<Task<Fin<A>>> f) =>\n        new(_ => f().Map(r => r.ThrowIfFail()));    \n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> LiftIO(IO<A> ma) =>\n        new(ma);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Map and map-left\n    //\n\n    /// <summary>\n    /// Maps the `Eff` monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Map<B>(Func<A, B> f) =>\n        new (effect.Map(f));\n\n    /// <summary>\n    /// Maps the `Eff` monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Select<B>(Func<A, B> f) =>\n        new (effect.Map(f));\n\n    /// <summary>\n    /// Maps the `Eff` monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, A> MapFail(Func<Error, Error> f) =>\n        this.Catch(f).As();\n\n    /// <summary>\n    /// Maps the inner IO monad\n    /// </summary>\n    /// <param name=\"f\">Function to map with</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> MapIO<B>(Func<IO<A>, IO<B>> f) =>\n        mapIO(this, f).As();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Bi-map\n    //\n\n    /// <summary>\n    /// Mapping of either the Success state or the Failure state depending on what\n    /// state this `Eff` monad is in.  \n    /// </summary>\n    /// <param name=\"Succ\">Mapping to use if the `Eff` monad if in a success state</param>\n    /// <param name=\"Fail\">Mapping to use if the `Eff` monad if in a failure state</param>\n    /// <returns>Mapped `Eff` monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> BiMap<B>(Func<A, B> Succ, Func<Error, Error> Fail) =>\n        Map(Succ).Catch(Fail).As();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Matching\n    //\n\n    /// <summary>\n    /// Pattern match the success or failure values and collapse them down to a success value\n    /// </summary>\n    /// <param name=\"Succ\">Success value mapping</param>\n    /// <param name=\"Fail\">Failure value mapping</param>\n    /// <returns>IO in a success state</returns>\n    [Pure]\n    public Eff<RT, B> Match<B>(Func<A, B> Succ, Func<Error, B> Fail) =>\n        Map(Succ).Catch(Fail).As();\n\n    /// <summary>\n    /// Map the failure to a success value\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO in a success state</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, A> IfFail(Func<Error, A> Fail) =>\n        this.Catch(Fail).As();\n\n    /// <summary>\n    /// Map the failure to a new IO effect\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO that encapsulates that IfFail</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, A> IfFailEff(Func<Error, K<Eff<RT>, A>> Fail) =>\n        this.Catch(Fail).As();\n\n    /// <summary>\n    /// Map the failure to a new IO effect\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO that encapsulates that IfFail</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, A> IfFailEff(Func<Error, K<Eff, A>> Fail) =>\n        IfFailEff(e => Fail(e).As().WithRuntime<RT>());\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Filter\n    //\n\n    /// <summary>\n    /// Only allow values through the effect if the predicate returns `true` for the bound value\n    /// </summary>\n    /// <param name=\"predicate\">Predicate to apply to the bound value></param>\n    /// <returns>Filtered IO</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, A> Filter(Func<A, bool> predicate) =>\n        Bind(x => predicate(x) ? Pure(x) : Fail(Errors.None));\n\n    /// <summary>\n    /// Only allow values through the effect if the predicate returns `true` for the bound value\n    /// </summary>\n    /// <param name=\"predicate\">Predicate to apply to the bound value></param>\n    /// <returns>Filtered IO</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, A> Where(Func<A, bool> predicate) =>\n        Bind(x => predicate(x) ? Pure(x) : Fail(Errors.None));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic binding\n    //\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<B>(Func<A, Eff<RT, B>> f) =>\n        new(effect.Bind(x => f(x).effect));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<B>(Func<A, IO<B>> f) =>\n        new(effect.Bind(f));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<B>(Func<A, Ask<RT, B>> f) =>\n        new(effect.Bind(f));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<B>(Func<A, K<Eff<RT>, B>> f) =>\n        Bind(a => f(a).As());\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(x => f(x).Value);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, A> Bind(Func<A, Fail<Error>> f) =>\n        Bind(x => Fail(f(x).Value));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<B>(Func<A, Eff<B>> f) =>\n        Bind(x => f(x).WithRuntime<RT>());\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"f\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, B> Bind<B>(Func<A, K<Eff, B>> f) =>\n        Bind(a => f(a).As());    \n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic binding and projection\n    //\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<B, C>(Func<A, Eff<RT, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<B, C>(Func<A, K<Eff<RT>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        new(effect.SelectMany(bind, project));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        new(effect.SelectMany(bind, project));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<B, C>(Func<A, Ask<RT, B>> bind, Func<A, B, C> project) =>\n        new(effect.SelectMany(bind, project));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<B, C>(Func<A, Fail<Error>> bind, Func<A, B, C> project) =>\n        SelectMany(x => Eff<RT, B>.Fail(bind(x).Value), project);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<C>(Func<A, Guard<Error, Unit>> bind, Func<A, Unit, C> project) =>\n        from x in this\n        from r in bind(x) switch\n                  {\n                      { Flag: true } => Eff<RT, Unit>.Pure(unit),\n                      var g          => Eff<RT, Unit>.Fail(g.OnFalse())\n                  }\n        select project(x, unit);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<C>(Func<A, Guard<Fail<Error>, Unit>> bind, Func<A, Unit, C> project) =>\n        from x in this\n        from r in bind(x) switch\n                  {\n                      { Flag: true } => Eff<RT, Unit>.Pure(unit),\n                      var g          => Eff<RT, Unit>.Fail(g.OnFalse().Value)\n                  }\n        select project(x, unit);\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<B, C>(Func<A, Eff<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monadic bind operation.  This runs the current `Eff` monad and feeds its result to the\n    /// function provided; which in turn returns a new `Eff` monad.  This can be thought of as\n    /// chaining IO operations sequentially.\n    /// </summary>\n    /// <param name=\"bind\">Bind operation</param>\n    /// <returns>Composition of this monad and the result of the function provided</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<RT, C> SelectMany<B, C>(Func<A, K<Eff, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Conversion operators\n    //\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(Pure<A> ma) =>\n        ma.ToEff<RT>();\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(Fail<Error> ma) =>\n        ma.ToEff<RT, A>();\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(in Lift<A> ma) =>\n        Lift(ma.Function);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(in Lift<Fin<A>> ma) =>\n        Lift(ma.Function);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(in Lift<RT, A> ma) =>\n        Lift(ma.Function);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(in Lift<RT, Fin<A>> ma) =>\n        Lift(ma.Function);    \n    \n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(in Either<Error, A> ma) =>\n        ma.Match(Left: Fail, Right: Pure);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(in Fin<A> ma) =>\n        ma.Match(Succ: Pure, Fail: Fail);\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(in Eff<A> ma) =>\n        ma.WithRuntime<RT>();\n\n    /// <summary>\n    /// Convert to an `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(in IO<A> ma) =>\n        LiftIO(ma);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Eff<RT, A>(Error fail) =>\n        Fail(fail);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Obsolete\n    //\n\n    /// <summary>\n    /// Lift a value into the `Eff` monad\n    /// </summary>\n    [Obsolete(\"Use either: `Eff<RT, A>.Lift`, `Prelude.liftEff`, or `lift`\")]\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Success(A value) =>\n        Pure(value);\n\n    /// <summary>\n    /// Lift a synchronous effect into the `Eff` monad\n    /// </summary>\n    [Obsolete(\"Use either: `Eff<RT, A>.Lift`, `Prelude.liftEff`, or `lift`\")]\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> Effect(Func<RT, A> f) =>\n        Lift(f);\n\n    /// <summary>\n    /// Lift a synchronous effect into the `Eff` monad\n    /// </summary>\n    [Obsolete(\"Use either: `Eff<RT, A>.Lift`, `Prelude.liftEff`, or `lift`\")]\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> EffectMaybe(Func<RT, Fin<A>> f) =>\n        Lift(f);\n\n    public override string ToString() => \n        \"Eff\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Extensions/Eff.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Eff<RT, B> Map<RT, A, B>(this Func<A, B> f, K<Eff<RT>,  A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Eff<RT, B> Map<RT, A, B>(this Func<A, B> f, Eff<RT, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Eff<RT, B> Action<RT, A, B>(\n        this Eff<RT, A> ma,\n        Eff<RT, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Eff<RT, B> Apply<RT, A, B>(this Eff<RT, Func<A, B>> mf, K<Eff<RT>,  A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Eff<RT, B> Apply<RT, A, B>(this K<Eff<RT>, Func<A, B>> mf, K<Eff<RT>, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Extensions/Eff.Extensions.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<RT, A>(K<Eff<RT>, A> ma)\n    {\n        /// <summary>\n        /// Cast type to its Kind\n        /// </summary>\n        public Eff<RT, A> As() =>\n            (Eff<RT, A>)ma;\n\n        /// <summary>\n        /// Invoke the effect\n        /// </summary>\n        /// <remarks>\n        /// Returns the result value only \n        /// </remarks>\n        [Pure, MethodImpl(Opt.Default)]\n        public Fin<A> Run(RT env) =>\n            ma.As().Run(env, EnvIO.New());\n\n        /// <summary>\n        /// Invoke the effect\n        /// </summary>\n        /// <remarks>\n        /// Returns the result value only \n        /// </remarks>\n        [Pure, MethodImpl(Opt.Default)]\n        public Fin<A> Run(RT env, EnvIO envIO)\n        {\n            try\n            {\n                return ma.As().effect.Run(env).Run(envIO);\n            }\n            catch(Exception e)\n            {\n                return Fin.Fail<A>(e);\n            }\n        }\n\n        /// <summary>\n        /// Invoke the effect\n        /// </summary>\n        /// <remarks>\n        /// This is labelled 'unsafe' because it can throw an exception, whereas\n        /// `Run` will capture any errors and return a `Fin` type.\n        /// </remarks>\n        [Pure, MethodImpl(Opt.Default)]\n        public A RunUnsafe(RT env) =>\n            ma.As().effect.Run(env).Run();\n\n        /// <summary>\n        /// Invoke the effect\n        /// </summary>\n        /// <remarks>\n        /// This is labelled 'unsafe' because it can throw an exception, whereas\n        /// `Run` will capture any errors and return a `Fin` type.\n        /// </remarks>\n        [Pure, MethodImpl(Opt.Default)]\n        public A RunUnsafe(RT env, EnvIO envIO) =>\n            ma.As().effect.Run(env).Run(envIO);\n\n        /// <summary>\n        /// Invoke the effect to leave the inner IO monad\n        /// </summary>\n        [Pure, MethodImpl(Opt.Default)]\n        public IO<A> RunIO(RT env) =>\n            ma.As().effect.Run(env).As();\n\n        /// <summary>\n        /// Invoke the effect\n        /// </summary>\n        /// <remarks>\n        /// Returns the result value only \n        /// </remarks>\n        [Pure, MethodImpl(Opt.Default)]\n        public async Task<Fin<A>> RunAsync(RT env)\n        {\n            try\n            {\n                return await ma.As().effect.Run(env).RunAsync();\n            }\n            catch(Exception e)\n            {\n                return Fin.Fail<A>(e);\n            }\n        }\n\n        /// <summary>\n        /// Invoke the effect\n        /// </summary>\n        /// <remarks>\n        /// Returns the result value only \n        /// </remarks>\n        [Pure, MethodImpl(Opt.Default)]\n        public async Task<Fin<A>> RunAsync(RT env, EnvIO envIO)\n        {\n            try\n            {\n                return await ma.As().effect.Run(env).RunAsync(envIO);\n            }\n            catch(Exception e)\n            {\n                return Fin.Fail<A>(e);\n            }\n        }\n\n        /// <summary>\n        /// Invoke the effect\n        /// </summary>\n        /// <remarks>\n        /// This is labelled 'unsafe' because it can throw an exception, whereas\n        /// `Run` will capture any errors and return a `Fin` type.\n        /// </remarks>\n        [Pure, MethodImpl(Opt.Default)]\n        public ValueTask<A> RunUnsafeAsync(RT env) =>\n            ma.As().effect.Run(env).RunAsync(EnvIO.New());\n\n        /// <summary>\n        /// Invoke the effect\n        /// </summary>\n        /// <remarks>\n        /// This is labelled 'unsafe' because it can throw an exception, whereas\n        /// `Run` will capture any errors and return a `Fin` type.\n        /// </remarks>\n        [Pure, MethodImpl(Opt.Default)]\n        public ValueTask<A> RunUnsafeAsync(RT env, EnvIO envIO) =>\n            ma.As().effect.Run(env).RunAsync(envIO);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Invoking\n    //\n\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic join\n    //\n\n    /// <summary>\n    /// Monadic join operator \n    /// </summary>\n    /// <remarks>\n    /// Collapses a nested IO monad so there is no nesting.\n    /// </remarks>\n    /// <param name=\"mma\">Nest IO monad to flatten</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Flattened IO monad</returns>\n    public static Eff<RT, A> Flatten<RT, A>(this K<Eff<RT>, Eff<RT, A>> mma) =>\n        mma.As().Bind(ma => ma);\n\n    /// <summary>\n    /// Monadic join operator \n    /// </summary>\n    /// <remarks>\n    /// Collapses a nested IO monad so there is no nesting.\n    /// </remarks>\n    /// <param name=\"mma\">Nest IO monad to flatten</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Flattened IO monad</returns>\n    public static Eff<RT, A> Flatten<RT, A>(this K<Eff<RT>, K<Eff<RT>, A>> mma) =>\n        mma.As().Bind(ma => ma);\n    \n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany extensions\n    //\n\n    /// <summary>\n    /// Monadic bind and project with paired IO monads\n    /// </summary>\n    public static Eff<RT, D> SelectMany<RT, A, B, C, D>(\n        this (K<Eff<RT>, A> First, K<Eff<RT>, B> Second) self,\n        Func<(A First, B Second), K<Eff<RT>, C>> bind,\n        Func<(A First, B Second), C, D> project) =>\n        self.Zip().Bind(ab => bind(ab).Map(c => project(ab, c))).As();\n\n    /// <summary>\n    /// Monadic bind and project with paired IO monads\n    /// </summary>\n    public static Eff<RT, D> SelectMany<RT, A, B, C, D>(\n        this K<Eff<RT>, A> self,\n        Func<A, (K<Eff<RT>, B> First, K<Eff<RT>, C> Second)> bind,\n        Func<A, (B First, C Second), D> project) =>\n        self.As().Bind(a => bind(a).Zip().Map(cd => project(a, cd)));\n\n    /// <summary>\n    /// Monadic bind and project with paired IO monads\n    /// </summary>\n    public static Eff<RT, E> SelectMany<RT, A, B, C, D, E>(\n        this (K<Eff<RT>, A> First, K<Eff<RT>, B> Second, K<Eff<RT>, C> Third) self,\n        Func<(A First, B Second, C Third), K<Eff<RT>, D>> bind,\n        Func<(A First, B Second, C Third), D, E> project) =>\n        self.Zip().Bind(ab => bind(ab).Map(c => project(ab, c))).As();\n\n    /// <summary>\n    /// Monadic bind and project with paired IO monads\n    /// </summary>\n    public static Eff<RT, E> SelectMany<RT, A, B, C, D, E>(\n        this K<Eff<RT>, A> self,\n        Func<A, (K<Eff<RT>, B> First, K<Eff<RT>, C> Second, K<Eff<RT>, D> Third)> bind,\n        Func<A, (B First, C Second, D Third), E> project) =>\n        self.As().Bind(a => bind(a).Zip().Map(cd => project(a, cd)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Extensions/Eff.Guard.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    /// <summary>\n    /// Natural transformation to `Eff`\n    /// </summary>\n    public static Eff<RT, Unit> ToEff<RT>(this Guard<Error, Unit> guard) =>\n        guard.Flag\n            ? Pure(unit)\n            : Fail(guard.OnFalse());\n\n    /// <summary>\n    /// Monadic binding support for `Eff`\n    /// </summary>\n    public static Eff<RT, B> Bind<RT, B>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, Eff<RT, B>> f) =>\n        guard.Flag\n            ? f(default).As()\n            : Fail(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `Eff`\n    /// </summary>\n    public static Eff<RT, C> SelectMany<RT, B, C>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, Eff<RT, B>> bind, \n        Func<Unit, B, C> project) =>\n        guard.Flag\n            ? bind(default).As().Map(b => project(default, b))\n            : Fail(guard.OnFalse());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Operators/Eff.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<RT, A, B>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Eff<RT, B> operator >>> (K<Eff<RT>, A> ma, K<Eff<RT>, B> mb) =>\n            ma.Action(mb).As();\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, B> operator * (K<Eff<RT>, Func<A, B>> mf, K<Eff<RT>, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, B> operator * (K<Eff<RT>, A> ma, K<Eff<RT>, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<RT, A, B, C>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, C>> operator * (\n            K<Eff<RT>, Func<A, B, C>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, C>> operator * (\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<RT, A, B, C, D>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, D>>> operator * (\n            K<Eff<RT>, Func<A, B, C, D>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, D>>> operator * (\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<RT, A, B, C, D, E>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Eff<RT>, Func<A, B, C, D, E>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<RT, A, B, C, D, E, F>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Eff<RT>, Func<A, B, C, D, E, F>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<RT, A, B, C, D, E, F, G>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Eff<RT>, Func<A, B, C, D, E, F, G>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<RT, A, B, C, D, E, F, G, H>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Eff<RT>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<RT, A, B, C, D, E, F, G, H, I>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Eff<RT>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<RT, A, B, C, D, E, F, G, H, I, J>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Eff<RT>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<RT, A, B, C, D, E, F, G, H, I, J, K>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Eff<RT>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Eff<RT>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Eff<RT>, A> ma,\n            K<Eff<RT>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Operators/Eff.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<RT, A>(K<Eff<RT>, A> self)\n    {\n        public static Eff<RT, A> operator |(K<Eff<RT>, A> lhs, K<Eff<RT>, A> rhs) =>\n            lhs.Choose(rhs).As();\n\n        public static Eff<RT, A> operator |(K<Eff<RT>, A> lhs, K<Eff, A> rhs) =>\n            lhs.Choose(rhs.As().WithRuntime<RT>()).As();\n\n        public static Eff<RT, A> operator |(K<Eff<RT>, A> lhs, Pure<A> rhs) =>\n            lhs.Choose(rhs.ToEff<RT>()).As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Operators/Eff.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<RT, A>(K<Eff<RT>, A> self)\n    {\n        public static Eff<RT, A> operator |(K<Eff<RT>, A> lhs, CatchM<Error, Eff<RT>, A> rhs) =>\n            lhs.Catch(rhs).As();\n\n        public static Eff<RT, A> operator |(K<Eff<RT>, A> lhs, Fail<Error> rhs) =>\n            lhs.Catch(rhs).As();\n\n        public static Eff<RT, A> operator |(K<Eff<RT>, A> lhs, Error rhs) =>\n            lhs.Catch(rhs).As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Operators/Eff.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static partial class EffExtensions\n{\n    extension<RT, X, A>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static Eff<RT, A> operator |(K<Eff<RT>, A> lhs, Finally<Eff<RT>, X> rhs) =>\n            lhs.Finally(rhs.Operation).As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Operators/Eff.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<RT, A, B>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, B> operator *(Func<A, B> f, K<Eff<RT>, A> ma) =>\n            ma.Map(f).As();\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, B> operator *(K<Eff<RT>, A> ma, Func<A, B> f) =>\n            ma.Map(f).As();\n    }\n    \n    extension<RT, A, B, C>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, C>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<RT, A, B, C, D>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, D>>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<RT, A, B, C, D, E>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<RT, A, B, C, D, E, F>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<RT, A, B, C, D, E, F, G>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<RT, A, B, C, D, E, F, G, H>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<RT, A, B, C, D, E, F, G, H, I>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<RT, A, B, C, D, E, F, G, H, I, J>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<RT, A, B, C, D, E, F, G, H, I, J, K>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Eff<RT>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Eff<RT, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Eff<RT>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Operators/Eff.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<RT, A, B>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Eff<RT, B> operator >> (K<Eff<RT>, A> ma, Func<A, K<Eff<RT>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Eff<RT, B> operator >> (K<Eff<RT>, A> lhs, K<Eff<RT>, B> rhs) =>\n            lhs >> (_ => rhs);\n        \n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Eff<RT, B> operator >> (K<Eff<RT>, A> ma, Func<A, K<IO, B>> f) =>\n            +ma.Bind(x => Eff.lift<RT, B>(+f(x)));\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Eff<RT, B> operator >> (K<Eff<RT>, A> lhs, K<IO, B> rhs) =>\n            lhs >> (_ => rhs);        \n    }\n    \n    extension<RT, A>(K<Eff<RT>, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Eff<RT, A> operator >> (K<Eff<RT>, A> lhs, K<Eff<RT>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n        \n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Eff<RT, A> operator >> (K<Eff<RT>, A> lhs, K<IO, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Operators/Eff.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EffExtensions\n{\n    extension<RT, A>(K<Eff<RT>, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Eff<RT, A> operator +(K<Eff<RT>, A> ma) =>\n            (Eff<RT, A>)ma;\n        \n        public static Eff<RT, A> operator >> (K<Eff<RT>, A> ma, Lower lower) =>\n            (Eff<RT, A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Prelude/Eff.Prelude.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing System.Threading.Tasks;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Construct a successful effect with a pure value\n    /// </summary>\n    /// <param name=\"value\">Pure value to construct the monad with</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Synchronous IO monad that captures the pure value</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> SuccessEff<RT, A>(A value) =>\n        LanguageExt.Eff<RT, A>.Pure(value);\n\n    /// <summary>\n    /// Construct a failed effect\n    /// </summary>\n    /// <param name=\"error\">Error that represents the failure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Synchronous IO monad that captures the failure</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> FailEff<RT, A>(Error error) =>\n        LanguageExt.Eff<RT, A>.Fail(error);    \n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Runtime helpers\n    //\n\n    /// <summary>\n    /// Make the runtime into the bound value\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, RT> runtime<RT>() =>\n        liftEff<RT, RT>(identity);\n\n    /// <summary>\n    /// Get all the internal state of the `Eff`\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, (RT Runtime, EnvIO EnvIO)> getState<RT>() =>\n        new(LanguageExt.Eff<RT>.getState);\n\n    /// <summary>\n    /// Create a new cancellation context and run the provided Aff in that context\n    /// </summary>\n    /// <param name=\"ma\">Operation to run in the next context</param>\n    /// <typeparam name=\"RT\">Runtime environment</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>An asynchronous effect that captures the operation running in context</returns>\n    public static Eff<RT, A> localCancel<RT, A>(Eff<RT, A> ma) =>\n        ma.LocalIO().As();\n\n    /// <summary>\n    /// Create a new local context for the environment by mapping the outer environment and then\n    /// using the result as a new context when running the IO monad provided\n    /// </summary>\n    /// <param name=\"f\">Function to map the outer environment into a new one to run `ma`</param>\n    /// <param name=\"ma\">IO monad to run in the new context</param>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<OuterRT, A> localEff<OuterRT, InnerRT, A>(Func<OuterRT, InnerRT> f, Eff<InnerRT, A> ma) =>\n         // Get the current state of the Eff  \n         from st in getState<OuterRT>()\n\n         // Run the local operation\n         from rs in IO.local(ma.effect.Run(f(st.Runtime))).As()\n         \n         // Ignore any changes to the state and just return the result of the local operation\n         select rs;\n \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monadic join\n    //\n\n    /// <summary>\n    /// Monadic join operator \n    /// </summary>\n    /// <remarks>\n    /// Collapses a nested IO monad so there is no nesting.\n    /// </remarks>\n    /// <param name=\"mma\">Nest IO monad to flatten</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Flattened IO monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> flatten<RT, A>(Eff<RT, Eff<RT, A>> mma) =>\n        mma.Bind(x => x);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Lifting\n    //\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> liftEff<RT, A>(Func<RT, Either<Error, A>> f) =>\n        LanguageExt.Eff<RT, A>.Lift(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> liftEff<RT, A>(Func<RT, Fin<A>> f) =>\n        LanguageExt.Eff<RT, A>.Lift(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> liftEff<RT, A>(Func<RT, A> f) =>\n        LanguageExt.Eff<RT, A>.Lift(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> liftEff<RT, A>(Func<RT, Task<A>> f) =>\n        LanguageExt.Eff<RT, A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> liftEff<RT, A>(Func<RT, Task<Fin<A>>> f) =>\n        LanguageExt.Eff<RT, A>.LiftIO(f);\n\n    /// <summary>\n    /// Lift an effect into the `Eff` monad\n    /// </summary>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> liftEff<RT, A>(IO<A> ma) =>\n        LanguageExt.Eff<RT, A>.LiftIO(ma);\n\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Map and map-left\n    //\n\n    /// <summary>\n    /// Maps the IO monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped IO monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, B> map<RT, A, B>(Eff<RT, A> ma, Func<A, B> f) =>\n        ma.Map(f);\n\n    /// <summary>\n    /// Maps the IO monad if it's in a success state\n    /// </summary>\n    /// <param name=\"f\">Function to map the success value with</param>\n    /// <returns>Mapped IO monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> mapFail<RT, A>(Eff<RT, A> ma, Func<Error, Error> f) =>\n        ma.MapFail(f);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Bi-map\n    //\n\n    /// <summary>\n    /// Mapping of either the Success state or the Failure state depending on what\n    /// state this IO monad is in.  \n    /// </summary>\n    /// <param name=\"Succ\">Mapping to use if the IO monad is in a success state</param>\n    /// <param name=\"Fail\">Mapping to use if the IO monad is in a failure state</param>\n    /// <returns>Mapped IO monad</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, B> bimap<RT, A, B>(Eff<RT, A> ma, Func<A, B> Succ, Func<Error, Error> Fail) =>\n        ma.BiMap(Succ, Fail);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Matching\n    //\n\n    /// <summary>\n    /// Pattern match the success or failure values and collapse them down to a success value\n    /// </summary>\n    /// <param name=\"Succ\">Success value mapping</param>\n    /// <param name=\"Fail\">Failure value mapping</param>\n    /// <returns>IO in a success state</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, B> match<RT, A, B>(Eff<RT, A> ma, Func<A, B> Succ, Func<Error, B> Fail) =>\n        ma.Match(Succ, Fail);\n\n    /// <summary>\n    /// Map the failure to a success value\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO in a success state</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> ifFail<RT, A>(Eff<RT, A> ma, Func<Error, A> Fail) =>\n        ma.IfFail(Fail);\n\n    /// <summary>\n    /// Map the failure to a new IO effect\n    /// </summary>\n    /// <param name=\"f\">Function to map the fail value</param>\n    /// <returns>IO that encapsulates that IfFail</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> ifFailEff<RT, A>(Eff<RT, A> ma, Func<Error, Eff<RT, A>> Fail) =>\n        ma.IfFailEff(Fail);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Filter\n    //\n\n    /// <summary>\n    /// Only allow values through the effect if the predicate returns `true` for the bound value\n    /// </summary>\n    /// <param name=\"predicate\">Predicate to apply to the bound value></param>\n    /// <returns>Filtered IO</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Eff<RT, A> filter<RT, A>(Eff<RT, A> ma, Func<A, bool> predicate) =>\n        ma.Filter(predicate);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Eff/Eff with runtime/Prelude/Eff.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Eff<RT, B> map<RT, A, B>(Func<A, B> f, K<Eff<RT>,  A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Eff<RT, B> action<RT, A, B>(K<Eff<RT>, A> ma, K<Eff<RT>, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Eff<RT, B> apply<RT, A, B>(K<Eff<RT>, Func<A, B>> mf, K<Eff<RT>, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOAction.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOAction<A, B, C>(K<IO, A> Fa, K<IO, B> Fb, Func<B, IO<C>> Next) : InvokeSyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOAction<A, B, D>(Fa, Fb, b => Next(b).Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOAction<A, B, D>(Fa, Fb, b => Next(b).Bind(f));\n    \n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOAction<A, B, D>(Fa, Fb, b => Next(b).BindAsync(f));\n    \n    public override IO<C> Invoke(EnvIO envIO)\n    {\n        var taskA = Fa.As().RunAsync(envIO);\n        if (taskA.IsCompleted)\n        {\n            return Fb.Bind(Next).As();\n        }\n        else\n        {\n            return new IOActionAsync<A, B, C>(taskA, Fb, Next);\n        }\n    }\n}\n\nrecord IOActionAsync<A, B, C>(ValueTask<A> Fa, K<IO, B> Fb, Func<B, IO<C>> Next) : InvokeAsyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOActionAsync<A, B, D>(Fa, Fb, b => Next(b).Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOActionAsync<A, B, D>(Fa, Fb, b => Next(b).Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOActionAsync<A, B, D>(Fa, Fb, b => Next(b).BindAsync(f));\n\n    public override async ValueTask<IO<C>> Invoke(EnvIO envIO)\n    {\n        await Fa;\n        return Fb.Bind(Next).As();\n    }\n}\n\nrecord IOActionLazy<A, B, C>(K<IO, A> Fa, Memo<IO, B> Fb, Func<B, IO<C>> Next) : InvokeSyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOActionLazy<A, B, D>(Fa, Fb, b => Next(b).Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOActionLazy<A, B, D>(Fa, Fb, b => Next(b).Bind(f));\n    \n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOActionLazy<A, B, D>(Fa, Fb, b => Next(b).BindAsync(f));\n    \n    public override IO<C> Invoke(EnvIO envIO)\n    {\n        var taskA = Fa.As().RunAsync(envIO);\n        if (taskA.IsCompleted)\n        {\n            return Fb.Value.Bind(Next).As();\n        }\n        else\n        {\n            return new IOActionLazyAsync<A, B, C>(taskA, Fb, Next);\n        }\n    }\n}\n\nrecord IOActionLazyAsync<A, B, C>(ValueTask<A> Fa, Memo<IO, B> Fb, Func<B, IO<C>> Next) : InvokeAsyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOActionLazyAsync<A, B, D>(Fa, Fb, b => Next(b).Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOActionLazyAsync<A, B, D>(Fa, Fb, b => Next(b).Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOActionLazyAsync<A, B, D>(Fa, Fb, b => Next(b).BindAsync(f));\n\n    public override async ValueTask<IO<C>> Invoke(EnvIO envIO)\n    {\n        await Fa;\n        return Fb.Value.Bind(Next).As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOActions.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOActions<A, B>(IterableNE<K<IO, A>> Fas, Func<A, IO<B>> Next) : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOActions<A, C>(Fas, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOActions<A, C>(Fas, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOActions<A, C>(Fas, x => Next(x).BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        var iter = Fas.GetIterator();\n        var head = iter.Head;\n        var task = head.RunAsync(envIO);\n        if (task.IsCompleted)\n        {\n            return new IOActionsSync<A, B>(task.Result, iter.Tail.Split(), Next);\n        }\n        else\n        {\n            return new IOActionsAsync<A, B>(task, iter.Tail.Split(), Next);\n        }\n    }\n}\n\nrecord IOActions2<A, B>(Iterator<K<IO, A>> Fas, Func<A, IO<B>> Next) : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOActions2<A, C>(Fas, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOActions2<A, C>(Fas, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOActions2<A, C>(Fas, x => Next(x).BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        var iter = Fas.GetIterator();\n        var head = iter.Head;\n        var task = head.RunAsync(envIO);\n        if (task.IsCompleted)\n        {\n            return new IOActionsSync<A, B>(task.Result, iter.Tail.Split(), Next);\n        }\n        else\n        {\n            return new IOActionsAsync<A, B>(task, iter.Tail.Split(), Next);\n        }\n    }\n}\n\nrecord IOActionsSync<A, B>(A Value, Iterator<K<IO, A>> Fas, Func<A, IO<B>> Next) : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOActionsSync<A, C>(Value, Fas, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOActionsSync<A, C>(Value, Fas, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOActionsSync<A, C>(Value, Fas, x => Next(x).BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        if (Fas.IsEmpty)\n        {\n            return Next(Value);\n        }\n        else\n        {\n            return new IOActions2<A, B>(Fas.Clone(), Next);\n        }\n    }\n}\n\nrecord IOActionsAsync<A, B>(ValueTask<A> Value, Iterator<K<IO, A>> Fas, Func<A, IO<B>> Next) : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOActionsAsync<A, C>(Value, Fas, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOActionsAsync<A, C>(Value, Fas, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOActionsAsync<A, C>(Value, Fas, x => Next(x).BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO)\n    {\n        var value = await Value;\n        \n        if (Fas.IsEmpty)\n        {\n            return Next(value);\n        }\n        else\n        {\n            return new IOActions2<A, B>(Fas.Clone(), Next);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOActionsAsync.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.DSL;\n\nrecord IOAsyncActions<A, B>(IteratorAsync<K<IO, A>> Fas, Func<A, IO<B>> Next) : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOAsyncActions<A, C>(Fas, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOAsyncActions<A, C>(Fas, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOAsyncActions<A, C>(Fas, x => Next(x).BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO)\n    {\n        if (await Fas.IsEmpty)\n        {\n            return IO.fail<B>(Error.New(\"Actions is empty\"));\n        }\n        else\n        {\n            ignore(await (await Fas.Head).RunAsync(envIO));\n            return new IOAsyncActions<A, B>(await Fas.Tail, Next);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOApply.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOApply<A, B, C>(K<IO, Func<A, B>> Ff, K<IO, A> Fa, Func<B, K<IO, C>> Next) : InvokeSyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) => \n        new IOApply<A, B, D>(Ff, Fa, x => Next(x).As().Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOApply<A, B, D>(Ff, Fa, x => Next(x).As().Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOApply<A, B, D>(Ff, Fa, x => Next(x).As().BindAsync(f));\n\n    public override IO<C> Invoke(EnvIO envIO)\n    {\n        var tf = Ff.RunAsync(envIO);\n        var ta = Fa.RunAsync(envIO);\n\n        switch (tf.IsCompleted, ta.IsCompleted)\n        {\n            case (true, true):\n                return Next(tf.Result(ta.Result)).As();\n                \n            default:\n                return new IOApplyFunctionAsync<A, B, C>(tf, ta, Next);\n        }        \n    }\n    \n    public override string ToString() => \n        \"IO apply\";\n}\n\nrecord IOApplyFunctionAsync<A, B, C>(ValueTask<Func<A, B>> Ff, ValueTask<A> Fa, Func<B, K<IO, C>> Next) : InvokeAsyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) => \n        new IOApplyFunctionAsync<A, B, D>(Ff, Fa, x => Next(x).As().Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOApplyFunctionAsync<A, B, D>(Ff, Fa, x => Next(x).As().Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOApplyFunctionAsync<A, B, D>(Ff, Fa, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<C>> Invoke(EnvIO envIO)\n    {\n        switch (Ff.IsCompleted, Fa.IsCompleted)\n        {\n            case (true, true):\n                return Next(Ff.Result(Fa.Result)).As();\n                \n            case (false, true):\n                return Next((await Ff)(Fa.Result)).As();\n            \n            case (true, false):\n                return Next(Ff.Result(await Fa)).As();\n            \n            default:\n                var tf = Ff.AsTask();\n                var ta = Fa.AsTask();\n                await Task.WhenAll(tf, ta);\n                return Next(Ff.Result(Fa.Result)).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO apply\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOBind.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOBind<A, B>(A Value, Func<A, K<IO, B>> F) : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) =>\n        new IOBindMap<A, B, C>(Value, F, f);\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) =>\n        new IOBindBind<A, B, C>(Value, F, f);\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) =>\n        new IOBindBindAsync2<A, B, C>(Value.AsValueTask(), x => F(x).AsValueTask(), f);\n\n    public override IO<B> Invoke(EnvIO envIO) =>\n        F(Value).As();\n    \n    public override string ToString() => \n        \"IO bind\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOBindAsync.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOBindAsync<A, B>(ValueTask<A> Value, Func<A, K<IO, B>> F) : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) =>\n        new IOBindMapAsync<A, B, C>(Value, F, f);\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) =>\n        new IOBindBindAsync<A, B, C>(Value, F, f);\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) =>\n        new IOBindBindAsync2<A, B, C>(Value, x => new ValueTask<K<IO, B>>(F(x)), f);\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) =>\n        F(await Value).As();\n    \n    public override string ToString() => \n        \"IO bind async\";\n}\n\nrecord IOBindBindAsync<A, B, C>(ValueTask<A> Value, Func<A, K<IO, B>> F, Func<B, K<IO, C>> G) : InvokeAsyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOBindBindAsync<A, B, D>(Value, F, x => G(x).As().Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) =>\n        new IOBindBindAsync<A, B, D>(Value, F, x => G(x).As().Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) =>\n        new IOBindBindAsync<A, B, D>(Value, F, x => G(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<C>> Invoke(EnvIO envIO) =>\n        F(await Value).Bind(G).As();\n    \n    public override string ToString() => \n        \"IO bind bind async\";\n}\n\nrecord IOBindMapAsync<A, B, C>(ValueTask<A> Value, Func<A, K<IO, B>> F, Func<B, C> G) : InvokeAsyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOBindMapAsync<A, B, D>(Value, F, x => f(G(x)));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) =>\n        new IOBindBindAsync<A, B, D>(Value, F, x => f(G(x)));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) =>\n        new IOBindBindAsync<A, B, D>(Value, F, x => IO.pure(G(x)).BindAsync(f));\n\n    public override async ValueTask<IO<C>> Invoke(EnvIO envIO) =>\n        F(await Value).Map(G).As();\n    \n    public override string ToString() => \n        \"IO bind map async\";\n}\n\nrecord IOBindAsync2<A, B>(ValueTask<A> Value, Func<A, ValueTask<K<IO, B>>> F) : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) =>\n        new IOBindAsync2<A, C>(Value, async x => (await F(x)).As().Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) =>\n        new IOBindBindSync2<A, B, C>(Value, F, f);\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) =>\n        new IOBindBindAsync2<A, B, C>(Value, F, f);\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) =>\n        (await F(await Value)).As();\n    \n    public override string ToString() => \n        \"IO bind bind async\";\n}\n\nrecord IOBindBindAsync2<A, B, C>(ValueTask<A> Value, Func<A, ValueTask<K<IO, B>>> F, Func<B, ValueTask<K<IO, C>>> G) : InvokeAsyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOBindBindAsync2<A, B, D>(Value, F, async x => (await G(x)).Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) =>\n        new IOBindBindAsync2<A, B, D>(Value, F, async x => (await G(x)).Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOBindBindAsync2<A, B, D>(Value, F, async x => (await G(x)).As().BindAsync(f));\n\n    public override async ValueTask<IO<C>> Invoke(EnvIO envIO) =>\n        (await F(await Value)).As().BindAsync(G);\n    \n    public override string ToString() => \n        \"IO bind bind async\";\n}\n\nrecord IOBindBindSync2<A, B, C>(ValueTask<A> Value, Func<A, ValueTask<K<IO, B>>> F, Func<B, K<IO, C>> G) : InvokeAsyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOBindBindSync2<A, B, D>(Value, F, x => G(x).Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) =>\n        new IOBindBindSync2<A, B, D>(Value, F, x => G(x).Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOBindBindSync2<A, B, D>(Value, F, x => G(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<C>> Invoke(EnvIO envIO) =>\n        (await F(await Value)).As().Bind(G);\n    \n    public override string ToString() => \n        \"IO bind bind async\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOBindMap.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOBindMap<A, B, C>(A Value, Func<A, K<IO, B>> Ff, Func<B, C> Fg) : InvokeSyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) => \n        new IOBindMap<A, B, C, D>(Value, Ff, Fg, f);\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOBindMap2<A, B, C, D>(Value, Ff, Fg, f);\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) =>\n        new IOBindMap2<A, B, C, D>(Value, Ff, Fg, x => IO.pureVAsync(f(x)).Bind(v => v));\n\n    public override IO<C> Invoke(EnvIO envIO) =>\n        Ff(Value).As().Map(Fg);\n    \n    public override string ToString() => \n        \"IO bind map\";\n}\n\nrecord IOBindBind<A, B, C>(A Value, Func<A, K<IO, B>> Ff, Func<B, K<IO, C>> Fg) : InvokeSyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) =>\n        new IOBindBindMap<A, B, C, D>(Value, Ff, Fg, f);\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) =>\n        new IOBindBind<A, B, D>(Value, Ff, x => Fg(x).Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOBindBind<A, B, D>(Value, Ff, x => Fg(x).As().BindAsync(f));\n    \n    public override IO<C> Invoke(EnvIO envIO) =>\n        Ff(Value).As().Bind(Fg);\n    \n    public override string ToString() => \n        \"IO bind bind\";\n}\n\nrecord IOBindBindMap<A, B, C, D>(A Value, Func<A, K<IO, B>> Ff, Func<B, K<IO, C>> Fg, Func<C, D> Fh) : InvokeSyncIO<D>\n{\n    public override IO<E> Map<E>(Func<D, E> f) =>\n        new IOBindBindMap<A, B, C, E>(Value, Ff, Fg, x => f(Fh(x)));\n\n    public override IO<E> Bind<E>(Func<D, K<IO, E>> f) =>\n        new IOBindBindMapBind<A, B, C, D, E>(Value, Ff, Fg, Fh, f);\n\n    public override IO<E> BindAsync<E>(Func<D, ValueTask<K<IO, E>>> f) => \n        new IOBindBindMapBind<A, B, C, D, E>(Value, Ff, Fg, Fh, x => IO.pureVAsync(f(x)).Bind(v => v));\n\n    public override IO<D> Invoke(EnvIO envIO) =>\n        Ff(Value).As().Bind(Fg).Map(Fh);\n    \n    public override string ToString() => \n        \"IO bind bind map\";\n}\n\nrecord IOBindBindMapBind<A, B, C, D, E>(A Value, Func<A, K<IO, B>> Ff, Func<B, K<IO, C>> Fg, Func<C, D> Fh, Func<D, K<IO, E>> Fi) : InvokeSyncIO<E>\n{\n    public override IO<F> Map<F>(Func<E, F> f) =>\n        new IOBindBindMapBind<A, B, C, D, F>(Value, Ff, Fg, Fh, x => Fi(x).Map(f));\n\n    public override IO<F> Bind<F>(Func<E, K<IO, F>> f) =>\n        new IOBindBindMapBind<A, B, C, D, F>(Value, Ff, Fg, Fh, x => Fi(x).Bind(f));\n\n    public override IO<F> BindAsync<F>(Func<E, ValueTask<K<IO, F>>> f) => \n        new IOBindBindMapBind<A, B, C, D, F>(Value, Ff, Fg, Fh, x => Fi(x).As().BindAsync(f));\n\n    public override IO<E> Invoke(EnvIO envIO) =>\n        Ff(Value).As().Bind(Fg).Map(Fh).Bind(Fi);\n    \n    public override string ToString() => \n        \"IO bind map bind\";\n}\n\nrecord IOBindMap<A, B, C, D>(A Value, Func<A, K<IO, B>> Ff, Func<B, C> Fg, Func<C, D> Fh) : InvokeSyncIO<D>\n{\n    public override IO<E> Map<E>(Func<D, E> f) =>\n        new IOBindMap<A, B, C, E>(Value, Ff, Fg, x => f(Fh(x)));\n\n    public override IO<E> Bind<E>(Func<D, K<IO, E>> f) =>\n        new IOBindMap2<A, B, C, E>(Value, Ff, Fg, x => f(Fh(x)));\n\n    public override IO<E> BindAsync<E>(Func<D, ValueTask<K<IO, E>>> f) => \n        new IOBindMap2<A, B, C, E>(Value, Ff, Fg, x => IO.pureVAsync(f(Fh(x))).Bind(v => v));\n\n    public override IO<D> Invoke(EnvIO envIO) =>\n        Ff(Value).As().Map(Fg).Map(Fh);\n    \n    public override string ToString() => \n        \"IO bind map\";\n}\n\nrecord IOBindMap2<A, B, C, D>(A Value, Func<A, K<IO, B>> Ff, Func<B, C> Fg, Func<C, K<IO, D>> Fh) : InvokeSyncIO<D>\n{\n    public override IO<E> Map<E>(Func<D, E> f) =>\n        new IOBindMap2<A, B, C, E>(Value, Ff, Fg, x => Fh(x).Map(f));\n\n    public override IO<E> Bind<E>(Func<D, K<IO, E>> f) =>\n        new IOBindMap2<A, B, C, E>(Value, Ff, Fg, x => Fh(x).As().Bind(f));\n\n    public override IO<E> BindAsync<E>(Func<D, ValueTask<K<IO, E>>> f) => \n        new IOBindMap2<A, B, C, E>(Value, Ff, Fg, x => Fh(x).As().BindAsync(f));\n\n    public override IO<D> Invoke(EnvIO envIO) =>\n        Ff(Value).As().Map(Fg).Bind(Fh);\n    \n    public override string ToString() => \n        \"IO bind map\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOCatch.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.DSL;\n\n/// <summary>\n/// Base-type of the IOCatch〈X, A〉 DSL-type used by the `IO` monad.\n///\n/// Use this to extend the core `IO` exception catching functionality.   \n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record IOCatch<A> : IO<A>\n{\n    /// <summary>\n    /// Provide the `IO` computation to run inside the `try` block \n    /// </summary>\n    /// <returns>`IO` computation to run inside the `try` block</returns>\n    public abstract IO<A> MakeOperation();\n    \n    /// <summary>\n    /// Provide the handler that will accept an `Exception` if one is thrown. \n    /// </summary>\n    /// <returns>Function to handle exceptions that returns an `IO`</returns>\n    public abstract Func<Exception, IO<A>> MakeHandler();\n    \n    public override string ToString() => \n        \"IO catch\";\n}\n\nrecord IOCatch<X, A>(\n    K<IO, X> Operation,\n    Func<Error, bool> Predicate,\n    Func<Error, K<IO, X>> Failure,\n    K<IO, Unit>? Final,\n    Func<X, K<IO, A>> Next) : IOCatch<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) =>\n        new IOCatch<X, B>(Operation, Predicate, Failure, Final, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) =>\n        new IOCatch<X, B>(Operation, Predicate, Failure, Final, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOCatch<X, B>(Operation, Predicate, Failure, Final, x => Next(x).As().BindAsync(f));\n\n    public override Func<Exception, IO<A>> MakeHandler() =>\n        e =>\n        {\n            var err = Error.New(e);\n            return Predicate(err)\n                       ? Failure(e).Bind(Next).As()\n                       : IO.fail<A>(err);\n        };\n\n    public override IO<A> MakeOperation() =>\n        Operation.Bind(x => new IOCatchPop<X>(IO.pure(x))).Bind(Next).As();\n    \n    public override string ToString() => \n        \"IO catch\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOCatchPop.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOCatchPop<A>(IO<A> Next) : IO<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) =>\n        new IOCatchPop<B>(Next.Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) =>\n        new IOCatchPop<B>(Next.Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOCatchPop<B>(Next.BindAsync(f));\n\n    public override string ToString() => \n        \"IO catch pop\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOEmpty.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.DSL;\n\nrecord IOEmpty<A> : InvokeSync<A>\n{\n    internal static readonly IO<A> Default = new IOEmpty<A>();\n\n    public override A Invoke(EnvIO envIO) => \n        throw Errors.None;\n    \n    public override IO<B> Map<B>(Func<A, B> f) => \n        IOEmpty<B>.Default;\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        IOEmpty<B>.Default;\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        IOEmpty<B>.Default;\n\n    public override IO<B> ApplyBack<B>(K<IO, Func<A, B>> f)=>\n        new IOEmptyAsync<Func<A, B>, B>(f);\n    \n    public override IO<S> Fold<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> Fold<S>(\n        S initialState,\n        Func<S, A, S> folder) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<A> Post() =>\n        Default;\n\n    protected override IO<A> WithEnv(Func<EnvIO, EnvIO> f) => \n        Default;\n\n    protected override IO<A> WithEnvFail(Func<EnvIO, EnvIO> f) => \n        Default;\n    \n    public override IO<ForkIO<A>> Fork(Option<TimeSpan> timeout = default) =>\n        IOEmpty<ForkIO<A>>.Default;\n\n    public override IO<A> RepeatUntil(Schedule schedule, Func<A, bool> predicate) => \n        Default;\n\n    public override IO<A> RetryUntil(Schedule schedule, Func<Error, bool> predicate) => \n        Default;\n\n    public override IO<A> Finally<X>(K<IO, X> @finally) => \n        Default;\n\n    public override IO<A> Catch(Func<Error, bool> Predicate, Func<Error, K<IO, A>> Fail) =>\n        Default;\n}\n\nrecord IOEmptyAsync<X, A>(K<IO, X> RunFirst) : InvokeAsync<A>\n{\n    public override async ValueTask<A> Invoke(EnvIO envIO)\n    {\n        ignore(await RunFirst.RunAsync(envIO));\n        throw Errors.None;\n    }\n    \n    public override IO<B> Map<B>(Func<A, B> f) => \n        IOEmpty<B>.Default;\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        IOEmpty<B>.Default;\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        IOEmpty<B>.Default;\n\n    public override IO<B> ApplyBack<B>(K<IO, Func<A, B>> f)=>\n        new IOEmptyAsync<Func<A, B>, B>(f);\n    \n    public override IO<S> Fold<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> Fold<S>(\n        S initialState,\n        Func<S, A, S> folder) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        IOEmpty<S>.Default;\n\n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        IOEmpty<S>.Default;\n    \n    public override IO<A> Post() =>\n        IOEmpty<A>.Default;\n\n    protected override IO<A> WithEnv(Func<EnvIO, EnvIO> f) => \n        IOEmpty<A>.Default;\n\n    protected override IO<A> WithEnvFail(Func<EnvIO, EnvIO> f) => \n        IOEmpty<A>.Default;\n    \n    public override IO<ForkIO<A>> Fork(Option<TimeSpan> timeout = default) =>\n        IOEmpty<ForkIO<A>>.Default;\n\n    public override IO<A> RepeatUntil(Schedule schedule, Func<A, bool> predicate) => \n        IOEmpty<A>.Default;\n\n    public override IO<A> RetryUntil(Schedule schedule, Func<Error, bool> predicate) => \n        IOEmpty<A>.Default;\n\n    public override IO<A> Finally<F>(K<IO, F> @finally) => \n        IOEmpty<A>.Default;\n\n    public override IO<A> Catch(Func<Error, bool> Predicate, Func<Error, K<IO, A>> Fail) =>\n        IOEmpty<A>.Default;    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOFail.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOFail<A>(Error Value) : InvokeSync<A>\n{\n    public override A Invoke(EnvIO envIO) => \n        Value.Throw<A>();\n    \n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOFail<B>(Value);\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOFail<B>(Value);\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOFail<B>(Value);\n\n    public override IO<S> Fold<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder) =>\n        new IOFail<S>(Value);\n\n    public override IO<S> Fold<S>(\n        S initialState,\n        Func<S, A, S> folder) =>\n        new IOFail<S>(Value);\n\n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        new IOFail<S>(Value);\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        new IOFail<S>(Value);\n    \n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        new IOFail<S>(Value);\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        new IOFail<S>(Value);\n    \n    public override IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        new IOFail<S>(Value);\n\n    public override IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        new IOFail<S>(Value);\n\n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        new IOFail<S>(Value);\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        new IOFail<S>(Value);\n    \n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        new IOFail<S>(Value);\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        new IOFail<S>(Value);\n    \n    public override IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        new IOFail<S>(Value);\n\n    public override IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        new IOFail<S>(Value);\n    \n    public override IO<A> Post() =>\n        this;\n\n    protected override IO<A> WithEnv(Func<EnvIO, EnvIO> f) => \n        this;\n\n    protected override IO<A> WithEnvFail(Func<EnvIO, EnvIO> f) => \n        this;\n    \n    public override IO<ForkIO<A>> Fork(Option<TimeSpan> timeout = default) =>\n        new IOFail<ForkIO<A>>(Value);\n\n    public override IO<A> RepeatUntil(Schedule schedule, Func<A, bool> predicate) => \n        this;\n\n    public override IO<A> RetryUntil(Schedule schedule, Func<Error, bool> predicate) => \n        this;\n\n    public override IO<A> Finally<X>(K<IO, X> @finally) => \n        this;\n\n    public override IO<A> Catch(Func<Error, bool> Predicate, Func<Error, K<IO, A>> Fail) =>\n        Fail(Value).As();\n    \n    public override string ToString() => \n        $\"fail({Value})\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOFinal.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOFinal<X, A, B>(K<IO, A> Fa, K<IO, X> Final, Func<A, K<IO, B>> Next) : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFinal<X,A,C>(Fa, Final, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFinal<X,A,C>(Fa, Final, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) =>\n        new IOFinal<X, A, C>(Fa, Final, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        var finalShouldRun = true;\n        try\n        {\n            var task = Fa.RunAsync(envIO);\n            finalShouldRun = false;\n            if (task.IsCompleted)\n            {\n                return Final.As().Bind(_ => Next(task.Result));\n            }\n            else\n            {\n                return new IOFinalAsync<X, A, B>(task, Final, Next);\n            }\n        }\n        finally\n        {\n            if(finalShouldRun) Final.As().Run(envIO);\n        }\n    }\n    \n    public override string ToString() => \n        \"IO final\";\n}\n\nrecord IOFinalAsync<X, A, B>(ValueTask<A> Fa, K<IO, X> Final, Func<A, K<IO, B>> Next) : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFinalAsync<X, A, C>(Fa, Final, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFinalAsync<X, A, C>(Fa, Final, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFinalAsync<X, A, C>(Fa, Final, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO)\n    {\n        try\n        {\n            var value = await Fa;\n            return Next(value).As();\n        }\n        finally\n        {\n            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed\n            await Final.RunAsync(envIO);\n        }\n    }\n    \n    public override string ToString() => \n        \"IO final async\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOFold.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.DSL;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOFold<S, A, B>(\n    IO<A> Operation,\n    Schedule Schedule,\n    S InitialState,\n    Func<S, A, S> Folder,\n    Func<S, K<IO, B>> Next)\n    : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) =>\n        new IOFold<S, A, C>(Operation, Schedule, InitialState, Folder, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFold<S, A, C>(Operation, Schedule, InitialState, Folder, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFold<S, A, C>(Operation, Schedule, InitialState, Folder, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        var task = Operation.RunAsync(envIO);\n        if (task.IsCompleted)\n        {\n            var value = task.Result;\n            var state = Folder(InitialState, value);\n            return new IOFoldingSync<S, A, B>(Operation, Schedule.Run().GetEnumerator(), state, Folder, Next);\n        }\n        else\n        {\n            return new IOFoldingInitialAsync<S, A, B>(\n                task, \n                Operation, \n                Schedule.Run().GetEnumerator(), InitialState, Folder, Next);\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold\";\n}\n\nrecord IOFoldingInitialAsync<S, A, B>(\n    ValueTask<A> First,\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<S, K<IO, B>> Next)\n    : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFoldingInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) \n    {\n        var value = await First;\n        var state = Folder(State, value);\n            \n        if (Schedule.MoveNext())\n        {\n            await Task.Delay((TimeSpan)Schedule.Current, envIO.Token);\n            value = await Operation.RunAsync(envIO);\n            state = Folder(State, value);\n            return new IOFoldingAsync<S, A, B>(Operation, Schedule, state, Folder, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO folding initial async\";\n}\n\nrecord IOFoldingAsync<S, A, B>(\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<S, K<IO, B>> Next)\n    : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFoldingAsync<S, A, C>(Operation, Schedule, State, Folder, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingAsync<S, A, C>(Operation, Schedule, State, Folder, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingAsync<S, A, C>(Operation, Schedule, State, Folder, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) \n    {\n        if (Schedule.MoveNext())\n        {\n            await Task.Delay((TimeSpan)Schedule.Current, envIO.Token);\n            var value = await Operation.RunAsync(envIO);\n            var state = Folder(State, value);\n            return new IOFoldingAsync<S, A, B>(Operation, Schedule, state, Folder, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO folding async\";\n}\n\nrecord IOFoldingSync<S, A, B>(\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<S, K<IO, B>> Next)\n    : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFoldingSync<S, A, C>(Operation, Schedule, State, Folder, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingSync<S, A, C>(Operation, Schedule, State, Folder, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingSync<S, A, C>(Operation, Schedule, State, Folder, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO) \n    {\n        if (Schedule.MoveNext())\n        {\n            Task.Delay((TimeSpan)Schedule.Current, envIO.Token).GetAwaiter().GetResult();\n            var value = Operation.Run(envIO);\n            var state = Folder(State, value);\n            return new IOFoldingSync<S, A, B>(Operation, Schedule, state, Folder, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO folding sync\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOFoldUntil.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.DSL;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOFoldUntil<S, A, B>(\n    IO<A> Operation,\n    Schedule Schedule,\n    S InitialState,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Predicate,\n    Func<S, K<IO, B>> Next) : \n    InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) =>\n        new IOFoldUntil<S, A, C>(Operation, Schedule, InitialState, Folder, Predicate, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldUntil<S, A, C>(Operation, Schedule, InitialState, Folder, Predicate, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldUntil<S, A, C>(Operation, Schedule, InitialState, Folder, Predicate, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        var task = Operation.RunAsync(envIO);\n        if (task.IsCompleted)\n        {\n            var value = task.Result;\n            var state = Folder(InitialState, value);\n            return Predicate((state, value))\n                       ? Next(state).As()\n                       : new IOFoldingUntilSync<S, A, B>(Operation, Schedule.Run().GetEnumerator(), state, Folder, Predicate, Next);\n        }\n        else\n        {\n            return new IOFoldingUntilInitialAsync<S, A, B>(\n                task, \n                Operation, \n                Schedule.Run().GetEnumerator(), InitialState, Folder, Predicate, Next);\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold until\";\n}\n\nrecord IOFoldingUntilInitialAsync<S, A, B>(\n    ValueTask<A> First,\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Predicate,\n    Func<S, K<IO, B>> Next) : \n    InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) =>\n        new IOFoldingUntilInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, Predicate, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingUntilInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, Predicate, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingUntilInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, Predicate, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) \n    {\n        var value = await First;\n        var state = Folder(State, value);\n        if (Predicate((state, value)))\n        {\n            return Next(state).As();\n        }\n            \n        if (Schedule.MoveNext())\n        {\n            await Task.Delay((TimeSpan)Schedule.Current, envIO.Token);\n            value = await Operation.RunAsync(envIO);\n            state = Folder(State, value);\n            return Predicate((state, value))\n                       ? Next(state).As()\n                       : new IOFoldingUntilAsync<S, A, B>(Operation, Schedule, state, Folder, Predicate, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold until initial async\";\n}\n\nrecord IOFoldingUntilAsync<S, A, B>(\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Predicate,\n    Func<S, K<IO, B>> Next) : \n    InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFoldingUntilAsync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingUntilAsync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingUntilAsync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) \n    {\n        if (Schedule.MoveNext())\n        {\n            await Task.Delay((TimeSpan)Schedule.Current, envIO.Token);\n            var value = await Operation.RunAsync(envIO);\n            var state = Folder(State, value);\n            return Predicate((state, value))\n                       ? Next(state).As()\n                       : new IOFoldingUntilAsync<S, A, B>(Operation, Schedule, state, Folder, Predicate, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold until async\";\n}\n\nrecord IOFoldingUntilSync<S, A, B>(\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Predicate,\n    Func<S, K<IO, B>> Next) : \n    InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFoldingUntilSync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingUntilSync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingUntilSync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO) \n    {\n        if (Schedule.MoveNext())\n        {\n            Task.Delay((TimeSpan)Schedule.Current, envIO.Token).GetAwaiter().GetResult();\n            var value = Operation.Run(envIO);\n            var state = Folder(State, value);\n            return Predicate((state, value))\n                       ? Next(state).As()\n                       : new IOFoldingUntilSync<S, A, B>(Operation, Schedule, state, Folder, Predicate, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold until sync\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOFoldWhile.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.DSL;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOFoldWhile<S, A, B>(\n    IO<A> Operation,\n    Schedule Schedule,\n    S InitialState,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Predicate,\n    Func<S, K<IO, B>> Next) : \n    InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) =>\n        new IOFoldWhile<S, A, C>(Operation, Schedule, InitialState, Folder, Predicate, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldWhile<S, A, C>(Operation, Schedule, InitialState, Folder, Predicate, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldWhile<S, A, C>(Operation, Schedule, InitialState, Folder, Predicate, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        var task = Operation.RunAsync(envIO);\n        if (task.IsCompleted)\n        {\n            var value = task.Result;\n            if (!Predicate((InitialState, value)))\n            {\n                return Next(InitialState).As();\n            }\n            var state = Folder(InitialState, value);\n            \n            return new IOFoldingWhileSync<S, A, B>(Operation, Schedule.Run().GetEnumerator(), state, Folder, Predicate, Next);\n        }\n        else\n        {\n            return new IOFoldingWhileInitialAsync<S, A, B>(\n                task, \n                Operation, \n                Schedule.Run().GetEnumerator(), InitialState, Folder, Predicate, Next);\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold while\";\n}\n\nrecord IOFoldingWhileInitialAsync<S, A, B>(\n    ValueTask<A> First,\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Predicate,\n    Func<S, K<IO, B>> Next) : \n    InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) =>\n        new IOFoldingWhileInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, Predicate, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingWhileInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, Predicate, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingWhileInitialAsync<S, A, C>(First, Operation, Schedule, State, Folder, Predicate, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) \n    {\n        var value = await First;\n        var state = State;\n        if (!Predicate((state, value)))\n        {\n            return Next(state).As();\n        }\n        state = Folder(State, value);\n            \n        if (Schedule.MoveNext())\n        {\n            await Task.Delay((TimeSpan)Schedule.Current, envIO.Token);\n            value = await Operation.RunAsync(envIO);\n            if (!Predicate((state, value)))\n            {\n                return Next(State).As();\n            }\n            state = Folder(State, value);\n            return new IOFoldingWhileAsync<S, A, B>(Operation, Schedule, state, Folder, Predicate, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold while initial async\";\n}\n\nrecord IOFoldingWhileAsync<S, A, B>(\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Predicate,\n    Func<S, K<IO, B>> Next)\n    : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFoldingWhileAsync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingWhileAsync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingWhileAsync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) \n    {\n        if (Schedule.MoveNext())\n        {\n            await Task.Delay((TimeSpan)Schedule.Current, envIO.Token);\n            var value = await Operation.RunAsync(envIO);\n            var state = State;\n            if (!Predicate((state, value)))\n            {\n                return Next(State).As();\n            }\n            state = Folder(State, value);\n            return new IOFoldingWhileAsync<S, A, B>(Operation, Schedule, state, Folder, Predicate, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold while async\";\n}\n\nrecord IOFoldingWhileSync<S, A, B>(\n    IO<A> Operation,\n    IEnumerator<Duration> Schedule,\n    S State,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Predicate,\n    Func<S, K<IO, B>> Next) : \n    InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOFoldingWhileSync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOFoldingWhileSync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOFoldingWhileSync<S, A, C>(Operation, Schedule, State, Folder, Predicate, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO) \n    {\n        if (Schedule.MoveNext())\n        {\n            Task.Delay((TimeSpan)Schedule.Current, envIO.Token).GetAwaiter().GetResult();\n            var value = Operation.Run(envIO);\n            var state = State;\n            if (!Predicate((state, value)))\n            {\n                return Next(State).As();\n            }\n            state = Folder(State, value);\n            return new IOFoldingWhileSync<S, A, B>(Operation, Schedule, state, Folder, Predicate, Next);\n        }\n        else\n        {\n            return Next(State).As();\n        }\n    }\n    \n    public override string ToString() => \n        \"IO fold while sync\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOLiftAsync.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n    \nrecord IOLiftAsync<A, B>(Func<EnvIO, Task<A>> F, Func<A, K<IO, B>> Next) : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOLiftAsync<A, C>(F, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOLiftAsync<A, C>(F, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOLiftAsync<A, C>(F, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) =>\n        Next(await F(envIO)).As();\n    \n    public override string ToString() => \n        \"IO lift async\";\n}\n    \nrecord IOLiftVAsync<A, B>(Func<EnvIO, ValueTask<A>> F, Func<A, K<IO, B>> Next) : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOLiftVAsync<A, C>(F, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOLiftVAsync<A, C>(F, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOLiftVAsync<A, C>(F, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO) =>\n        Next(await F(envIO)).As();\n    \n    public override string ToString() => \n        \"IO lift vasync\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOLiftSync.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOLiftSync<A, B>(Func<EnvIO, A> F, Func<A, K<IO, B>> Next) : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOLiftSync<A, C>(F, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOLiftSync<A, C>(F, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOLiftSync<A, C>(F, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO) =>\n        Next(F(envIO)).As();\n    \n    public override string ToString() => \n        \"IO lift sync\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOLocal2.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOLocal<X, A>(Func<EnvIO, EnvIO> MapEnvIO, K<IO, X> Operation, Func<X, K<IO, A>> Next) : InvokeAsyncIO<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOLocal<X, B>(MapEnvIO, Operation, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOLocal<X, B>(MapEnvIO, Operation, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOLocal<X, B>(MapEnvIO, Operation, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<A>> Invoke(EnvIO envIO)\n    {\n        using var local = MapEnvIO(envIO);\n        return +Next(await Operation.RunAsync(local));\n    }\n\n    public override string ToString() => \n        \"IO local\";\n}\n\nrecord IOLocalOnFailOnly<X, A>(Func<EnvIO, EnvIO> MapEnvIO, K<IO, X> Operation, Func<X, K<IO, A>> Next) : InvokeAsyncIO<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOLocalOnFailOnly<X, B>(MapEnvIO, Operation, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOLocalOnFailOnly<X, B>(MapEnvIO, Operation, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOLocalOnFailOnly<X, B>(MapEnvIO, Operation, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<A>> Invoke(EnvIO envIO)\n    {\n        var local = MapEnvIO(envIO);\n        try\n        {\n            return +Next(await Operation.RunAsync(local));\n        }\n        catch\n        {\n            local.DisposeResources();\n            throw;\n        }\n        finally\n        {\n            local.DisposeNonResources();\n        }\n    }\n\n    public override string ToString() => \n        \"IO local\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOMap.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOMap<A, B, C>(Func<A, B> Ff, IO<A> Fa, Func<B, K<IO, C>> Next) : InvokeSyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) => \n        new IOMap<A, B, D>(Ff, Fa, x => Next(x).Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOMap<A, B, D>(Ff, Fa, x => Next(x).Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOMap<A, B, D>(Ff, Fa, x => Next(x).As().BindAsync(f));\n\n    public override IO<C> Invoke(EnvIO envIO)\n    {\n        var task = Fa.RunAsync(envIO);\n        return task.IsCompleted\n                   ? Next(Ff(task.Result)).As()\n                   : new IOPureMapAsync<A, B, C>(Ff, task, Next);\n    }\n    \n    public override string ToString() => \n        \"IO map\";\n}\n\nrecord IOPureMap<A, B, C>(Func<A, B> Ff, A Fa, Func<B, K<IO, C>> Next) : InvokeSyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) => \n        new IOPureMap<A, B, D>(Ff, Fa, x => Next(x).Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOPureMap<A, B, D>(Ff, Fa, x => Next(x).Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOPureMap<A, B, D>(Ff, Fa, x => Next(x).As().BindAsync(f));\n\n    public override IO<C> Invoke(EnvIO envIO) =>\n        Next(Ff(Fa)).As();\n    \n    public override string ToString() => \n        \"IO pure map\";\n}\n\nrecord IOPureMapAsync<A, B, C>(Func<A, B> Ff, ValueTask<A> Fa, Func<B, K<IO, C>> Next) : InvokeAsyncIO<C>\n{\n    public override IO<D> Map<D>(Func<C, D> f) => \n        new IOPureMapAsync<A, B, D>(Ff, Fa, x => Next(x).As().Map(f));\n\n    public override IO<D> Bind<D>(Func<C, K<IO, D>> f) => \n        new IOPureMapAsync<A, B, D>(Ff, Fa, x => Next(x).As().Bind(f));\n\n    public override IO<D> BindAsync<D>(Func<C, ValueTask<K<IO, D>>> f) => \n        new IOPureMapAsync<A, B, D>(Ff, Fa, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<C>> Invoke(EnvIO envIO) =>\n        Next(Ff(await Fa)).As();\n    \n    public override string ToString() => \n        \"IO pure map async\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOPure.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOPure<A>(A Value) : InvokeSync<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) =>\n        new IOPureMap<A, B, B>(f, Value, IO.pure);\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) =>\n        new IOBind<A, B>(Value, f);\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOBindAsync2<A, B>(new ValueTask<A>(Value), f);\n\n    public override A Invoke(EnvIO envIO) => \n        Value;\n    \n    public override string ToString() => \n        $\"pure({Value})\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOPureAsync.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOPureAsync<A>(ValueTask<A> Value) : InvokeAsync<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) =>\n        new IOPureMapAsync<A, B, B>(f, Value, IO.pure);\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) =>\n        new IOBindAsync<A, B>(Value, f);\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOBindAsync2<A, B>(Value, f);\n\n    public override async ValueTask<A> Invoke(EnvIO envIO) => \n        await Value;\n    \n    public override string ToString() => \n        \"IO pure async\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOTail.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOTail<A>(IO<A> Tail) : IO<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        throw new NotSupportedException(\"You can't map a tail call\");\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) =>\n        throw new NotSupportedException(\"You can't chain a tail call\");\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        throw new NotSupportedException(\"You can't chain a tail call\");\n\n    public override string ToString() => \n        \"IO tail\";\n\n    public static IO<C> resolve<B, C>(A initialValue, IO<B> bindResult, Func<A, B, C> project)\n        => bindResult switch\n           {\n               IOTail<B> tail when typeof(B) == typeof(C) => (IO<C>)(object)tail.Tail,\n               IOTail<B> => throw new NotSupportedException(\"Tail calls can't transform in the `select`\"),\n               var mb => mb.Map(y => project(initialValue, y))\n           };\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOTimeout.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\nnamespace LanguageExt.DSL;\n\nrecord IOTimeout<A, B>(IO<A> Fa, TimeSpan TimeLimit, Func<A, K<IO, B>> Next) : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOTimeout<A, C>(Fa, TimeLimit, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOTimeout<A, C>(Fa, TimeLimit, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOTimeout<A, C>(Fa, TimeLimit, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        using var localEnv = envIO.LocalCancelWithTimeout(TimeLimit);\n        var       r        = Fa.Run(localEnv);\n        return +Next(r);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOToken.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOToken<A>(Func<CancellationToken, IO<A>> Next) :  InvokeSyncIO<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOTokenMap<A, B>(Next, f);\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOTokenBind<A, B>(Next, f);\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOTokenBindAsync<A, B>(Next, f);\n\n    public override IO<A> Invoke(EnvIO envIO) =>\n        Next(envIO.Token);\n}\n\nrecord IOTokenMap<A, B>(Func<CancellationToken, IO<A>> Next, Func<A, B> F) :  InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOTokenMap<A, C>(Next, x => f(F(x)));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOTokenBind<A, C>(Next, x => f(F(x)));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOTokenBindAsync<A, C>(Next, async x => await f(F(x)));\n\n    public override IO<B> Invoke(EnvIO envIO) =>\n        Next(envIO.Token).Map(F);\n}\n\nrecord IOTokenBind<A, B>(Func<CancellationToken, IO<A>> Next, Func<A, K<IO, B>> F) :  InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOTokenBind<A, C>(Next, x => F(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOTokenBind<A, C>(Next, x => F(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOTokenBind<A, C>(Next, x => F(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO) =>\n        Next(envIO.Token).Bind(F);\n}\n\nrecord IOTokenBindAsync<A, B>(Func<CancellationToken, IO<A>> Next, Func<A, ValueTask<K<IO, B>>> F) :  InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOTokenBindAsync<A, C>(Next, async x => (await F(x)).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOTokenBindAsync<A, C>(Next, async x => (await F(x)).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOTokenBindAsync<A, C>(Next, async x => (await F(x)).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO) =>\n        Next(envIO.Token).BindAsync(F);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOUninterruptible.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\nnamespace LanguageExt.DSL;\n\nrecord IOUninterruptible<A, B>(IO<A> Fa, Func<A, K<IO, B>> Next) : InvokeSyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOUninterruptible<A, C>(Fa, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOUninterruptible<A, C>(Fa, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOUninterruptible<A, C>(Fa, x => Next(x).As().BindAsync(f));\n\n    public override IO<B> Invoke(EnvIO envIO)\n    {\n        var localEnv = EnvIO.New(envIO.Resources, CancellationToken.None, null, envIO.SyncContext);\n        var tr = Fa.RunAsync(localEnv);\n        return tr.IsCompleted\n                   ? +Next(tr.Result)\n                   : new IOUninterruptibleAsync<A, B>(tr, localEnv, Next);\n    }\n}\n\nrecord IOUninterruptibleAsync<A, B>(ValueTask<A> Fa, EnvIO LocalEnv, Func<A, K<IO, B>> Next) : InvokeAsyncIO<B>\n{\n    public override IO<C> Map<C>(Func<B, C> f) => \n        new IOUninterruptibleAsync<A, C>(Fa, LocalEnv, x => Next(x).Map(f));\n\n    public override IO<C> Bind<C>(Func<B, K<IO, C>> f) => \n        new IOUninterruptibleAsync<A, C>(Fa, LocalEnv, x => Next(x).Bind(f));\n\n    public override IO<C> BindAsync<C>(Func<B, ValueTask<K<IO, C>>> f) => \n        new IOUninterruptibleAsync<A, C>(Fa, LocalEnv, x => Next(x).As().BindAsync(f));\n\n    public override async ValueTask<IO<B>> Invoke(EnvIO envIO)\n    {\n        var r = await Fa;\n        LocalEnv.Dispose();\n        return +Next(r);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/IOUse.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.DSL;\n\nrecord IOUse<X, A>(IO<X> Acquire, Func<X, IO<Unit>> Release, Func<X, IO<A>> Next) : InvokeSyncIO<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOUse<X, B>(Acquire, Release, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOUse<X, B>(Acquire, Release, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOUse<X, B>(Acquire, Release, x => Next(x).BindAsync(f));\n\n    public override IO<A> Invoke(EnvIO envIO)\n    {\n        var task = Acquire.RunAsync(envIO);\n        if (task.IsCompleted)\n        {\n            envIO.Resources.Acquire(task.Result, Release);\n            return Next(task.Result);\n        }\n        else\n        {\n            return new IOAcquireAsync<X, A>(task, Release, Next);\n        }\n    }\n    \n    public override string ToString() => \n        \"IO use\";\n}\n\nrecord IOUseDisposable<X, A>(IO<X> Acquire, Func<X, IO<A>> Next) : InvokeSyncIO<A>\n    where X : IDisposable\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOUseDisposable<X, B>(Acquire, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOUseDisposable<X, B>(Acquire, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOUseDisposable<X, B>(Acquire, x => Next(x).BindAsync(f));\n\n    public override IO<A> Invoke(EnvIO envIO)\n    {\n        var task = Acquire.RunAsync(envIO);\n        if (task.IsCompleted)\n        {\n            envIO.Resources.Acquire(task.Result);\n            return Next(task.Result);\n        }\n        else\n        {\n            return new IOAcquireDisposableAsync<X, A>(task, Next);\n        }\n    }\n    \n    public override string ToString() => \n        \"IO use disposable\";\n}\n\nrecord IOUseAsyncDisposable<X, A>(IO<X> Acquire, Func<X, IO<A>> Next) : InvokeSyncIO<A>\n    where X : IAsyncDisposable\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOUseAsyncDisposable<X, B>(Acquire, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOUseAsyncDisposable<X, B>(Acquire, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOUseAsyncDisposable<X, B>(Acquire, x => Next(x).BindAsync(f));\n\n    public override IO<A> Invoke(EnvIO envIO)\n    {\n        var task = Acquire.RunAsync(envIO);\n        if (task.IsCompleted)\n        {\n            envIO.Resources.AcquireAsync(task.Result);\n            return Next(task.Result);\n        }\n        else\n        {\n            return new IOAcquireAsyncDisposableAsync<X, A>(task, Next);\n        }\n    }\n    \n    public override string ToString() => \n        \"IO pure async disposable\";\n}\n\nrecord IOAcquireAsync<X, A>(ValueTask<X> Value, Func<X, IO<Unit>> Release, Func<X, IO<A>> Next) : InvokeAsyncIO<A>\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOAcquireAsync<X, B>(Value, Release, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOAcquireAsync<X, B>(Value, Release, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOAcquireAsync<X, B>(Value, Release, x => Next(x).BindAsync(f));\n\n    public override async ValueTask<IO<A>> Invoke(EnvIO envIO)\n    {\n        var value = await Value;\n        envIO.Resources.Acquire(value, Release);\n        return Next(value);\n    }\n    \n    public override string ToString() => \n        \"IO acquire async\";\n}\n\nrecord IOAcquireDisposableAsync<X, A>(ValueTask<X> Value, Func<X, IO<A>> Next) : InvokeAsyncIO<A>\n    where X : IDisposable\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOAcquireDisposableAsync<X, B>(Value, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOAcquireDisposableAsync<X, B>(Value, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOAcquireDisposableAsync<X, B>(Value, x => Next(x).BindAsync(f));\n\n    public override async ValueTask<IO<A>> Invoke(EnvIO envIO)\n    {\n        var value = await Value;\n        envIO.Resources.Acquire(value);\n        return Next(value);\n    }\n    \n    public override string ToString() => \n        \"IO acquire disposable async\";\n}\n\nrecord IOAcquireAsyncDisposableAsync<X, A>(ValueTask<X> Value, Func<X, IO<A>> Next) : InvokeAsyncIO<A>\n    where X : IAsyncDisposable\n{\n    public override IO<B> Map<B>(Func<A, B> f) => \n        new IOAcquireAsyncDisposableAsync<X, B>(Value, x => Next(x).Map(f));\n\n    public override IO<B> Bind<B>(Func<A, K<IO, B>> f) => \n        new IOAcquireAsyncDisposableAsync<X, B>(Value, x => Next(x).Bind(f));\n\n    public override IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f) => \n        new IOAcquireAsyncDisposableAsync<X, B>(Value, x => Next(x).BindAsync(f));\n\n    public override async ValueTask<IO<A>> Invoke(EnvIO envIO)\n    {\n        var value = await Value;\n        envIO.Resources.AcquireAsync(value);\n        return Next(value);\n    }\n    \n    public override string ToString() => \n        \"IO acquire async disposable async\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/InvokeAsync.cs",
    "content": "using System.Threading.Tasks;\n\nnamespace LanguageExt.DSL;\n\n/// <summary>\n/// Base-type of the DSL types used by the `IO` monad.  Use this to extend the core `IO` functionality.   \n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record InvokeAsync<A> : IO<A>\n{\n    public abstract ValueTask<A> Invoke(EnvIO envIO);\n    \n    public override string ToString() => \n        \"IO invoke async\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/InvokeAsyncIO.cs",
    "content": "using System.Threading.Tasks;\n\nnamespace LanguageExt.DSL;\n\n/// <summary>\n/// Base-type of the DSL types used by the `IO` monad.  Use this to extend the core `IO` functionality.   \n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record InvokeAsyncIO<A> : IO<A>\n{\n    public abstract ValueTask<IO<A>> Invoke(EnvIO envIO);\n    \n    public override string ToString() => \n        \"IO invoke async\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/InvokeSync.cs",
    "content": "namespace LanguageExt.DSL;\n\n/// <summary>\n/// Base-type of the DSL types used by the `IO` monad.  Use this to extend the core `IO` functionality.   \n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record InvokeSync<A> : IO<A>\n{\n    public abstract A Invoke(EnvIO envIO);\n    \n    public override string ToString() => \n        \"IO invoke sync\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/DSL/InvokeSyncIO.cs",
    "content": "namespace LanguageExt.DSL;\n\n/// <summary>\n/// Base-type of the DSL types used by the `IO` monad.  Use this to extend the core `IO` functionality.   \n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record InvokeSyncIO<A> : IO<A>\n{\n    public abstract IO<A> Invoke(EnvIO envIO);\n    \n    public override string ToString() => \n        \"IO invoke sync\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/EnvIO.cs",
    "content": "using System;\nusing System.Threading;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Environment for the IO monad \n/// </summary>\npublic class EnvIO : IDisposable\n{\n    public readonly Resources Resources;\n    public readonly CancellationToken Token;\n    public readonly CancellationTokenSource Source;\n    public readonly SynchronizationContext? SyncContext;\n    readonly CancellationTokenRegistration? Registration;\n    readonly int Own;\n    int resourcesDisposed;\n    int nonResourcesDisposed;\n\n    static readonly EnvIO DisposeEnv = new(\n        new Resources(null), \n        CancellationToken.None, \n        new CancellationTokenSource(), \n        null, \n        null, \n        0);\n    \n    internal EnvIO(Resources resources,\n          CancellationToken token,\n          CancellationTokenSource source,\n          SynchronizationContext? syncContext,\n          CancellationTokenRegistration? registration,\n          int own)\n    {\n        Resources            = resources;\n        Token                = token;\n        Source               = source;\n        SyncContext          = syncContext;\n        Registration         = registration;\n        Own                  = own;\n        resourcesDisposed    = 0;\n        nonResourcesDisposed = 0;\n    }\n\n    public static EnvIO New(\n        Resources? resources = null,\n        CancellationToken token = default,\n        CancellationTokenSource? source = null,\n        SynchronizationContext? syncContext = null,\n        TimeSpan? timeout = null)\n    {\n        var own = 0;\n        CancellationTokenRegistration? reg = null; \n        if (source is null)\n        {\n            source = timeout is null \n                         ? new CancellationTokenSource() \n                         : new CancellationTokenSource(timeout.Value);\n            own |= 1;\n        }\n\n        if (resources is null)\n        {\n            resources = new Resources(null);\n            own |= 2;\n        }\n\n        if ((own & 1) == 1)\n        {\n            if (token.CanBeCanceled)\n            {\n                reg = token.Register(() => source.Cancel());\n            }\n\n            token = source.Token;\n        }\n\n        syncContext ??= SynchronizationContext.Current;\n        return new EnvIO(resources, token, source, syncContext, reg, own);\n    }\n\n    public EnvIO Local =>\n        New(null, Token, null, SynchronizationContext.Current);\n\n    public EnvIO LocalWithTimeout(TimeSpan timeout) =>\n        New(null, Token, null, SynchronizationContext.Current, timeout);\n\n    public EnvIO LocalResources =>\n        New(null, Token, Source, SyncContext);\n\n    public EnvIO LocalCancel =>\n        New(Resources, Token, null, SyncContext);\n\n    public EnvIO LocalSyncContext =>\n        New(Resources, Token, Source, SynchronizationContext.Current);\n\n    public EnvIO LocalCancelWithTimeout(TimeSpan timeout) =>\n        New(Resources, Token, null, SyncContext, timeout);\n\n    public void Dispose()\n    {\n        DisposeResources();\n        DisposeNonResources();\n    }\n\n    public void DisposeResources()\n    {\n        if (Interlocked.CompareExchange(ref resourcesDisposed, 1, 0) == 0)\n        {\n            if ((Own & 2) == 2)\n            {\n                var env = New();\n                Resources.DisposeU(env);\n            }\n        }\n    }\n\n    public void DisposeNonResources()\n    {\n        if (Interlocked.CompareExchange(ref nonResourcesDisposed, 1, 0) == 0)\n        {\n            if ((Own & 1) == 1) Source.Dispose();\n            Registration?.Dispose();\n        }\n    }\n\n    public override string ToString() => \n        \"EnvIO\";\n}\n    \n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Extensions/IO.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static IO<B> Map<A, B>(this Func<A, B> f, K<IO, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static IO<B> Map<A, B>(this Func<A, B> f, IO<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static IO<B> Action<A, B>(this IO<A> ma, IO<B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static IO<B> Apply<A, B>(this IO<Func<A, B>> mf, K<IO, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static IO<B> Apply<A, B>(this K<IO, Func<A, B>> mf, K<IO, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Extensions/IO.Extensions.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.DSL;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    extension<A>(K<IO, A> ma)\n    {\n        /// <summary>\n        /// Convert the kind version of the `IO` monad to an `IO` monad.\n        /// </summary>\n        /// <remarks>\n        /// This is a simple cast operation which is just a bit more elegant\n        /// than manually casting.\n        /// </remarks>\n        /// <returns></returns>\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public IO<A> As() =>\n            (IO<A>)ma;\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public A Run() =>\n            ma.As().Run();\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public A Run(EnvIO envIO) =>\n            ma.As().Run(envIO);\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Fin<A> RunSafe() =>\n            ma.As().Try().Run().Run();\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Fin<A> RunSafe(EnvIO envIO) =>\n            ma.As().Try().Run().Run(envIO);\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public ValueTask<A> RunAsync() =>\n            ma.As().RunAsync();\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public ValueTask<A> RunAsync(EnvIO envIO) =>\n            ma.As().RunAsync(envIO);\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public ValueTask<Fin<A>> RunSafeAsync() =>\n            ma.As().Try().Run().RunAsync();\n\n        [Pure]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public ValueTask<Fin<A>> RunSafeAsync(EnvIO envIO) =>\n            ma.As().Try().Run().RunAsync(envIO);\n    }\n    \n    extension<M, A, B>(K<IO, A> ma) \n        where M : MonadIO<M>\n    {\n        public K<M, B> Bind(Func<A, K<M, B>> f) =>\n            M.LiftIO(ma).Bind(f);\n\n        public K<M, B> BindAsync(Func<A, ValueTask<K<M, B>>> f) => \n            ma.Bind(x => M.LiftIO(new IOPureAsync<K<M, B>>(f(x)))).Flatten();\n    }\n\n    /// <summary>\n    /// Get the outer task and wrap it up in a new IO within the IO\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<A> Flatten<A>(this Task<IO<A>> tma) =>\n        IO.liftAsync(async () => await tma.ConfigureAwait(false))\n          .Flatten();\n\n    /// <summary>\n    /// Unwrap the inner IO to flatten the structure\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<A> Flatten<A>(this IO<IO<A>> mma) =>\n        mma.Bind(x => x);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<C> SelectMany<A, B, C>(this K<IO, A> ma, Func<A, K<IO, B>> bind, Func<A, B, C> project) =>\n        ma.As().SelectMany(bind, project);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static OptionT<M, C> SelectMany<M, A, B, C>(this K<IO, A> ma, Func<A, OptionT<M, B>> bind, Func<A, B, C> project)\n        where M : MonadIO<M>, Alternative<M> =>\n        OptionT.liftIO<M, A>(ma.As()).SelectMany(bind, project);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static TryT<M, C> SelectMany<M, A, B, C>(this K<IO, A> ma, Func<A, TryT<M, B>> bind, Func<A, B, C> project)\n        where M : MonadIO<M>, Alternative<M> =>\n        TryT.liftIO<M, A>(ma.As()).SelectMany(bind, project);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static EitherT<L, M, C> SelectMany<L, M, A, B, C>(this K<IO, A> ma, Func<A, EitherT<L, M, B>> bind, Func<A, B, C> project)\n        where M : MonadIO<M>, Alternative<M> =>\n        EitherT.liftIO<L, M, A>(ma.As()).SelectMany(bind, project);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static FinT<M, C> SelectMany<M, A, B, C>(this K<IO, A> ma, Func<A, FinT<M, B>> bind, Func<A, B, C> project)\n        where M : MonadIO<M>, Alternative<M> =>\n        FinT.liftIO<M, A>(ma.As()).SelectMany(bind, project);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ValidationT<F, M, C> SelectMany<F, M, A, B, C>(this K<IO, A> ma, Func<A, ValidationT<F, M, B>> bind, Func<A, B, C> project)\n        where F : Monoid<F>\n        where M : MonadIO<M>, Alternative<M> =>\n        ValidationT.liftIO<F, M, A>(ma.As()).SelectMany(bind, project);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ReaderT<Env, M, C> SelectMany<Env, M, A, B, C>(this K<IO, A> ma, Func<A, ReaderT<Env, M, B>> bind, Func<A, B, C> project)\n        where M : MonadIO<M>, Alternative<M> =>\n        ReaderT<Env, M, A>.LiftIO(ma.As()).SelectMany(bind, project);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static StateT<S, M, C> SelectMany<S, M, A, B, C>(this K<IO, A> ma, Func<A, StateT<S, M, B>> bind, Func<A, B, C> project)\n        where M : MonadIO<M>, Alternative<M> =>\n        StateT<S, M, A>.LiftIO(ma.As()).SelectMany(bind, project);\n\n    /// <summary>\n    /// Wait for a signal\n    /// </summary>\n    public static IO<bool> WaitOneIO(this AutoResetEvent wait) =>\n        IO.liftAsync(e => wait.WaitOneAsync(e.Token));\n\n    /// <summary>\n    /// Wait for a signal\n    /// </summary>\n    public static K<M, bool> WaitOneIO<M>(this AutoResetEvent wait)\n        where M : Monad<M> =>\n        M.LiftIOMaybe(wait.WaitOneIO());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Extensions/IO.Guard.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class IOGuardExtensions\n{\n    extension(Guard<Error, Unit> guard)\n    {\n        /// <summary>\n        /// Monadic binding support for `IO`\n        /// </summary>\n        public IO<B> Bind<B>(Func<Unit, IO<B>> f) =>\n            guard.Flag \n                ? f(unit).As() \n                : Fail(guard.OnFalse());\n\n        /// <summary>\n        /// Monadic binding support for `IO`\n        /// </summary>\n        public IO<C> SelectMany<B, C>(Func<Unit, IO<B>> bind, \n                                      Func<Unit, B, C> project) =>\n            guard.Flag\n                ? bind(default).As().Map(b => project(default, b))\n                : Fail(guard.OnFalse());\n\n        /// <summary>\n        /// Natural transformation to `IO`\n        /// </summary>\n        public IO<Unit> ToIO() =>\n            IO.lift(() => guard.Flag\n                              ? unit\n                              : guard.OnFalse().Throw());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/ForkIO.cs",
    "content": "using System.Threading.Tasks;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Result of forking an `IO` monad\n/// </summary>\n/// <param name=\"Cancel\">An `IO` monad, which, if invoked, would cancel the forked IO operation</param>\n/// <param name=\"Await\">An `IO` monad, which, if invoked, would await the result of the forked\n/// `IO` operation.  Obviously, this mitigates the reasons for forking somewhat, but this struct\n/// could be passed to another process that does the awaiting - and so still has some value.</param>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic readonly record struct ForkIO<A>(\n    IO<Unit> Cancel, \n    IO<A> Await);\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/IO.Module.cs",
    "content": "using System;\nusing LanguageExt.DSL;\nusing System.Threading;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing System.Threading.Tasks;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic partial class IO\n{\n    /// <summary>\n    /// Lift a pure value into an IO computation\n    /// </summary>\n    /// <param name=\"value\">value</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IO in a success state.  Always yields the lifted value.</returns>\n    [Pure]\n    public static IO<A> pure<A>(A value) =>\n        new IOPure<A>(value);\n    \n    /// <summary>\n    /// Lift a pure value into an IO computation\n    /// </summary>\n    /// <param name=\"value\">value</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IO in a success state.  Always yields the lifted value.</returns>\n    [Pure]\n    internal static IO<A> pureAsync<A>(Task<A> value) =>\n        new IOPureAsync<A>(new ValueTask<A>(value));\n    \n    /// <summary>\n    /// Lift a pure value into an IO computation\n    /// </summary>\n    /// <param name=\"value\">value</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IO in a success state.  Always yields the lifted value.</returns>\n    [Pure]\n    internal static IO<A> pureVAsync<A>(ValueTask<A> value) =>\n        new IOPureAsync<A>(value);\n    \n    /// <summary>\n    /// Put the IO into a failure state\n    /// </summary>\n    /// <param name=\"value\">Error value</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IO in a failed state.  Always yields an error.</returns>\n    [Pure]\n    public static IO<A> fail<A>(Error value) =>\n        new IOFail<A>(value);\n    \n    /// <summary>\n    /// Put the IO into a failure state\n    /// </summary>\n    /// <param name=\"value\">Error value</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IO in a failed state.  Always yields an error.</returns>\n    [Pure]\n    public static IO<A> fail<A>(string value) =>\n        fail<A>(Error.New(value));\n    \n    /// <summary>\n    /// Lift an action into the IO monad\n    /// </summary>\n    /// <param name=\"f\">Action to lift</param>\n    [Pure]\n    public static IO<Unit> lift(Action f) =>\n        lift(() =>\n             {\n                 f();\n                 return unit;\n             });\n    \n    [Pure]\n    public static IO<A> lift<A>(Either<Error, A> ma) =>\n        ma switch\n        {\n            Either<Error, A>.Right (var r) => pure(r),\n            Either<Error, A>.Left (var l)  => fail<A>(l),\n            _                              => fail<A>(Errors.Bottom)\n        };\n    \n    [Pure]\n    public static IO<A> lift<A>(Fin<A> ma) =>\n        lift(ma.ToEither());\n    \n    [Pure]\n    public static IO<A> lift<A>(Func<A> f) => \n        new IOLiftSync<A, A>(_ => f(), pure);\n    \n    [Pure]\n    public static IO<A> lift<A>(Func<EnvIO, A> f) => \n        new IOLiftSync<A, A>(f, pure);\n    \n    [Pure]\n    public static IO<A> lift<A>(Func<Fin<A>> f) => \n        lift(() => f().ThrowIfFail());\n    \n    [Pure]\n    public static IO<A> lift<A>(Func<EnvIO, Fin<A>> f) => \n        lift(e => f(e).ThrowIfFail());\n    \n    [Pure]\n    public static IO<A> lift<A>(Func<Either<Error, A>> f) => \n        lift(() => f().ToFin().ThrowIfFail());\n    \n    [Pure]\n    public static IO<A> lift<A>(Func<EnvIO, Either<Error, A>> f) => \n        lift(e => f(e).ToFin().ThrowIfFail());\n\n    [Pure]\n    public static IO<A> liftAsync<A>(Func<Task<A>> f) => \n        new IOLiftAsync<A, A>(_ => f(), pure);\n\n    [Pure]\n    public static IO<A> liftAsync<A>(Func<EnvIO, Task<A>> f) => \n        new IOLiftAsync<A, A>(f, pure);\n\n    [Pure]\n    public static IO<A> liftVAsync<A>(Func<ValueTask<A>> f) => \n        new IOLiftVAsync<A, A>(_ => f(), pure);\n\n    [Pure]\n    public static IO<A> liftVAsync<A>(Func<EnvIO, ValueTask<A>> f) => \n        new IOLiftVAsync<A, A>(f, pure);\n\n    /// <summary>\n    /// Wraps this computation in a local-environment that ignores any cancellation-token cancellation requests.\n    /// </summary>\n    /// <returns>An uninterruptible computation</returns>\n    [Pure]\n    public static IO<A> uninterruptible<A>(IO<A> ma) =>\n        ma.Uninterruptible();\n\n    /// <summary>\n    /// Creates a local cancellation environment\n    /// </summary>\n    /// <remarks>\n    /// A local cancellation environment stops other IO computations, that rely on the same\n    /// environmental cancellation token, from being taken down by a regional cancellation.\n    ///\n    /// If an `IO.cancel` is invoked locally, then it will still create an exception that\n    /// propagates upwards and so catching cancellations is still important. \n    /// </remarks>\n    /// <param name=\"ma\">Computation to run within the local context</param>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Result of the computation</returns>\n    [Pure]\n    public static IO<A> local<A>(K<IO, A> ma) => \n        ma.As().Local();\n\n    public static readonly IO<EnvIO> env = \n        lift(e => e);\n    \n    public static readonly IO<CancellationToken> token = \n        new IOToken<CancellationToken>(pure);\n    \n    public static readonly IO<CancellationTokenSource> source = \n        lift(e => e.Source);\n    \n    public static readonly IO<Option<SynchronizationContext>> syncContext = \n        lift(e => Optional(e.SyncContext));\n\n    [Pure]\n    public static IO<A> empty<A>() =>\n        IO<A>.Empty;\n\n    [Pure]\n    public static IO<A> combine<A>(K<IO, A> ma, K<IO, A> mb) => \n        ma.As() | mb.As();\n\n    /// <summary>\n    /// Yield the thread for the specified duration or until cancelled.\n    /// </summary>\n    /// <param name=\"duration\">Amount of time to yield for</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public static IO<Unit> yieldFor(Duration duration) =>\n        Math.Abs(duration.Milliseconds) < 0.00000001\n            ? unitIO\n            : liftAsync(e => yieldFor(duration, e.Token));\n\n    /// <summary>\n    /// Yield the thread for the specified duration or until cancelled.\n    /// </summary>\n    /// <param name=\"timeSpan\">Amount of time to yield for</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public static IO<Unit> yieldFor(TimeSpan timeSpan) =>\n        Math.Abs(timeSpan.TotalMilliseconds) < 0.00000001\n            ? unitIO\n            : liftAsync(e => yieldFor(timeSpan, e.Token));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Internal\n    //\n    \n    /// <summary>\n    /// Yields the thread for the `Duration` specified allowing for concurrency\n    /// on the current thread \n    /// </summary>\n    internal static async Task<Unit> yieldFor(Duration d, CancellationToken token)\n    {\n        await Task.Delay((TimeSpan)d, token);\n        return unit;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/IO.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Common;\nusing LanguageExt.DSL;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class IO : \n    MonadUnliftIO<IO>,\n    Final<IO>,\n    Fallible<IO>,\n    Alternative<IO>\n{\n    static K<IO, B> Applicative<IO>.Apply<A, B>(K<IO, Func<A, B>> mf, K<IO, A> ma) =>\n        (mf, ma) switch\n        {\n            (_, IOEmpty<A>)          => IOEmpty<B>.Default,\n            (IOEmpty<Func<A, B>>, _) => IOEmpty<B>.Default,\n            _                        => ma.As().ApplyBack(mf.As()),\n        };\n\n    static K<IO, B> Applicative<IO>.Apply<A, B>(K<IO, Func<A, B>> mf, Memo<IO, A> ma) =>\n        mf switch\n        {\n            IOEmpty<Func<A, B>>       => IOEmpty<B>.Default,\n            IOFail<Func<A, B>>(var e) => new IOFail<B>(e),\n            _                         => ma.Value.As().ApplyBack(mf) \n        };\n\n    static K<IO, B> Applicative<IO>.Action<A, B>(K<IO, A> ma, K<IO, B> mb) =>\n        ma switch\n        {\n            IOEmpty<A>       => IOEmpty<B>.Default,\n            IOFail<A>(var e) => new IOFail<B>(e),\n            _                => new IOAction<A, B, B>(ma, mb, pure)\n        };\n\n    static K<IO, B> Applicative<IO>.Action<A, B>(K<IO, A> ma, Memo<IO, B> mb) =>\n        ma switch\n        {\n            IOEmpty<A>       => IOEmpty<B>.Default,\n            IOFail<A>(var e) => new IOFail<B>(e),\n            _                => new IOActionLazy<A, B, B>(ma, mb, pure)\n        };\n\n    static K<IO, A> Applicative<IO>.Actions<A>(IterableNE<K<IO, A>> fas) =>\n        new IOActions<A, A>(fas, pure);\n\n    static K<IO, B> Monad<IO>.Bind<A, B>(K<IO, A> ma, Func<A, K<IO, B>> f) =>\n        ma switch\n        {\n            IOEmpty<A>       => IOEmpty<B>.Default,\n            IOFail<A>(var e) => new IOFail<B>(e),\n            IO<A> io         => io.Bind(f),\n            _                => throw new NotSupportedException()\n        };\n\n    static K<IO, B> Monad<IO>.Recur<A, B>(A value, Func<A, K<IO, Next<A, B>>> f) =>\n        liftVAsync(async e =>\n                  {\n                      while (true)\n                      {\n                          if(e.Token.IsCancellationRequested) throw new OperationCanceledException();\n                          var next = await f(value).As().RunAsync(e);\n                          if (next.IsDone) return next.Done;\n                          value = next.Loop;\n                      }\n                  });\n\n    static K<IO, B> Functor<IO>.Map<A, B>(Func<A, B> f, K<IO, A> ma) => \n        ma is IOEmpty<A>\n            ? IOEmpty<B>.Default\n            : ma.As().Map(f);\n\n    static K<IO, A> Applicative<IO>.Pure<A>(A value) =>\n        new IOPure<A>(value);\n\n    static K<IO, A> Fallible<Error, IO>.Fail<A>(Error error) => \n        fail<A>(error);\n\n    static K<IO, A> Fallible<Error, IO>.Catch<A>(\n        K<IO, A> fa,\n        Func<Error, bool> Predicate,\n        Func<Error, K<IO, A>> Fail) =>\n        fa switch\n        {\n            IOEmpty<A>       => Predicate(Errors.None) ? Fail(Errors.None) : fa,\n            IOFail<A>(var e) => Predicate(e) ? Fail(e) : fa,\n            _                => new IOCatch<A, A>(fa, Predicate, Fail, null, pure),\n        };        \n\n    static K<IO, A> Choice<IO>.Choose<A>(K<IO, A> fa, K<IO, A> fb) =>\n        fa switch\n        {\n            IOEmpty<A> => fb,\n            IOFail<A>  => fb,\n            _          => new IOCatch<A, A>(fa, _ => true, _ => fb, null, pure)\n        };\n\n    static K<IO, A> Choice<IO>.Choose<A>(K<IO, A> fa, Memo<IO, A> fb) =>\n        fa switch\n        {\n            IOEmpty<A> => fb.Value,\n            IOFail<A>  => fb.Value,\n            _          => new IOCatch<A, A>(fa, _ => true, _ => fb.Value, null, pure)\n        };\n\n    static K<IO, A> Alternative<IO>.Empty<A>() =>\n        empty<A>();\n\n    static K<IO, A> MonadIO<IO>.LiftIO<A>(IO<A> ma) => \n        ma;\n\n    static K<IO, B> MonadUnliftIO<IO>.MapIO<A, B>(K<IO, A> ma, Func<IO<A>, IO<B>> f) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<B>.Default\n            : f(ma.As());\n\n    static K<IO, IO<A>> MonadUnliftIO<IO>.ToIO<A>(K<IO, A> ma) =>\n        pure(ma.As());\n\n    static K<IO, A> Final<IO>.Finally<X, A>(K<IO, A> fa, K<IO, X> @finally) =>\n        fa is IOEmpty<A>\n            ? fa\n            : new IOFinal<X, A, A>(fa, @finally, pure);\n    \n    /// <summary>\n    /// Creates a local cancellation environment\n    /// </summary>\n    /// <remarks>\n    /// A local cancellation environment stops other IO computations, that rely on the same\n    /// environmental cancellation token, from being taken down by a regional cancellation.\n    ///\n    /// If an `IO.cancel` is invoked locally, then it will still create an exception that\n    /// propagates upwards and so catching cancellations is still important. \n    /// </remarks>\n    /// <param name=\"ma\">Computation to run within the local context</param>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Result of the computation</returns>\n    static K<IO, A> MonadUnliftIO<IO>.LocalIO<A>(K<IO, A> ma) =>\n        ma is IOEmpty<A>\n            ? ma\n            : ma.As().Local();\n\n    /// <summary>\n    /// Make this IO computation run on the `SynchronizationContext` that was captured at the start\n    /// of the IO chain (i.e. the one embedded within the `EnvIO` environment that is passed through\n    /// all IO computations)\n    /// </summary>\n    static K<IO, A> MonadUnliftIO<IO>.PostIO<A>(K<IO, A> ma) =>\n        ma is IOEmpty<A>\n            ? ma\n            : ma.As().Post();        \n\n    /// <summary>\n    /// Await a forked operation\n    /// </summary>\n    static K<IO, A> MonadUnliftIO<IO>.Await<A>(K<IO, ForkIO<A>> ma) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().Bind(f => f.Await);    \n\n    /// <summary>\n    /// Queue this IO operation to run on the thread-pool. \n    /// </summary>\n    /// <param name=\"timeout\">Maximum time that the forked IO operation can run for. `None` for no timeout.</param>\n    /// <returns>Returns a `ForkIO` data-structure that contains two IO effects that can be used to either cancel\n    /// the forked IO operation or to await the result of it.\n    /// </returns>\n    static K<IO, ForkIO<A>> MonadUnliftIO<IO>.ForkIO<A>(K<IO, A> ma, Option<TimeSpan> timeout) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<ForkIO<A>>.Default\n            : ma.As().Fork(timeout);\n\n    /// <summary>\n    /// Timeout operation if it takes too long\n    /// </summary>\n    static K<IO, A> MonadUnliftIO<IO>.TimeoutIO<A>(K<IO, A> ma, TimeSpan timeout) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().Timeout(timeout);\n\n    /// <summary>\n    /// The IO monad tracks resources automatically, this creates a local resource environment\n    /// to run this computation in.  Once the computation has completed any resources acquired\n    /// are automatically released.  Imagine this as the ultimate `using` statement.\n    /// </summary>\n    static K<IO, A> MonadUnliftIO<IO>.BracketIO<A>(K<IO, A> ma) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().Bracket();\n\n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <param name=\"Acq\">Resource acquisition</param>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Fin\">Function to invoke to release the resource</param>\n    static K<IO, C> MonadUnliftIO<IO>.BracketIO<A, B, C>(\n        K<IO, A> Acq,\n        Func<A, IO<C>> Use,\n        Func<A, IO<B>> Fin) =>\n        Acq is IOEmpty<A>\n            ? IOEmpty<C>.Default\n            : Acq.As().Bracket(Use, Fin);\n\n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <param name=\"Acq\">Resource acquisition</param>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Catch\">Function to run to handle any exceptions</param>\n    /// <param name=\"Fin\">Function to invoke to release the resource</param>\n    static K<IO, C> MonadUnliftIO<IO>.BracketIO<A, B, C>(\n        K<IO, A> Acq,\n        Func<A, IO<C>> Use,\n        Func<Error, IO<C>> Catch,\n        Func<A, IO<B>> Fin) =>\n        Acq is IOEmpty<A>\n            ? IOEmpty<C>.Default\n            : Acq.As().Bracket(Use, Catch, Fin);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Repeating the effect\n    //\n\n    /// <summary>\n    /// Keeps repeating the computation forever, or until an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <returns>The result of the last invocation</returns>\n    static K<IO, A> MonadUnliftIO<IO>.RepeatIO<A>(K<IO, A> ma) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().Repeat();\n\n    /// <summary>\n    /// Keeps repeating the computation, until the scheduler expires, or an error occurs  \n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <returns>The result of the last invocation</returns>\n    static K<IO, A> MonadUnliftIO<IO>.RepeatIO<A>(\n        K<IO, A> ma,\n        Schedule schedule) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().Repeat(schedule);\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns false, or an error occurs \n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    static K<IO, A> MonadUnliftIO<IO>.RepeatWhileIO<A>(\n        K<IO, A> ma,\n        Func<A, bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().RepeatWhile(predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation, until the scheduler expires, or the predicate returns false, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    static K<IO, A> MonadUnliftIO<IO>.RepeatWhileIO<A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        Func<A, bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().RepeatWhile(schedule, predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns true, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    static K<IO, A> MonadUnliftIO<IO>.RepeatUntilIO<A>(\n        K<IO, A> ma,\n        Func<A, bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().RepeatUntil(predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation, until the scheduler expires, or the predicate returns true, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    static K<IO, A> MonadUnliftIO<IO>.RepeatUntilIO<A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        Func<A, bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().RepeatUntil(schedule, predicate);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Retrying the effect when it fails\n    //\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will retry forever\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    static K<IO, A> MonadUnliftIO<IO>.RetryIO<A>(K<IO, A> ma) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().Retry();\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will retry until the schedule expires\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    static K<IO, A> MonadUnliftIO<IO>.RetryIO<A>(\n        K<IO, A> ma,\n        Schedule schedule) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().Retry(schedule);\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n    /// at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    static K<IO, A> MonadUnliftIO<IO>.RetryWhileIO<A>(\n        K<IO, A> ma,\n        Func<Error, bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().RetryWhile(predicate);\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n    /// or, until the schedule expires; at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    static K<IO, A> MonadUnliftIO<IO>.RetryWhileIO<A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        Func<Error, bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().RetryWhile(schedule, predicate);\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n    /// at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    static K<IO, A> MonadUnliftIO<IO>.RetryUntilIO<A>(\n        K<IO, A> ma,\n        Func<Error, bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().RetryUntil(predicate);\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n    /// or, until the schedule expires; at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    static K<IO, A> MonadUnliftIO<IO>.RetryUntilIO<A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        Func<Error, bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<A>.Default\n            : ma.As().RetryUntil(schedule, predicate);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Folding\n    //\n\n    static K<IO, S> MonadUnliftIO<IO>.FoldIO<S, A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().Fold(schedule, initialState, folder);\n\n    static K<IO, S> MonadUnliftIO<IO>.FoldIO<S, A>(\n        K<IO, A> ma,\n        S initialState,\n        Func<S, A, S> folder) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().Fold(initialState, folder);\n\n    static K<IO, S> MonadUnliftIO<IO>.FoldWhileIO<S, A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldWhile(schedule, initialState, folder, stateIs);\n\n    static K<IO, S> MonadUnliftIO<IO>.FoldWhileIO<S, A>(\n        K<IO, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldWhile(initialState, folder, stateIs);\n\n    static K<IO, S> MonadUnliftIO<IO>.FoldWhileIO<S, A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldWhile(schedule, initialState, folder, valueIs);\n\n    static K<IO, S> MonadUnliftIO<IO>.FoldWhileIO<S, A>(\n        K<IO, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldWhile(initialState, folder, valueIs);\n    \n    static K<IO, S> MonadUnliftIO<IO>.FoldWhileIO<S, A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldWhile(schedule, initialState, folder, predicate);\n\n    static K<IO, S> MonadUnliftIO<IO>.FoldWhileIO<S, A>(\n        K<IO, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldWhile(initialState, folder, predicate);\n    \n    static K<IO, S> MonadUnliftIO<IO>.FoldUntilIO<S, A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldUntil(schedule, initialState, folder, stateIs);\n    \n    static K<IO, S> MonadUnliftIO<IO>.FoldUntilIO<S, A>(\n        K<IO, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldUntil(initialState, folder, stateIs);\n    \n    static K<IO, S> MonadUnliftIO<IO>.FoldUntilIO<S, A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldUntil(schedule, initialState, folder, valueIs);\n    \n    static K<IO, S> MonadUnliftIO<IO>.FoldUntilIO<S, A>(\n        K<IO, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldUntil(initialState, folder, valueIs);\n    \n    static K<IO, S> MonadUnliftIO<IO>.FoldUntilIO<S, A>(\n        K<IO, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldUntil(initialState, folder, predicate);\n\n    static K<IO, S> MonadUnliftIO<IO>.FoldUntilIO<S, A>(\n        K<IO, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        ma is IOEmpty<A>\n            ? IOEmpty<S>.Default\n            : ma.As().FoldUntil(schedule, initialState, folder, predicate);       \n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/IO.cs",
    "content": "using System;\nusing LanguageExt.DSL;\nusing System.Threading;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing System.Threading.Tasks;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A value of type `IO` is a computation which, when performed, does some I/O before returning\n/// a value of type `A`.\n///\n/// There is really only one way you should _\"perform\"_ an I/O action: bind it to `Main` in your\n/// program:  When your program is run, the I/O will be performed. It shouldn't be possible to\n/// perform I/O from an arbitrary function, unless that function is itself in the `IO` monad and\n/// called at some point, directly or indirectly, from `Main`.\n///\n/// As this is C#, the above restrictions are for you to enforce. It would be reasonable\n/// to relax that approach and have I/O invoked from, say, web-request handlers - or any other 'edges'\n/// of your application.\n/// \n/// `IO` is a monad, so `IO` actions can be combined using either the LINQ-notation or the `bind` \n/// operations from the `Monad` class.\n/// </summary>\n/// <param name=\"runIO\">The lifted thunk that is the IO operation</param>\n/// <typeparam name=\"A\">Bound value</typeparam>\npublic abstract record IO<A> :\n    K<IO, A>,\n    Monoid<IO<A>>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  General\n    //\n    \n    public static IO<A> Empty =>\n        IOEmpty<A>.Default;\n    \n    /// <summary>\n    /// Wraps this IO computation in a local-environment that ignores any cancellation-token cancellation requests.\n    /// </summary>\n    /// <returns>An uninterruptible IO computation</returns>\n    public IO<A> Uninterruptible() =>\n        new IOUninterruptible<A, A>(this, IO.pure);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Functor\n    //\n\n    public abstract IO<B> Map<B>(Func<A, B> f);\n\n    public virtual IO<B> ApplyBack<B>(K<IO, Func<A, B>> f) =>\n        new IOApply<A, B, B>(f, this, IO.pure);\n    \n    public IO<B> Map<B>(B value) =>\n        Map(_ => value);\n\n    public IO<A> MapFail(Func<Error, Error> f) => \n        this.Catch(f).As();\n    \n    public IO<B> BiMap<B>(Func<A, B> Succ, Func<Error, Error> Fail) =>\n        Map(Succ).Catch(Fail).As();\n\n    public IO<B> Match<B>(Func<A, B> Succ, Func<Error, B> Fail) =>\n        Map(Succ).Catch(Fail).As();\n\n    public IO<A> IfFail(Func<Error, A> Fail) =>\n        this.Catch(Fail).As();\n\n    public IO<A> IfFail(A Fail) =>\n        this.Catch(Fail).As();\n    \n    public IO<A> IfFail(Func<Error, IO<A>> Fail) =>\n        this.CatchIO(Fail).As();\n\n    public IO<A> IfFail(IO<A> Fail) =>\n        this.Catch(Fail).As();\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Folding\n    //\n\n    public virtual IO<S> Fold<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder) =>\n        new IOFold<S, A, S>(this, schedule, initialState, folder, IO.pure);\n\n    public virtual IO<S> Fold<S>(\n        S initialState,\n        Func<S, A, S> folder) =>\n        new IOFold<S, A, S>(this, Schedule.Forever, initialState, folder, IO.pure);\n\n    public virtual IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        new IOFoldWhile<S, A, S>(this, schedule, initialState, folder, s => stateIs(s.State), IO.pure);\n\n    public virtual IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        new IOFoldWhile<S, A, S>(this, Schedule.Forever, initialState, folder, s => stateIs(s.State), IO.pure);\n    \n    public virtual IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        new IOFoldWhile<S, A, S>(this, schedule, initialState, folder, s => valueIs(s.Value), IO.pure);\n\n    public virtual IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        new IOFoldWhile<S, A, S>(this, Schedule.Forever, initialState, folder, s => valueIs(s.Value), IO.pure);\n    \n    public virtual IO<S> FoldWhile<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        new IOFoldWhile<S, A, S>(this, schedule, initialState, folder, predicate, IO.pure);\n\n    public virtual IO<S> FoldWhile<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        new IOFoldWhile<S, A, S>(this, Schedule.Forever, initialState, folder, predicate, IO.pure);\n\n    public virtual IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        new IOFoldUntil<S, A, S>(this, schedule, initialState, folder, p => stateIs(p.State), IO.pure);\n    \n    public virtual IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        new IOFoldUntil<S, A, S>(this, Schedule.Forever, initialState, folder, p => stateIs(p.State), IO.pure);\n    \n    public virtual IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        new IOFoldUntil<S, A, S>(this, schedule, initialState, folder, p => valueIs(p.Value), IO.pure);\n    \n    public virtual IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        new IOFoldUntil<S, A, S>(this, Schedule.Forever, initialState, folder, p => valueIs(p.Value), IO.pure);\n    \n    public virtual IO<S> FoldUntil<S>(\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        new IOFoldUntil<S, A, S>(this, Schedule.Forever, initialState, folder, predicate, IO.pure);\n\n    public virtual IO<S> FoldUntil<S>(\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        new IOFoldUntil<S, A, S>(this, schedule, initialState, folder, predicate, IO.pure);\n    \n    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Cross thread-context posting\n    //\n \n    /// <summary>\n    /// Make this IO computation run on the `SynchronizationContext` that was captured at the start\n    /// of the IO chain (i.e. the one embedded within the `EnvIO` environment that is passed through\n    /// all IO computations)\n    /// </summary>\n    public virtual IO<A> Post() =>\n        IO.liftAsync(async env =>\n                       {\n                           if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                           if (env.SyncContext is null) return await RunAsync(env);\n\n                           A?         value = default;\n                           Exception? error = default;\n                           using var  wait  = new AutoResetEvent(false);\n\n                           env.SyncContext.Post(_ =>\n                                                {\n                                                    try\n                                                    {\n                                                        value = Run(env);\n                                                    }\n                                                    catch (Exception e)\n                                                    {\n                                                        error = e;\n                                                    }\n                                                    finally\n                                                    {\n                                                        wait.Set();\n                                                    }\n                                                },\n                                                null);\n\n                           await wait.WaitOneAsync(env.Token);\n                           if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                           if (error is not null) error.Rethrow<A>();\n                           return value!;\n                       });\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monad\n    //\n\n    public abstract IO<B> Bind<B>(Func<A, K<IO, B>> f);\n    public abstract IO<B> BindAsync<B>(Func<A, ValueTask<K<IO, B>>> f);\n\n    public IO<B> Bind<B>(Func<A, IO<B>> f) =>\n        Bind(x => f(x).Kind());\n\n    public IO<B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(x => f(x).Value);\n\n    public IO<B> BindAsync<B>(Func<A, ValueTask<IO<B>>> f) =>\n        BindAsync(async x => (await f(x)).Kind());\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  LINQ\n    //\n    \n    public IO<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    public IO<C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        Bind(x => IOTail<A>.resolve(x, bind(x), project));\n\n    public IO<C> SelectMany<B, C>(Func<A, K<IO, B>> bind, Func<A, B, C> project) =>\n        Bind(x => IOTail<A>.resolve(x, bind(x).As(), project));\n\n    public IO<C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    public Eff<C> SelectMany<B, C>(Func<A, Eff<B>> bind, Func<A, B, C> project) =>\n        Eff<A>.LiftIO(this).SelectMany(bind, project);\n\n    public Eff<RT, C> SelectMany<RT, B, C>(Func<A, Eff<RT, B>> bind, Func<A, B, C> project) =>\n        Eff<RT, A>.LiftIO(this).SelectMany(bind, project);\n\n    public IO<C> SelectMany<C>(Func<A, Guard<Error, Unit>> bind, Func<A, Unit, C> project) =>\n        SelectMany(a => bind(a).ToIO(), project);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Brackets\n    //\n\n    /// <summary>\n    /// The IO monad tracks resources automatically; this method creates a local resource environment\n    /// to run this computation in.  Once the computation is complete, any resources acquired are automatically\n    /// released.  Imagine this as the ultimate `using` statement.\n    /// </summary>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public IO<A> Bracket() =>\n        WithEnv(env => env.LocalResources);\n\n    /// <summary>\n    /// The IO monad tracks resources automatically; this method creates a local resource environment\n    /// to run the computation in.  If the computation errors, then the resources are automatically\n    /// released.  \n    /// </summary>\n    /// <remarks>\n    /// This differs from `Bracket` in that `Bracket` will also free resources once the computation\n    /// is successfully complete.  `BracketFail` only frees resources on failure.\n    /// </remarks>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public IO<A> BracketFail() =>\n        WithEnvFail(env => env.LocalResources);\n\n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Fin\">Function to invoke to release the resource</param>\n    public IO<C> Bracket<B, C>(Func<A, IO<C>> Use, Func<A, IO<B>> Fin) =>\n        Bind(x => Use(x).Finally(Fin(x)));\n\n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Catch\">Function to run to handle any exceptions</param>\n    /// <param name=\"Fin\">Function to invoke to release the resource</param>\n    public IO<C> Bracket<B, C>(Func<A, IO<C>> Use, Func<Error, IO<C>> Catch, Func<A, IO<B>> Fin) =>\n        Bind(x => Use(x).Catch(Catch).Finally(Fin(x)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Conversion\n    //\n    \n    public static implicit operator IO<A>(Pure<A> ma) =>\n        IO.pure(ma.Value);\n\n    public static implicit operator IO<A>(Error error) =>\n        IO.lift(_ => error.Throw<A>());\n\n    public static implicit operator IO<A>(Fail<Error> ma) =>\n        IO.lift(() => ma.Value.Throw<A>());\n\n    public static implicit operator IO<A>(Fail<Exception> ma) =>\n        IO.lift(() => ma.Value.Rethrow<A>());\n\n    public static implicit operator IO<A>(Lift<EnvIO, A> ma) =>\n        IO.lift(ma.Function);\n\n    public static implicit operator IO<A>(Lift<A> ma) =>\n        IO.lift(ma.Function);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Parallel\n    //\n\n    /// <summary>\n    /// Applies a time limit to the IO computation.  If exceeded, an exception is thrown.  \n    /// </summary>\n    /// <param name=\"timeout\">Timeout</param>\n    /// <returns>Result of the operation or throws if the time limit exceeded.</returns>\n    public IO<A> Timeout(TimeSpan timeout) =>\n        new IOTimeout<A, A>(this, timeout, IO.pure);\n\n    /// <summary>\n    /// Map the `EnvIO` value threaded through the computation.  Upon completion, any resources acquired during\n    /// the processing of this computation (in the newly mapped local context) will automatically be released.       \n    /// </summary>\n   protected virtual IO<A> WithEnv(Func<EnvIO, EnvIO> f) =>\n        new IOLocal<A, A>(f, this, IO.pure);\n\n    /// <summary>\n    /// Map the `EnvIO` value threaded through the computation.  Upon completion, any resources acquired during\n    /// the processing of this computation (in the newly mapped local context) will automatically be released.       \n    /// </summary>\n    /// <remarks>\n    /// This variant will only release resources on failure.  Successful computations will allow the return of\n    /// acquired resources so they can be used outside this computation.\n    /// </remarks>\n    protected virtual IO<A> WithEnvFail(Func<EnvIO, EnvIO> f) =>\n        new IOLocalOnFailOnly<A, A>(f, this, IO.pure);\n\n    /// <summary>\n    /// Create a local cancellation environment\n    /// </summary>\n    public IO<A> Local() =>\n        WithEnv(env => EnvIO.New(env.Resources, env.Token, null, env.SyncContext));\n    \n    /// <summary>\n    /// Queues the specified work to run on the thread pool  \n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a forked IO computation will automatically be released upon the forked\n    /// computation's completion (successful or otherwise).  Resources acquired in the parent thread will be\n    /// available to the forked thread, and can be released from there, but they are shared resources at that\n    /// point and should be treated with care.\n    /// </remarks>\n    /// <param name=\"timeout\">Optional timeout</param>\n    /// <returns>`Fork` record that contains members for cancellation and optional awaiting</returns>\n    public virtual IO<ForkIO<A>> Fork(Option<TimeSpan> timeout = default) =>\n        IO.lift(\n            env =>\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                \n                // Create a new local token-source with its own cancellation token\n                var tsrc  = timeout.Match(Some: to => new CancellationTokenSource(to), \n                                          None: () => new CancellationTokenSource());\n                var token = tsrc.Token;\n\n                // If the parent cancels, we should too\n                var reg = env.Token.Register(() => tsrc.Cancel());\n\n                // Gather our resources for clean-up\n                var cleanup = new CleanUp(tsrc, reg);\n\n                var parentResources = env.Resources;\n\n                var task = Task.Factory.StartNew(\n                    () =>\n                    {\n                        var forkedResources = new Resources(parentResources);\n                        try\n                        {\n                            var t = RunAsync(EnvIO.New(forkedResources, token, tsrc, env.SyncContext));\n                            return t.GetAwaiter().GetResult();\n                        }\n                        finally\n                        {\n                            forkedResources.Dispose();\n                            cleanup.Dispose();\n                        }\n                    }, TaskCreationOptions.LongRunning);\n\n                return new ForkIO<A>(\n                        IO.lift<Unit>(_ => {\n                                          try\n                                          {\n                                              tsrc.Cancel();\n                                          }\n                                          catch(OperationCanceledException)\n                                          {\n                                              // ignore if already cancelled\n                                          }\n                                          catch(ObjectDisposedException)\n                                          {\n                                              // ignore if already cancelled\n                                          }\n                                          return default; \n                                      }),\n                        IO.liftAsync(e => AwaitAsync(task, e, token, tsrc)));\n            });\n    \n    \n    /// <summary>\n    /// Run the `IO` monad to get its result.  Differs from `Run` in that it catches any exceptions and turns\n    /// them into a `Fin〈A〉` result. \n    /// </summary>\n    public FinT<IO, A> Try() =>\n        new (Map(Fin.Succ).Catch(Fin.Fail<A>));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Repeating the effect\n    //\n    \n    /// <summary>\n    /// Keeps repeating the computation forever, or until an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <returns>The result of the last invocation</returns>\n    public IO<A> Repeat() =>\n        RepeatUntil(_ => false);\n\n    /// <summary>\n    /// Keeps repeating the computation, until the scheduler expires, or an error occurs  \n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <returns>The result of the last invocation</returns>\n    public IO<A> Repeat(Schedule schedule) =>\n        RepeatUntil(schedule, _ => false);\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns false, or an error occurs \n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    public IO<A> RepeatWhile(Func<A, bool> predicate) => \n        RepeatUntil(not(predicate));\n\n    /// <summary>\n    /// Keeps repeating the computation, until the scheduler expires, or the predicate returns false, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    public IO<A> RepeatWhile(\n        Schedule schedule,\n        Func<A, bool> predicate) =>\n        RepeatUntil(schedule, not(predicate));\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns true, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    public IO<A> RepeatUntil(Func<A, bool> predicate) =>\n        Bracket().Bind(v => predicate(v) \n                                ? IO.pure(v) \n                                : RepeatUntil(predicate));\n\n    /// <summary>\n    /// Keeps repeating the computation, until the scheduler expires, or the predicate returns true, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    public virtual IO<A> RepeatUntil(\n        Schedule schedule,\n        Func<A, bool> predicate)\n    {\n        return go(schedule.PrependZero.Run().GetIterator(), default);\n\n        IO<A> go(Iterator<Duration> iter, A? value) =>\n            iter switch\n            {\n                Iterator<Duration>.Nil =>\n                    IO.pure<A>(value!),\n\n                Iterator<Duration>.Cons(var head, var tail) =>\n                    IO.yieldFor(head)\n                      .Bind(_ => Bracket()\n                               .Bind(v => predicate(v) \n                                              ? IO.pure(v) \n                                              : go(tail, v))),\n                \n                _ => throw new InvalidOperationException(\"Invalid iterator\")\n            };\n    }\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Retrying the effect when it fails\n    //\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will retry forever\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public IO<A> Retry() =>\n        RetryUntil(_ => false);\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will retry until the schedule expires\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public IO<A> Retry(Schedule schedule) =>\n        RetryUntil(schedule, _ => false);\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n    /// at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public IO<A> RetryWhile(Func<Error, bool> predicate) => \n        RetryUntil(not(predicate));\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n    /// or, until the schedule expires; at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public IO<A> RetryWhile(\n        Schedule schedule,\n        Func<Error, bool> predicate) =>\n        RetryUntil(schedule, not(predicate));\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n    /// at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public IO<A> RetryUntil(Func<Error, bool> predicate) =>\n        BracketFail()\n           .Catch(e => predicate(e)\n                           ? IO.fail<A>(e)\n                           : RetryUntil(predicate)).As();\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n    /// or, until the schedule expires; at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public virtual IO<A> RetryUntil(Schedule schedule, Func<Error, bool> predicate)\n    {\n        return go(schedule.PrependZero.Run().GetIterator(), Errors.None);\n\n        IO<A> go(Iterator<Duration> iter, Error error) =>\n            iter switch\n            {\n                Iterator<Duration>.Nil =>\n                    IO.fail<A>(error),\n\n                Iterator<Duration>.Cons(var head, var tail) =>\n                    IO.yieldFor(head)\n                      .Bind(_ => BracketFail()\n                                   .Catch(e => predicate(e)\n                                                   ? IO.fail<A>(e)\n                                                   : go(tail, e))),\n                     \n                _ => throw new InvalidOperationException(\"Invalid iterator\")\n            };\n    }\n\n    /// <summary>\n    /// Catches any error thrown by invoking this IO computation, passes it through a predicate,\n    /// and if that returns true, returns the result of invoking the Fail function, otherwise\n    /// this is returned.\n    /// </summary>\n    /// <param name=\"Predicate\">Predicate</param>\n    /// <param name=\"Fail\">Fail functions</param>\n    public virtual IO<A> Catch(Func<Error, bool> Predicate, Func<Error, K<IO, A>> Fail) =>\n        new IOCatch<A, A>(this, Predicate, Fail, null, IO.pure);\n\n    /// <summary>\n    /// Run a `finally` operation after the `this` operation regardless of whether `this` succeeds or not.\n    /// </summary>\n    /// <param name=\"finally\">Finally operation</param>\n    /// <returns>Result of primary operation</returns>\n    public virtual IO<A> Finally<X>(K<IO, X> @finally) =>\n        new IOFinal<X, A, A>(this, @finally, IO.pure);\n    \n    /// <summary>\n    /// Monoid combine\n    /// </summary>\n    /// <param name=\"rhs\">Alternative</param>\n    /// <returns>This if computation runs without error.  `rhs` otherwise</returns>\n    public IO<A> Combine(IO<A> rhs) =>\n        Catch(_ => true, _ => rhs);\n\n    /// <summary>\n    /// Run the `IO` monad to get its result\n    /// </summary>\n    /// <remarks>\n    /// Any lifted asynchronous operations will yield to the thread-scheduler, allowing other queued\n    /// operations to run concurrently.  So, even though this call isn't awaitable it still plays\n    /// nicely and doesn't block the thread.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: An exception will always be thrown if the IO operation fails.  Lift this monad into\n    /// other error handling monads to leverage more declarative error handling. \n    /// </remarks>\n    /// <param name=\"env\">IO environment</param>\n    /// <returns>Result of the IO operation</returns>\n    /// <exception cref=\"OperationCanceledException\">Throws if the operation is cancelled</exception>\n    public A Run()\n    {\n        // RunAsync can run completely synchronously and without the creation of an async/await state-machine, so calling\n        // it for operations that are completely synchronous has no additional overhead for us.  Therefore, calling it\n        // directly here and then unpacking the `ValueTask` makes sense to reduce code duplication.\n\n        var task = RunAsync();\n        if (task.IsCompleted) return task.Result;\n\n        // If RunAsync really had to do some asynchronous work, then make sure we use the awaiter and get its result\n        return task.GetAwaiter().GetResult();\n    }\n\n    /// <summary>\n    /// Run the `IO` monad to get its result\n    /// </summary>\n    /// <remarks>\n    /// Any lifted asynchronous operations will yield to the thread-scheduler, allowing other queued\n    /// operations to run concurrently.  So, even though this call isn't awaitable it still plays\n    /// nicely and doesn't block the thread.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: An exception will always be thrown if the IO operation fails.  Lift this monad into\n    /// other error handling monads to leverage more declarative error handling. \n    /// </remarks>\n    /// <param name=\"env\">IO environment</param>\n    /// <returns>Result of the IO operation</returns>\n    /// <exception cref=\"OperationCanceledException\">Throws if the operation is cancelled</exception>\n    public A Run(EnvIO envIO)\n    {\n        // RunAsync can run completely synchronously and without the creation of an async/await state-machine, so calling\n        // it for operations that are completely synchronous has no additional overhead for us.  Therefore, calling it\n        // directly here and then unpacking the `ValueTask` makes sense to reduce code duplication.\n\n        var task = RunAsync(envIO);\n        if (task.IsCompleted) return task.Result;\n\n        // If RunAsync really had to do some asynchronous work, then make sure we use the awaiter and get its result\n        return task.GetAwaiter().GetResult();\n    }\n\n    /// <summary>\n    /// Run the `IO` monad to get its result\n    /// </summary>\n    /// <remarks>\n    /// This forks the operation to run on a new task that is then awaited.\n    /// \n    /// Any lifted asynchronous operations will yield to the thread-scheduler, allowing other queued\n    /// operations to run concurrently.  So, even though this call isn't awaitable it still plays\n    /// nicely and doesn't block the thread.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: An exception will always be thrown if the IO operation fails.  Lift this monad into\n    /// other error handling monads to leverage more declarative error handling. \n    /// </remarks>\n    /// <returns>Result of the IO operation</returns>\n    /// <exception cref=\"OperationCanceledException\">Throws if the operation is cancelled</exception>\n    public ValueTask<A> RunAsync()\n    {\n        var envIO = EnvIO.New();\n        try\n        {\n            var va = RunAsync(envIO);\n            if (va.IsCompleted)\n            {\n                envIO.Dispose();\n                return va;\n            }\n            else\n            {\n                return SafeRunAsync(va, envIO);\n            }\n        }\n        catch (Exception)\n        {\n            envIO.Dispose();\n            throw;\n        }\n    }\n\n    /// <summary>\n    /// Run the `IO` monad to get its result\n    /// </summary>\n    /// <remarks>\n    /// Any lifted asynchronous operations will yield to the thread-scheduler, allowing other queued\n    /// operations to run concurrently.  So, even though this call isn't awaitable it still plays\n    /// nicely and doesn't block the thread.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: An exception will always be thrown if the IO operation fails.  Lift this monad into\n    /// other error handling monads to leverage more declarative error handling. \n    /// </remarks>\n    /// <param name=\"token\">Cancellation toke</param>\n    /// <returns>Result of the IO operation</returns>\n    /// <exception cref=\"OperationCanceledException\">Throws if the operation is cancelled</exception>\n    public async ValueTask<A> RunAsync(CancellationToken token)\n    {\n        using var env = EnvIO.New(token: token);\n        return await RunAsync(env);\n    }\n\n    static async ValueTask<A> SafeRunAsync(ValueTask<A> va, EnvIO envIO)\n    {\n        try\n        {\n            return await va;\n        }\n        finally\n        {\n            envIO.Dispose();\n        }\n    }\n\n    /// <summary>\n    /// Run the `IO` monad to get its result\n    /// </summary>\n    /// <remarks>\n    /// This forks the operation to run on a new task that is then awaited.\n    /// \n    /// Any lifted asynchronous operations will yield to the thread-scheduler, allowing other queued\n    /// operations to run concurrently.  So, even though this call isn't awaitable it still plays\n    /// nicely and doesn't block the thread.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: An exception will always be thrown if the IO operation fails.  Lift this monad into\n    /// other error handling monads to leverage more declarative error handling. \n    /// </remarks>\n    /// <returns>Result of the IO operation</returns>\n    /// <exception cref=\"OperationCanceledException\">Throws if the operation is cancelled</exception>\n    public ValueTask<A> RunAsync(EnvIO envIO)\n    {\n        if (envIO.Token.IsCancellationRequested) return ValueTask.FromCanceled<A>(envIO.Token);\n        var ma     = this;\n        \n        var stack  = Seq(new StackItem(ex => ex.Rethrow<IO<A>>())); // we want at least one item in the stack\n                                                                    // so that we benefit from the auto-clean-up   \n                                                                    // of resources.\n                                                                              \n        while (!envIO.Token.IsCancellationRequested)\n        {\n            switch (ma)\n            {\n                case InvokeAsync<A>:\n                    return ma.RunAsyncInternal(stack, envIO);\n\n                case InvokeAsyncIO<A>:\n                    return ma.RunAsyncInternal(stack, envIO);\n\n                case InvokeSync<A> op:\n                    try\n                    {\n                        return new ValueTask<A>(op.Invoke(envIO));\n                    }\n                    catch (Exception e)\n                    {\n                        if (stack.IsEmpty) throw;\n                        ma = RunCatchHandler(e);\n                        break;\n                    }\n\n                case InvokeSyncIO<A> op:\n                    try\n                    {\n                        ma = op.Invoke(envIO);\n                    }\n                    catch (Exception e)\n                    {\n                        if (stack.IsEmpty) throw;\n                        ma = RunCatchHandler(e);\n                    }\n\n                    break;\n\n                case IOCatch<A> c:\n                    var @catch = c.MakeHandler();\n                    stack = new StackItem(@catch).Cons(stack);\n                    ma = c.MakeOperation();\n                    break;\n\n                case IOCatchPop<A> pop:\n                    stack = stack.Tail;\n                    ma = pop.Next;\n                    break;\n\n                case IOTail<A> tail:\n                    ma = tail.Tail;\n                    break;\n\n                default:\n                    return ValueTask.FromException<A>(Errors.IODSLExtension);\n            }\n        }\n\n        return ValueTask.FromCanceled<A>(envIO.Token);\n\n        IO<A> RunCatchHandler(Exception e)\n        {\n            var top       = stack[0];\n            var @catch    = top.Catch;\n            stack = stack.Tail;\n\n            // This must be the last thing because the `@catch` may rethrow,\n            // so we have to have cleaned everything up.\n            return @catch(e);\n        }\n    }\n\n    /// <summary>\n    /// This version of `RunAsync` uses the async/await machinery.  It is kept separate from the `RunAsync` version\n    /// so that we can avoid creating the async/await state-machine if all operations are synchronous.\n    /// </summary>\n    async ValueTask<A> RunAsyncInternal(Seq<StackItem> stack, EnvIO envIO)\n    {\n        var ma = this;\n        while (!envIO.Token.IsCancellationRequested)\n        {\n            switch (ma)\n            {\n                case InvokeAsync<A> op:\n                    try\n                    {\n                        return await op.Invoke(envIO);\n                    }\n                    catch (Exception e)\n                    {\n                        if (stack.IsEmpty) throw;\n                        ma = RunCatchHandler(e);\n                        break;\n                    }\n\n                case InvokeSync<A> op:\n                    try\n                    {\n                        return op.Invoke(envIO);\n                    }\n                    catch (Exception e)\n                    {\n                        if (stack.IsEmpty) throw;\n                        ma = RunCatchHandler(e);\n                        break;\n                    }\n\n                case InvokeSyncIO<A> op:\n                    try\n                    {\n                        ma = op.Invoke(envIO);\n                    }\n                    catch (Exception e)\n                    {\n                        if (stack.IsEmpty) throw;\n                        ma = RunCatchHandler(e);\n                    }\n                    break;\n\n                case InvokeAsyncIO<A> op:\n                    try\n                    {\n                        ma = await op.Invoke(envIO);\n                    }\n                    catch (Exception e)\n                    {\n                        if (stack.IsEmpty) throw;\n                        ma = RunCatchHandler(e);\n                    }\n                    break;\n\n                case IOCatch<A> c:\n                    var @catch = c.MakeHandler();\n                    stack = new StackItem(@catch).Cons(stack);\n                    ma = c.MakeOperation();\n                    break;\n\n                case IOCatchPop<A> pop:\n                    stack = stack.Tail;\n                    ma = pop.Next;\n                    break;\n                \n                case IOTail<A> tail:\n                    ma = tail.Tail;\n                    break;\n\n                default:\n                    return Errors.IODSLExtension.Throw<A>();\n            }\n        }\n\n        throw new OperationCanceledException();\n\n        IO<A> RunCatchHandler(Exception e)\n        {\n            var top    = stack[0];\n            var @catch = top.Catch;\n            stack = stack.Tail;\n\n            // This must be the last thing because the `@catch` may rethrow,\n            // so we have to have cleaned everything up.\n            return @catch(e);\n        }\n    }\n\n    public override string ToString() => \n        \"IO\";\n    \n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Internal\n    //\n    \n    async Task<A> AwaitAsync(Task<A> t, EnvIO envIO, CancellationToken token, CancellationTokenSource source)\n    {\n        if (envIO.Token.IsCancellationRequested) throw new OperationCanceledException();\n        if (token.IsCancellationRequested) throw new OperationCanceledException();\n        await using var reg = envIO.Token.Register(source.Cancel);\n        return await t;        \n    }\n    \n    record CleanUp(CancellationTokenSource Src, CancellationTokenRegistration Reg) : IDisposable\n    {\n        volatile int disposed;\n        public void Dispose()\n        {\n            if (Interlocked.Exchange(ref disposed, 1) == 0)\n            {\n                try{Src.Dispose();} catch { /* not important */ }\n                try{Reg.Dispose();} catch { /* not important */ }\n            }\n        }\n    }\n    \n    readonly record struct StackItem(Func<Exception, IO<A>> Catch); \n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Operators/IO.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    extension<A, B>(K<IO, A> self)\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static IO<B> operator >>> (K<IO, A> ma, K<IO, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<B> operator * (K<IO, Func<A, B>> mf, K<IO, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<B> operator * (K<IO, A> ma, K<IO, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<A, B, C>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, C>> operator * (\n            K<IO, Func<A, B, C>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, C>> operator * (\n            K<IO, A> ma,\n            K<IO, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<A, B, C, D>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, D>>> operator * (\n            K<IO, Func<A, B, C, D>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, D>>> operator * (\n            K<IO, A> ma,\n            K<IO, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<IO, Func<A, B, C, D, E>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<IO, A> ma,\n            K<IO, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<IO, Func<A, B, C, D, E, F>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<IO, A> ma,\n            K<IO, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<IO, Func<A, B, C, D, E, F, G>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<IO, A> ma,\n            K<IO, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G, H>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<IO, Func<A, B, C, D, E, F, G, H>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<IO, A> ma,\n            K<IO, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<IO, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<IO, A> ma,\n            K<IO, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<IO, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<IO, A> ma,\n            K<IO, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<IO, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<IO, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<IO, A> ma,\n            K<IO, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Operators/IO.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    extension<A>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static IO<A> operator |(K<IO, A> lhs, K<IO, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static IO<A> operator |(K<IO, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(rhs.ToIO());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Operators/IO.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    extension<A>(K<IO, A> self)\n    {\n        public static IO<A> operator |(K<IO, A> lhs, CatchM<Error, IO, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static IO<A> operator |(K<IO, A> lhs, Fail<Error> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static IO<A> operator |(K<IO, A> lhs, Error rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Operators/IO.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class IOExtensions\n{\n    extension<X, A>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static IO<A> operator |(K<IO, A> lhs, Finally<IO, X> rhs) =>\n            +lhs.Finally(rhs.Operation);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Operators/IO.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    extension<A, B>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<B> operator *(Func<A, B> f, K<IO, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<B> operator *(K<IO, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<A, B, C>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, C>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<A, B, C, D>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, D>>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H, I, J>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<IO, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static IO<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<IO, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Operators/IO.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    extension<A, B>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static IO<B> operator >> (K<IO, A> ma, Func<A, K<IO, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static IO<B> operator >> (K<IO, A> lhs, K<IO, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<A>(K<IO, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static IO<A> operator >> (K<IO, A> lhs, K<IO, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Operators/IO.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    extension<A>(K<IO, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static IO<A> operator +(K<IO, A> ma) =>\n            (IO<A>)ma;\n        \n        public static IO<A> operator >> (K<IO, A> ma, Lower lower) =>\n            (IO<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Prelude/IO.Prelude.Concurreny.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Generates a new reference that can be used within a `sync` transaction\n    /// \n    /// `Refs` ensure safe shared use of mutable storage locations via a software transactional \n    /// memory (STM) system. `Refs` are bound to a single storage location for their lifetime, \n    /// and only allow mutation of that location to occur within a transaction.\n    /// </summary>\n    /// <remarks>\n    /// \n    /// Transactions (within a `sync(() => ...)`) should be easy to understand if you’ve ever used database \n    /// transactions - they ensure that all actions on Refs are atomic, consistent, and isolated. \n    /// \n    ///  * **Atomic** - means that every change to Refs made within a transaction occurs or none do. \n    ///  * **Consistent** - means that each new value can be checked with a validator function before allowing \n    /// the transaction to commit. \n    ///  * **Isolated** - means that no transaction sees the effects of any other transaction while it is \n    /// running. \n    /// \n    /// Another feature common to STMs is that, should a transaction have a conflict while running, \n    /// it is automatically retried.  The language-ext STM uses multi-version concurrency control for \n    /// snapshot and serialisable isolation.\n    /// \n    /// In practice, this means:\n    ///\n    /// All reads of Refs will see a consistent snapshot of the _Ref world_ as of the starting point \n    /// of the transaction (its 'read point'). The transaction will see any changes it has made. \n    /// This is called the in-transaction-value.\n    ///\n    /// All changes made to Refs during a transaction will appear to occur at a single point in the \n    /// _Ref world_ timeline (its 'write point').\n    ///\n    /// No changes will have been made by any other transactions to any Refs that have been modified \n    /// by this transaction.\n    ///\n    ///  * Readers will never block writers, or other readers.\n    ///\n    ///  * Writers will never block readers.\n    ///\n    /// I/O and other activities with side effects should be avoided in transactions, since transactions \n    /// will be retried. \n    ///\n    /// If a constraint on the validity of a value of a Ref that is being changed depends upon the \n    /// simultaneous value of a Ref that is not being changed, that second Ref can be protected from \n    /// modification by running the `sync` transaction with `Isolation.Serialisable`.\n    ///\n    /// The language-ext STM is designed to work with the persistent collections (`Map`, `HashMap`, \n    /// `Seq`, `Lst`, `Set, `HashSet` etc.), and it is strongly recommended that you use the language-ext \n    /// collections as the values of your Refs. Since all work done in an STM transaction is speculative, \n    /// it is imperative that there be a low cost to making copies and modifications. Persistent collections \n    /// have free copies (just use the original, it can’t be changed), and 'modifications' share structure \n    /// efficiently. In any case:\n    ///\n    /// The values placed in Refs must be, or be considered, **immutable**. Otherwise, this library can’t help you.\n    /// </remarks>\n    /// <remarks>\n    /// See the [concurrency section](https://github.com/louthy/language-ext/wiki/Concurrency) of the wiki for more info.\n    /// </remarks>\n    /// <param name=\"value\">Initial value of the ref</param>\n    /// <param name=\"validator\">Validator that is called on the ref value just\n    /// before any transaction is committed (within a `sync`)</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Ref<A>> refIO<A>(A value, Func<A, bool>? validator = null) =>\n        lift(() => Ref(value, validator));\n        \n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does read from or written to the values used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the strictest form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would *not* cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<R> atomicIO<R>(Func<R> op, Isolation isolation = Isolation.Snapshot) =>\n        lift(() => atomic(op, isolation));\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does read from or written to the values used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the strictest form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would *not* cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Unit> atomicIO(Action op, Isolation isolation = Isolation.Snapshot) =>\n        lift(() => atomic(op, isolation));\n        \n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<R> snapshotIO<R>(Func<R> op) =>\n        lift(() => snapshot(op));\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Snapshot isolation requires that nothing outside the transaction has written to any of the values that are\n    /// *written-to within the transaction*.  If anything does write to the values used within the transaction, then\n    /// the transaction is rolled back and retried (using the latest 'world' state). \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Unit> snapshotIO(Action op) =>\n        lift(() => snapshot(op));\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does read from or written to the values used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the strictest form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would *not* cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<R> serialIO<R>(Func<R> op) =>\n        lift(() => serial(op));\n\n    /// <summary>\n    /// Run the op within a new transaction\n    /// If a transaction is already running, then this becomes part of the parent transaction\n    /// </summary>\n    /// <remarks>\n    /// Serialisable isolation requires that nothing outside the transaction has written to any of the values that\n    /// are *read-from or written-to within the transaction*.  If anything does read from or written to the values used\n    /// within the transaction, then it is rolled back and retried (using the latest 'world' state).\n    ///\n    /// It is the strictest form of isolation, and the most likely to conflict; but protects against cross read/write  \n    /// inconsistencies.  For example, if you have:\n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     snapshot(() => x.Value = y.Value + 1);\n    ///\n    /// Then something writing to `y` mid-way through the transaction would *not* cause the transaction to fail.\n    /// Because `y` was only read-from, not written to.  However, this: \n    ///\n    ///     var x = Ref(1);\n    ///     var y = Ref(2);\n    ///\n    ///     serial(() => x.Value = y.Value + 1);\n    ///\n    /// ... would fail if something wrote to `y`.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Unit> serialIO(Action op) =>\n        lift(() => serial(op));        \n\n    /// <summary>\n    /// Swap the old value for the new returned by `f`\n    /// Must be run within a `sync` transaction\n    /// </summary>\n    /// <param name=\"r\">`Ref` to process</param>\n    /// <param name=\"f\">Function to update the `Ref`</param>\n    /// <returns>The value returned from `f`</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<A> swapIO<A>(Ref<A> r, Func<A, A> f) =>\n        r.SwapIO(f);\n\n    /// <summary>\n    /// Must be called in a transaction. Sets the in-transaction-value of\n    /// ref to:  \n    /// \n    ///     `f(in-transaction-value-of-ref)`\n    ///     \n    /// and returns the in-transaction-value when complete.\n    /// \n    /// At the commit point of the transaction, `f` is run *AGAIN* with the\n    /// most recently committed value:\n    /// \n    ///     `f(most-recently-committed-value-of-ref)`\n    /// \n    /// Thus `f` should be commutative, or, failing that, you must accept\n    /// last-one-in-wins behavior.\n    /// \n    /// Commute allows for more concurrency than just setting the Ref's value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<A> commuteIO<A>(Ref<A> r, Func<A, A> f) =>\n        lift(() => commute(r, f));\n\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks. \n    /// </summary>\n    /// <param name=\"value\">Initial value of the atom</param>\n    /// <returns>The constructed Atom</returns>\n    /// <remarks>\n    /// The intended use of atom is to hold one an immutable data structure. You change \n    /// the value by applying a function to the old value. This is done in an atomic \n    /// manner by `Swap`.  \n    /// \n    /// Internally, `Swap` reads the current value, applies the function to it, and \n    /// attempts to `CompareExchange` it in. Since another thread may have changed the \n    /// value in the intervening time, it may have to retry, and does so in a spin loop. \n    /// \n    /// The net effect is that the value will always be the result of the application \n    /// of the supplied function to a current value, atomically. However, because the \n    /// function might be called multiple times, it must be free of side effects.\n    /// \n    /// Atoms are an efficient way to represent some state that will never need to be \n    /// coordinated with any other, and for which you wish to make synchronous changes.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Atom<A>> atomIO<A>(A value) =>\n        lift(() => Atom(value));\n\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks. \n    /// </summary>\n    /// <param name=\"value\">Initial value of the atom</param>\n    /// <param name=\"validator\">Function to run on the value after each state change.  \n    /// \n    /// If the function returns false for any proposed new state, then the `swap` \n    /// function will return `false`, else it will return `true` on successful setting \n    /// of the atom's state\n    /// </param>\n    /// <returns>The constructed Atom or None if the validation faled for the initial \n    /// `value` </returns>\n    /// <remarks>\n    /// The intended use of atom is to hold one an immutable data structure. You change \n    /// the value by applying a function to the old value. This is done in an atomic \n    /// manner by `Swap`.  \n    /// \n    /// Internally, `Swap` reads the current value, applies the function to it, and \n    /// attempts to `CompareExchange` it in. Since another thread may have changed the \n    /// value in the intervening time, it may have to retry, and does so in a spin loop. \n    /// \n    /// The net effect is that the value will always be the result of the application \n    /// of the supplied function to a current value, atomically. However, because the \n    /// function might be called multiple times, it must be free of side effects.\n    /// \n    /// Atoms are an efficient way to represent some state that will never need to be \n    /// coordinated with any other, and for which you wish to make synchronous changes.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Atom<A>> atomIO<A>(A value, Func<A, bool> validator) =>\n        lift(() => Atom(value, validator) switch\n                   {\n                       { IsSome: true } atom => (Atom<A>)atom,\n                       _                     => throw Exceptions.ValidationFailed\n                   });\n\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks. \n    /// </summary>\n    /// <param name=\"metadata\">Metadata to be passed to the validation function</param>\n    /// <param name=\"value\">Initial value of the atom</param>\n    /// <returns>The constructed Atom</returns>\n    /// <remarks>\n    /// The intended use of atom is to hold one an immutable data structure. You change \n    /// the value by applying a function to the old value. This is done in an atomic \n    /// manner by `Swap`.  \n    /// \n    /// Internally, `Swap` reads the current value, applies the function to it, and \n    /// attempts to `CompareExchange` it in. Since another thread may have changed the \n    /// value in the intervening time, it may have to retry, and does so in a spin loop. \n    /// \n    /// The net effect is that the value will always be the result of the application \n    /// of the supplied function to a current value, atomically. However, because the \n    /// function might be called multiple times, it must be free of side effects.\n    /// \n    /// Atoms are an efficient way to represent some state that will never need to be \n    /// coordinated with any other, and for which you wish to make synchronous changes.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Atom<M, A>> atomIO<M, A>(M metadata, A value) =>\n        lift(() => Atom(metadata, value));\n\n    /// <summary>\n    /// Atoms provide a way to manage shared, synchronous, independent state without \n    /// locks. \n    /// </summary>\n    /// <param name=\"metadata\">Metadata to be passed to the validation function</param>\n    /// <param name=\"value\">Initial value of the atom</param>\n    /// <param name=\"validator\">Function to run on the value after each state change.  \n    /// \n    /// If the function returns false for any proposed new state, then the `swap` \n    /// function will return `false`, else it will return `true` on successful setting \n    /// of the atom's state\n    /// </param>\n    /// <returns>The constructed Atom or None if the validation faled for the initial \n    /// `value` </returns>\n    /// <remarks>\n    /// The intended use of atom is to hold one an immutable data structure. You change \n    /// the value by applying a function to the old value. This is done in an atomic \n    /// manner by `Swap`.  \n    /// \n    /// Internally, `Swap` reads the current value, applies the function to it, and \n    /// attempts to `CompareExchange` it in. Since another thread may have changed the \n    /// value in the intervening time, it may have to retry, and does so in a spin loop. \n    /// \n    /// The net effect is that the value will always be the result of the application \n    /// of the supplied function to a current value, atomically. However, because the \n    /// function might be called multiple times, it must be free of side effects.\n    /// \n    /// Atoms are an efficient way to represent some state that will never need to be \n    /// coordinated with any other, and for which you wish to make synchronous changes.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Atom<M, A>> atomIO<M, A>(M metadata, A value, Func<A, bool> validator) =>\n        lift(() => Atom(metadata, value, validator) switch\n                   {\n                       { IsSome: true } atom => (Atom<M, A>)atom,\n                       _                     => throw Exceptions.ValidationFailed\n                   });\n        \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// If the swap operation fails (which can only happen due to its validator returning false),\n    /// then a snapshot of the current value within the Atom is returned.\n    /// If there is no validator for the Atom then the return value is always the snapshot of\n    /// the successful `f` function. \n    /// </returns>\n    public static IO<A> swapIO<A>(Atom<A> ma, Func<A, A> f) =>\n        ma.SwapIO(f);\n        \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// If the swap operation fails (which can only happen due to its validator returning false),\n    /// then a snapshot of the current value within the Atom is returned.\n    /// If there is no validator for the Atom then the return value is always the snapshot of\n    /// the successful `f` function. \n    /// </returns>\n    public static IO<A> swapIO<M, A>(Atom<M, A> ma, Func<M, A, A> f) =>\n        ma.SwapIO(f);\n        \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// * If `f` returns `None` then no update occurs and the result of the call\n    ///   to `Swap` will be the latest (unchanged) value of `A`.\n    /// * If the swap operation fails, due to its validator returning false, then a snapshot of\n    ///   the current value within the Atom is returned.\n    /// * If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// * If there is no validator for the Atom then the return value is always the snapshot of\n    ///   the successful `f` function. \n    /// </returns>\n    public static IO<A> swapIO<A>(Atom<A> ma, Func<A, Option<A>> f) =>\n        ma.SwapMaybeIO(f);\n        \n    /// <summary>\n    /// Atomically updates the value by passing the old value to `f` and updating\n    /// the atom with the result.  Note: `f` may be called multiple times, so it\n    /// should be free of side effects.\n    /// </summary>\n    /// <param name=\"f\">Function to update the atom</param>\n    /// <returns>\n    /// * If `f` returns `None` then no update occurs and the result of the call\n    ///   to `Swap` will be the latest (unchanged) value of `A`.\n    /// * If the swap operation fails, due to its validator returning false, then a snapshot of\n    ///   the current value within the Atom is returned.\n    /// * If the swap operation succeeded then a snapshot of the value that was set is returned.\n    /// * If there is no validator for the Atom then the return value is always the snapshot of\n    ///   the successful `f` function. \n    /// </returns>\n    public static IO<A> swapIO<M, A>(Atom<M, A> ma, Func<M, A, Option<A>> f) =>\n        ma.SwapIO(f);\n\n    /// <summary>\n    /// Retrieve an IO computation that on each invocation will snapshot of the\n    /// value in an atom\n    /// </summary>\n    /// <param name=\"ma\">Atom to snapshot</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>IO representation of the snapshot</returns>\n    public static IO<A> valueIO<A>(Atom<A> ma) =>\n        ma.ValueIO;\n\n    /// <summary>\n    /// Retrieve an IO computation that on each invocation will snapshot of the\n    /// value in an atom\n    /// </summary>\n    /// <param name=\"ma\">Atom to snapshot</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>IO representation of the snapshot</returns>\n    public static IO<A> valueIO<M, A>(Atom<M, A> ma) =>\n        ma.ValueIO;\n\n    /// <summary>\n    /// Write a value to an atom.\n    /// </summary>\n    /// <remarks>\n    /// Note, this can be dangerous and is usually better to use `swapIO` if the \n    /// `value` is derived from a snapshot of the atom's value (via `valueIO`).\n    /// \n    /// The computation is better run inside the swap operation for atomic consistency.\n    ///\n    /// However, using `writeIO` is reasonable if this is simply a forceful overwrite\n    /// of the atomic value without any dependency on the previous state.   \n    /// </remarks>\n    /// <param name=\"ma\">Atom to write</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>IO representation of the write operation</returns>\n    public static IO<A> writeIO<A>(Atom<A> ma, A value) =>\n        ma.SwapIO(_ => value);\n\n    /// <summary>\n    /// Write a value to an atom.\n    /// </summary>\n    /// <remarks>\n    /// Note, this can be dangerous and is usually better to use `swapIO` if the \n    /// `value` is derived from a snapshot of the atom's value (via `valueIO`).\n    /// \n    /// The computation is better run inside the swap operation for atomic consistency.\n    ///\n    /// However, using `writeIO` is reasonable if this is simply a forceful overwrite\n    /// of the atomic value without any dependency on the previous state.   \n    /// </remarks>\n    /// <param name=\"ma\">Atom to write</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>IO representation of the write operation</returns>\n    public static IO<A> writeIO<M, A>(Atom<M, A> ma, A value) =>\n        ma.SwapIO((_, _) => value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Prelude/IO.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.DSL;\nusing LanguageExt.Traits;\nusing LanguageExt.UnsafeValueAccess;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Access the cancellation-token from the IO environment\n    /// </summary>\n    /// <returns>CancellationToken</returns>\n    public static readonly IO<CancellationToken> cancelToken =\n        IO.lift(e => e.Token);\n\n    /// <summary>\n    /// Request a cancellation of the IO expression\n    /// </summary>\n    public static readonly IO<Unit> cancel =\n        IO.lift<Unit>(\n            e =>\n            {\n                e.Source.Cancel();\n                throw new OperationCanceledException();\n            });\n    \n    /// <summary>\n    /// Always yields a `Unit` value\n    /// </summary>\n    public static readonly IO<Unit> unitIO = \n        IO.pure<Unit>(default);\n    \n    /// <summary>\n    /// Yields the IO environment\n    /// </summary>\n    public static readonly IO<EnvIO> envIO = \n        IO.lift<EnvIO>(e => e);\n\n    /// <summary>\n    /// Tail call \n    /// </summary>\n    /// <param name=\"tailIO\"></param>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    public static IO<A> tail<A>(IO<A> tailIO) =>\n        new IOTail<A>(tailIO);\n\n    /// <summary>\n    /// Wraps this computation in a local-environment that ignores any cancellation-token cancellation requests.\n    /// </summary>\n    /// <returns>An uninterruptible computation</returns>\n    public static IO<A> uninterruptible<A>(IO<A> ma) =>\n        ma.Uninterruptible();\n\n    /// <summary>\n    /// Yield the thread for the specified duration or until cancelled.\n    /// </summary>\n    /// <param name=\"duration\">Amount of time to yield for</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<Unit> yieldFor(Duration duration) =>\n        IO.yieldFor(duration);\n\n    /// <summary>\n    /// Yield the thread for the specified duration or until cancelled.\n    /// </summary>\n    /// <param name=\"timeSpan\">Amount of time to yield for</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<Unit> yieldFor(TimeSpan timeSpan) =>\n        IO.yieldFor(timeSpan);\n\n    /// <summary>\n    /// Awaits all \n    /// </summary>\n    /// <param name=\"forks\">IO operations to await</param>\n    /// <returns>Sequence of results</returns>\n    public static IO<Seq<A>> awaitAll<A>(params ForkIO<A>[] forks) =>\n        awaitAll(forks.ToSeqUnsafe());\n\n    /// <summary>\n    /// Awaits all operations\n    /// </summary>\n    /// <param name=\"ms\">Operations to await</param>\n    /// <returns>Sequence of results</returns>\n    public static IO<Seq<A>> awaitAll<A>(Seq<IO<A>> ms) =>\n        IO.liftAsync(async eio =>\n                     {\n                         var result = await Task.WhenAll(ms.Map(io => io.RunAsync(eio).AsTask()));\n                         return result.ToSeqUnsafe();\n                     });\n\n    /// <summary>\n    /// Awaits all \n    /// </summary>\n    /// <param name=\"forks\">IO operations to await</param>\n    /// <returns>Sequence of results</returns>\n    public static IO<Seq<A>> awaitAll<A>(Seq<IO<ForkIO<A>>> forks) =>\n        IO.liftAsync(async eio =>\n                     {\n                         var forks1 = forks.Map(mf => mf.Run(eio));\n                         var result = await Task.WhenAll(forks1.Map(f => f.Await.RunAsync(eio).AsTask()));\n                         return result.ToSeqUnsafe();\n                     });\n\n    /// <summary>\n    /// Awaits all \n    /// </summary>\n    /// <param name=\"forks\">IO operations to await</param>\n    /// <returns>Sequence of results</returns>\n    public static IO<Seq<A>> awaitAll<A>(Seq<ForkIO<A>> forks) =>\n        IO.liftAsync(async eio =>\n                     {\n                         var result = await Task.WhenAll(forks.Map(f => f.Await.RunAsync(eio).AsTask()));\n                         return result.ToSeqUnsafe();\n                     });\n\n    /// <summary>\n    /// Awaits for any IO to complete\n    /// </summary>\n    /// <param name=\"ms\">IO operations to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    public static IO<A> awaitAny<A>(params IO<A>[] ms) =>\n        awaitAny(ms.ToSeqUnsafe());\n\n    /// <summary>\n    /// Awaits for any IO to complete\n    /// </summary>\n    /// <param name=\"ms\">IO operations to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    public static IO<A> awaitAny<A>(params K<IO, A>[] ms) =>\n        awaitAny(ms.ToSeqUnsafe());\n\n    /// <summary>\n    /// Awaits for any forks to complete\n    /// </summary>\n    /// <param name=\"forks\">Forks to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    public static IO<A> awaitAny<A>(params IO<ForkIO<A>>[] forks) =>\n        awaitAny(forks.ToSeqUnsafe());\n\n    /// <summary>\n    /// Awaits for any forks to complete\n    /// </summary>\n    /// <param name=\"forks\">Forks to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    public static IO<A> awaitAny<A>(params ForkIO<A>[] forks) =>\n        awaitAny(forks.ToSeqUnsafe());\n\n    /// <summary>\n    /// Awaits for any IO to complete\n    /// </summary>\n    /// <param name=\"ms\">IO operations to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    public static IO<A> awaitAny<A>(Seq<K<IO, A>> ms) =>\n        awaitAny(ms.Map(m => m.As()));\n    \n    /// <summary>\n    /// Awaits for any IO to complete\n    /// </summary>\n    /// <param name=\"ms\">IO operations to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    public static IO<A> awaitAny<A>(Seq<IO<A>> ms) =>\n        IO.liftAsync(async eio =>\n                     {\n                         if(eio.Token.IsCancellationRequested) throw new OperationCanceledException();\n                         using var lenv = eio.LocalCancel;\n                         var result = await await Task.WhenAny(ms.Map(io => io.RunAsync(lenv).AsTask()));\n                         await lenv.Source.CancelAsync();\n                         return result;\n                     });\n\n    /// <summary>\n    /// Awaits for any forks to complete\n    /// </summary>\n    /// <param name=\"forks\">Forks to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    public static IO<A> awaitAny<A>(Seq<ForkIO<A>> forks) =>\n        IO.liftAsync(async eio =>\n                     {\n                         if(eio.Token.IsCancellationRequested) throw new OperationCanceledException();\n                         using var lenv = eio.LocalCancel;\n                         var result = await await Task.WhenAny(forks.Map(f => f.Await.RunAsync(eio).AsTask()));\n                         await lenv.Source.CancelAsync();\n                         return result;\n                     });\n\n    /// <summary>\n    /// Awaits for any forks to complete\n    /// </summary>\n    /// <param name=\"forks\">Forks to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    public static IO<A> awaitAny<A>(Seq<IO<ForkIO<A>>> forks) =>\n        IO.liftAsync(async eio =>\n                     {\n                         if(eio.Token.IsCancellationRequested) throw new OperationCanceledException();\n                         using var lenv   = eio.LocalCancel;\n                         var       forks1 = forks.Map(mf => mf.Run(lenv));\n                         var       result = await await Task.WhenAny(forks1.Map(f => f.Await.RunAsync(eio).AsTask()));\n                         await lenv.Source.CancelAsync();\n                         return result;\n                     });\n    \n    /// <summary>\n    /// Timeout operation if it takes too long\n    /// </summary>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> timeout<A>(TimeSpan timeout, K<IO, A> ma) => \n        ma.As().Timeout(timeout);\n    \n    /// <summary>\n    /// Keeps repeating the computation   \n    /// </summary>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    public static IO<A> repeat<A>(IO<A> ma) =>\n        ma.Repeat();\n\n    /// <summary>\n    /// Keeps repeating the computation until the scheduler expires  \n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    public static IO<A> repeat<A>(Schedule schedule, K<IO, A> ma) =>\n        ma.As().Repeat(schedule);\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns false\n    /// </summary>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    public static IO<A> repeatWhile<A>(IO<A> ma, Func<A, bool> predicate) => \n        ma.As().RepeatWhile(predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation until the scheduler expires, or the predicate returns false\n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    public static IO<A> repeatWhile<A>(\n        Schedule schedule,\n        K<IO, A> ma,\n        Func<A, bool> predicate) => \n        ma.As().RepeatWhile(schedule, predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns true\n    /// </summary>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    public static IO<A> repeatUntil<A>(\n        K<IO, A> ma,\n        Func<A, bool> predicate) =>\n        ma.As().RepeatUntil(predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation until the scheduler expires, or the predicate returns true\n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    public static IO<A> repeatUntil<A>(\n        Schedule schedule,\n        K<IO, A> ma,\n        Func<A, bool> predicate) => \n        ma.As().RepeatUntil(schedule, predicate);\n\n    /// <summary>\n    /// Keeps retrying the computation   \n    /// </summary>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    public static IO<A> retry<A>(K<IO, A> ma) => \n        ma.As().Retry();\n\n    /// <summary>\n    /// Keeps retrying the computation until the scheduler expires  \n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for retrying</param>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    public static IO<A> retry<A>(Schedule schedule, K<IO, A> ma) => \n        ma.As().Retry(schedule);\n\n    /// <summary>\n    /// Keeps retrying the computation until the predicate returns false\n    /// </summary>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    public static IO<A> retryWhile<A>(\n        K<IO, A> ma,\n        Func<Error, bool> predicate) => \n        ma.As().RetryWhile(predicate);\n\n    /// <summary>\n    /// Keeps retrying the computation until the scheduler expires, or the predicate returns false\n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for retrying</param>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    public static IO<A> retryWhile<A>(\n        Schedule schedule,\n        K<IO, A> ma,\n        Func<Error, bool> predicate) => \n        ma.As().RetryWhile(schedule, predicate);\n\n    /// <summary>\n    /// Keeps retrying the computation until the predicate returns true\n    /// </summary>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    public static IO<A> retryUntil<A>(\n        K<IO, A> ma,\n        Func<Error, bool> predicate) => \n        ma.As().RetryUntil(predicate);\n\n    /// <summary>\n    /// Keeps retrying the computation until the scheduler expires, or the predicate returns true\n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for retrying</param>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    public static IO<A> retryUntil<A>(\n        Schedule schedule,\n        K<IO, A> ma,\n        Func<Error, bool> predicate) => \n        ma.As().RetryUntil(schedule, predicate);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Prelude/IO.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static IO<B> map<A, B>(Func<A, B> f, K<IO, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static IO<B> action<A, B>(K<IO, A> ma, K<IO, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static IO<B> apply<A, B>(K<IO, Func<A, B>> mf, K<IO, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Effects/IO/Resources.cs",
    "content": "using System;\nusing System.Threading;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Holds the acquired resources for the `ResourceT` monad transformer\n/// </summary>\npublic class Resources : IDisposable\n{\n    readonly AtomHashMap<object, TrackedResource> resources = AtomHashMap<object, TrackedResource>();\n    readonly Resources? parent;\n\n    public Resources(Resources? parent) =>\n        this.parent = parent;\n\n    public static IO<Resources> NewIO(Resources? parent) => \n        IO.lift(_ => new Resources(parent));\n    \n    public void Dispose()\n    {\n        var s = new CancellationTokenSource();\n        var e = EnvIO.New(this, default, s, SynchronizationContext.Current);\n        DisposeU(e);\n    }\n    \n    public Unit DisposeU(EnvIO envIO)\n    {\n        if(resources.IsEmpty) return unit;\n        using var source = new CancellationTokenSource();\n        var disposeEnv = new EnvIO(envIO.Resources, CancellationToken.None, source, envIO.SyncContext, null, 0);\n        foreach (var item in resources)\n        {\n            item.Value.Release().Run(disposeEnv);\n        }\n        return default;\n    }\n\n    public Unit DisposeU()\n    {\n        Dispose();\n        return default;\n    }\n\n    public IO<Unit> DisposeIO() =>\n        IO.lift(_ => DisposeU());\n\n    public Unit Acquire<A>(A value) where A : IDisposable\n    {\n        var obj = (object?)value;\n        if (obj is null) throw new InvalidCastException();\n        return resources.TryAdd(obj, new TrackedResourceDisposable<A>(value));\n    }\n\n    public Unit AcquireAsync<A>(A value) where A : IAsyncDisposable\n    {\n        var obj = (object?)value;\n        if (obj is null) throw new InvalidCastException();\n        return resources.TryAdd(obj, new TrackedResourceAsyncDisposable<A>(value));\n    }\n\n    public Unit Acquire<A>(A value, Func<A, IO<Unit>> release) \n    {\n        var obj = (object?)value;\n        if (obj is null) throw new InvalidCastException();\n        return resources.TryAdd(obj, new TrackedResourceWithFree<A>(value, release));\n    }\n\n    public IO<Unit> Release<A>(A value)\n    {\n        var obj = (object?)value;\n        if (obj is null) throw new InvalidCastException();\n        return resources.Find(obj)\n                        .Match(Some: f =>\n                                     {\n                                         resources.Remove(obj);\n                                         return f.Release();\n                                     },\n                               None: () => parent is null \n                                               ? unitIO\n                                               : parent.Release(value));\n    }\n\n    public IO<Unit> ReleaseAll() =>\n        IO.lift(envIO =>\n                {\n                    resources.Swap(\n                        r =>\n                        {\n                            foreach (var kv in r)\n                            {\n                                kv.Value.Release().Run(envIO);\n                            }\n                            return [];\n                        });\n                    return unit;\n                });\n    \n    internal Unit Merge(Resources rhs) =>\n        resources.Swap(r => r.AddRange(rhs.resources.AsIterable()));\n}\n\nabstract record TrackedResource\n{\n    public abstract IO<Unit> Release();\n}\n\n/// <summary>\n/// Holds a resource with its disposal function\n/// </summary>\nrecord TrackedResourceWithFree<A>(A Value, Func<A, IO<Unit>> Dispose) : TrackedResource\n{\n    public override IO<Unit> Release() => \n        Dispose(Value);\n}\n\n/// <summary>\n/// Holds a resource with its disposal function\n/// </summary>\nrecord TrackedResourceDisposable<A>(A Value) : TrackedResource\n    where A : IDisposable\n{\n    public override IO<Unit> Release() =>\n        Value switch\n        {\n            IAsyncDisposable disposable => IO.liftAsync(async () =>\n                                                        {\n                                                            await disposable.DisposeAsync().ConfigureAwait(false);\n                                                            return unit;\n                                                        }),\n\n            _ => IO.lift(() =>\n                         {\n                             Value.Dispose();\n                             return unit;\n                         })\n        };\n}\n\n/// <summary>\n/// Holds a resource with its disposal function\n/// </summary>\nrecord TrackedResourceAsyncDisposable<A>(A Value) : TrackedResource\n    where A : IAsyncDisposable\n{\n    public override IO<Unit> Release() =>\n        IO.liftAsync(async () =>\n                     {\n                         await Value.DisposeAsync().ConfigureAwait(false);\n                         return unit;\n                     });\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/MinRT.cs",
    "content": "namespace LanguageExt.Effects;\n\n/// <summary>\n/// Minimal runtime for running the non-runtime based IO monads\n/// </summary>\npublic readonly struct MinRT;\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Prelude.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.UnsafeValueAccess;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Tail call \n    /// </summary>\n    /// <param name=\"ma\"></param>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<M, A> tailIO<M, A>(K<M, A> ma) \n        where M : MonadUnliftIO<M> =>\n        ma.MapIO(tail);\n    \n    /// <summary>\n    /// Make this computation run on the `SynchronizationContext` that was captured at the start\n    /// of the IO chain (i.e. the one embedded within the `EnvIO` environment that is passed through\n    /// all IO computations)\n    /// </summary>\n    [Pure]\n    public static K<M, A> postIO<M, A>(K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        M.PostIO(ma);        \n\n    /// <summary>\n    /// Queue this IO operation to run on the thread-pool. \n    /// </summary>\n    /// <param name=\"timeout\">Maximum time that the forked IO operation can run for. `None` for no timeout.</param>\n    /// <returns>Returns a `ForkIO` data-structure that contains two IO effects that can be used to either cancel\n    /// the forked IO operation or to await the result of it.\n    /// </returns>\n    [Pure]\n    public static K<M, B> mapIO<M, A, B>(K<M, A> ma, Func<IO<A>, IO<B>> f)\n        where M : MonadUnliftIO<M>, Monad<M> =>\n        M.MapIO(ma, f);    \n\n    /// <summary>\n    /// Wraps this computation in a local-environment that ignores any cancellation-token cancellation requests.\n    /// </summary>\n    /// <returns>An uninterruptible computation</returns>\n    [Pure]\n    public static K<M, A> uninterruptible<M, A>(K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        M.UninterruptibleIO(ma);\n    \n    /// <summary>\n    /// Creates a local cancellation environment\n    /// </summary>\n    /// <remarks>\n    /// A local cancellation environment stops other IO computations, that rely on the same\n    /// environmental cancellation token, from being taken down by a regional cancellation.\n    ///\n    /// If an `IO.cancel` is invoked locally, then it will still create an exception that\n    /// propagates upwards and so catching cancellations is still important. \n    /// </remarks>\n    /// <param name=\"ma\">Computation to run within the local context</param>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Result of the computation</returns>\n    [Pure]\n    public static K<M, A> localIO<M, A>(K<M, A> ma) \n        where M : MonadUnliftIO<M> =>\n        M.LocalIO(ma);\n\n    /// <summary>\n    /// Queue this IO operation to run on the thread-pool. \n    /// </summary>\n    /// <param name=\"timeout\">Maximum time that the forked IO operation can run for. `None` for no timeout.</param>\n    /// <returns>Returns a `ForkIO` data-structure that contains two IO effects that can be used to either cancel\n    /// the forked IO operation or to await the result of it.\n    /// </returns>\n    [Pure]\n    public static K<M, ForkIO<A>> fork<M, A>(K<M, A> ma, Option<TimeSpan> timeout = default)\n        where M : MonadUnliftIO<M>, Monad<M> =>\n        M.ForkIO(ma, timeout);\n\n    /// <summary>\n    /// Queue this IO operation to run on the thread-pool. \n    /// </summary>\n    /// <param name=\"timeout\">Maximum time that the forked IO operation can run for. `None` for no timeout.</param>\n    /// <returns>Returns a `ForkIO` data-structure that contains two IO effects that can be used to either cancel\n    /// the forked IO operation or to await the result of it.\n    /// </returns>\n    [Pure]\n    public static K<M, A> awaitIO<M, A>(K<M, ForkIO<A>> ma)\n        where M : MonadUnliftIO<M> =>\n        M.Await(ma);\n    \n    /// <summary>\n    /// Awaits all operations\n    /// </summary>\n    /// <param name=\"ms\">Operations to await</param>\n    /// <returns>Sequence of results</returns>\n    [Pure]\n    public static K<M, Seq<A>> awaitAll<M, A>(params K<M, A>[] ms)\n        where M : MonadUnliftIO<M> =>\n        awaitAll(ms.ToSeqUnsafe());\n    \n    /// <summary>\n    /// Awaits all forks\n    /// </summary>\n    /// <param name=\"forks\">Forks to await</param>\n    /// <returns>Sequence of results</returns>\n    [Pure]\n    public static K<M, Seq<A>> awaitAll<M, A>(params K<M, ForkIO<A>>[] forks)\n        where M : MonadUnliftIO<M> =>\n        awaitAll(forks.ToSeqUnsafe());\n    \n    /// <summary>\n    /// Awaits all operations\n    /// </summary>\n    /// <param name=\"ms\">Operations to await</param>\n    /// <returns>Sequence of results</returns>\n    [Pure]\n    public static K<M, Seq<A>> awaitAll<M, A>(Seq<K<M, A>> ms)\n        where M : MonadUnliftIO<M> =>\n        ms.Traverse(f => f.ToIO())\n          .Bind(awaitAll);\n    \n    /// <summary>\n    /// Awaits all forks\n    /// </summary>\n    /// <param name=\"forks\">Forks to await</param>\n    /// <returns>Sequence of results</returns>\n    [Pure]\n    public static K<M, Seq<A>> awaitAll<M, A>(Seq<K<M, ForkIO<A>>> forks)\n        where M : MonadUnliftIO<M> =>\n        forks.TraverseM(f => f.Await());\n\n    /// <summary>\n    /// Awaits for any operation to complete\n    /// </summary>\n    /// <param name=\"ms\">Operations to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    [Pure]\n    public static K<M, A> awaitAny<M, A>(params K<M, A>[] ms)\n        where M : MonadUnliftIO<M> =>\n        awaitAny(ms.ToSeqUnsafe());\n\n    /// <summary>\n    /// Awaits for any forks to complete\n    /// </summary>\n    /// <param name=\"forks\">Forks to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    [Pure]\n    public static K<M, A> awaitAny<M, A>(params K<M, ForkIO<A>>[] forks)\n        where M : MonadUnliftIO<M> =>\n        awaitAny(forks.ToSeqUnsafe());\n\n    /// <summary>\n    /// Awaits for any forks to complete\n    /// </summary>\n    /// <param name=\"forks\">Forks to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    [Pure]\n    public static K<M, A> awaitAny<M, A>(Seq<K<M, ForkIO<A>>> forks)\n        where M : MonadUnliftIO<M> =>\n        forks.Traverse(f => f.ToIO())\n             .Bind(awaitAny);\n\n    /// <summary>\n    /// Awaits for operations to complete\n    /// </summary>\n    /// <param name=\"ms\">Operations to await</param>\n    /// <returns>\n    /// If we get one success, then we'll return straight away and cancel the others.\n    /// If we get any errors, we'll collect them in the hope that at least one works.\n    /// If we have collected as many errors as we have forks, then we'll return them all.\n    /// </returns>\n    [Pure]\n    public static K<M, A> awaitAny<M, A>(Seq<K<M, A>> forks)\n        where M : MonadUnliftIO<M> =>\n        forks.Traverse(f => f.ToIO())\n             .Bind(awaitAny);\n\n    /// <summary>\n    /// Timeout operation if it takes too long\n    /// </summary>\n    [Pure]\n    public static K<M, A> timeout<M, A>(TimeSpan timeout, K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        ma.TimeoutIO(timeout);\n    \n    /// <summary>\n    /// Keeps repeating the computation   \n    /// </summary>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    [Pure]\n    public static K<M, A> repeat<M, A>(K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        ma.RepeatIO();\n\n    /// <summary>\n    /// Keeps repeating the computation, until the scheduler expires  \n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    [Pure]\n    public static K<M, A> repeat<M, A>(Schedule schedule, K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        ma.RepeatIO(schedule);\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns false\n    /// </summary>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    [Pure]\n    public static K<M, A> repeatWhile<M, A>(K<M, A> ma, Func<A, bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        ma.RepeatWhileIO(predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation until the scheduler expires, or the predicate returns false\n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    [Pure]\n    public static K<M, A> repeatWhile<M, A>(\n        Schedule schedule,\n        K<M, A> ma,\n        Func<A, bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        ma.RepeatWhileIO(schedule, predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns true\n    /// </summary>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    [Pure]\n    public static K<M, A> repeatUntil<M, A>(\n        K<M, A> ma,\n        Func<A, bool> predicate)\n        where M : MonadUnliftIO<M> =>\n        ma.RepeatUntilIO(predicate);\n\n    /// <summary>\n    /// Keeps repeating the computation until the scheduler expires, or the predicate returns true\n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"ma\">Computation to repeat</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of `ma`</returns>\n    [Pure]\n    public static K<M, A> repeatUntil<M, A>(\n        Schedule schedule,\n        K<M, A> ma,\n        Func<A, bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        ma.RepeatUntilIO(schedule, predicate);\n\n    /// <summary>\n    /// Keeps retrying the computation   \n    /// </summary>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    [Pure]\n    public static K<M, A> retry<M, A>(K<M, A> ma) \n        where M : MonadUnliftIO<M> =>\n        ma.RetryIO();\n\n    /// <summary>\n    /// Keeps retrying the computation until the scheduler expires  \n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for retrying</param>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    [Pure]\n    public static K<M, A> retry<M, A>(Schedule schedule, K<M, A> ma) \n        where M : MonadUnliftIO<M> =>\n        ma.RetryIO(schedule);\n\n    /// <summary>\n    /// Keeps retrying the computation until the predicate returns false\n    /// </summary>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    [Pure]\n    public static K<M, A> retryWhile<M, A>(\n        K<M, A> ma,\n        Func<Error, bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        ma.RetryWhileIO(predicate);\n\n    /// <summary>\n    /// Keeps retrying the computation until the scheduler expires, or the predicate returns false\n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for retrying</param>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    [Pure]\n    public static K<M, A> retryWhile<M, A>(\n        Schedule schedule,\n        K<M, A> ma,\n        Func<Error, bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        ma.RetryWhileIO(schedule, predicate);\n\n    /// <summary>\n    /// Keeps retrying the computation until the predicate returns true\n    /// </summary>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    [Pure]\n    public static K<M, A> retryUntil<M, A>(\n        K<M, A> ma,\n        Func<Error, bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        ma.RetryUntilIO(predicate);\n\n    /// <summary>\n    /// Keeps retrying the computation until the scheduler expires, or the predicate returns true\n    /// </summary>\n    /// <param name=\"schedule\">Scheduler strategy for retrying</param>\n    /// <param name=\"ma\">Computation to retry</param>\n    /// <typeparam name=\"A\">Computation bound value type</typeparam>\n    /// <returns>The result of the last invocation of ma</returns>\n    [Pure]\n    public static K<M, A> retryUntil<M, A>(\n        Schedule schedule,\n        K<M, A> ma,\n        Func<Error, bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        ma.RetryUntilIO(schedule, predicate);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/README.md",
    "content": "Effects are functorial, monadic, and applicative types that are designed to capture IO based side-effects.    \n\n| Section              | Type                                          | Description                                                                                                                                                                                                                     |\n|----------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [`IO`](IO)           | [`IO<A>`](IO)                                 | Asynchronous and synchronous IO.  Captures side-effects, manages resources, but throws exceptions.  The `IO` monad is the base of all IO based operations and should be used in your monad-transformer stacks when you need IO. |\n| [`Eff`](Eff)         | [`Eff<A>`](Eff)                               | Asynchronous and synchronous IO.  Captures side-effects, manages resources, handles exceptions elegantly.                                                                                                                       |\n| [`Eff`](Eff)         | [`Eff<RT, A>`](Eff)                           | Asynchronous and synchronous IO.  Captures side-effects, manages resources, handles exceptions elegantly, and has an injectable runtime (`RT`) which can provide configuration and dependency-injection                         |\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Schedule/Duration.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Period of time in milliseconds.\n/// Can be used to convert between other duration like types, such as TimeSpan and Time.\n/// </summary>\npublic readonly struct Duration :\n    IEquatable<Duration>,\n    IComparable<Duration>\n{\n    public readonly double Milliseconds;\n\n    /// <summary>\n    /// Duration constructor\n    /// </summary>\n    /// <param name=\"milliseconds\">Magnitude of the duration.  Must be zero or a positive value</param>\n    /// <exception cref=\"ArgumentException\">Throws if `milliseconds` is less than `0`</exception>\n    public Duration(double milliseconds)\n    {\n        if (milliseconds < 0) throw new ArgumentException($\"{nameof(milliseconds)} must be a positive number.\");\n        Milliseconds = milliseconds;\n    }\n\n    /// <summary>\n    /// Zero magnitude duration (instant)\n    /// </summary>\n    public static Duration Zero =\n        new(0);\n    \n    /// <summary>\n    /// Return true if the time duration is zero\n    /// </summary>\n    public bool IsZero =>\n        Milliseconds < 0.00000000001;\n\n    /// <summary>\n    /// Random duration between the provided min and max durations. \n    /// </summary>\n    /// <remarks>\n    /// This can be used to seed a schedule in parallel.\n    /// Providing another method of de-correlation.\n    ///\n    /// For example, this is a linear schedule that,\n    ///\n    /// - starts with a seed duration between 10 and 50 milliseconds\n    /// - includes a 10% jitter, added and removed in sequence from each duration\n    /// - recurring 5 times\n    ///\n    ///     Schedule.linear(Duration.Random(10*ms, 50*ms)) | Schedule.decorrelate() | Schedule.recurs(5)\n    ///\n    /// Three runs result in,\n    ///\n    ///     (25ms, 23ms, 50ms, 47ms, 72ms)\n    ///     (13ms, 11ms, 25ms, 23ms, 40ms)\n    ///     (28ms, 25ms, 56ms, 53ms, 87ms)\n    ///\n    /// </remarks>\n    /// <param name=\"min\">min duration</param>\n    /// <param name=\"max\">max duration</param>\n    /// <param name=\"seed\">optional seed</param>\n    /// <returns>random duration between min and max duration</returns>\n    [Pure]\n    public static Duration random(Duration min, Duration max, Option<int> seed = default)\n        => new(SingletonRandom.Uniform(min, max, seed));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Duration(double milliseconds) =>\n        new(milliseconds);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Duration(TimeSpan timeSpan) =>\n        new(timeSpan.TotalMilliseconds);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Duration(Time time) =>\n        new(time.Milliseconds);\n\n    [Pure]\n    public static implicit operator double(Duration duration) =>\n        duration.Milliseconds;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static explicit operator TimeSpan(Duration duration) =>\n        TimeSpan.FromMilliseconds(duration.Milliseconds);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static explicit operator Time(Duration duration) =>\n        duration.Milliseconds.Milliseconds();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(Duration a, Duration b) =>\n        a.Milliseconds.Equals(b.Milliseconds);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(Duration a, Duration b) =>\n        !(a == b);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(Duration other) =>\n        Milliseconds.Equals(other);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is Duration other && Equals(other);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        Milliseconds.GetHashCode();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(Duration other) =>\n        Milliseconds.CompareTo(other);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >(Duration a, Duration b) =>\n        a.CompareTo(b) > 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >=(Duration a, Duration b) =>\n        a.CompareTo(b) >= 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <(Duration a, Duration b) =>\n        a.CompareTo(b) < 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <=(Duration a, Duration b) =>\n        a.CompareTo(b) <= 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        $\"{nameof(Duration)}({(TimeSpan)this})\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Schedule/Schedule.Constructors.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic abstract partial record Schedule\n{\n    /// <summary>\n    /// Identity or no-op schedule result transformer\n    /// </summary>\n    public static readonly ScheduleTransformer Identity =\n        Transform(identity);\n\n    /// <summary>\n    /// `Schedule` constructor that recurs for the specified durations\n    /// </summary>\n    /// <param name=\"durations\">durations to apply</param>\n    [Pure]\n    public static Schedule TimeSeries(params Duration[] durations) =>\n        new SchItems(durations.AsIterable());\n\n    /// <summary>\n    /// `Schedule` constructor that recurs for the specified durations\n    /// </summary>\n    /// <param name=\"durations\">durations to apply</param>\n    [Pure]\n    public static Schedule TimeSeries(Arr<Duration> durations) =>\n        new SchItems(durations.AsIterable());\n\n    /// <summary>\n    /// `Schedule` constructor that recurs for the specified durations\n    /// </summary>\n    /// <param name=\"durations\">durations to apply</param>\n    [Pure]\n    public static Schedule TimeSeries(Seq<Duration> durations) =>\n        new SchItems(durations.AsIterable());\n\n    /// <summary>\n    /// `Schedule` constructor that recurs for the specified durations\n    /// </summary>\n    /// <param name=\"durations\">durations to apply</param>\n    [Pure]\n    public static Schedule TimeSeries(Lst<Duration> durations) =>\n        new SchItems(durations.AsIterable());\n\n    /// <summary>\n    /// `Schedule` constructor that recurs for the specified durations\n    /// </summary>\n    /// <param name=\"durations\">durations to apply</param>\n    [Pure]\n    public static Schedule TimeSeries(Set<Duration> durations) =>\n        new SchItems(IterableExtensions.AsIterable(durations.Value));\n\n    /// <summary>\n    /// `Schedule` constructor that recurs for the specified durations\n    /// </summary>\n    /// <param name=\"durations\">durations to apply</param>\n    [Pure]\n    public static Schedule TimeSeries(HashSet<Duration> durations) =>\n        new SchItems(durations.AsIterable());\n    \n    /// <summary>\n    /// `ScheduleTransformer` constructor which provides mapping capabilities for `Schedule` instances\n    /// </summary>\n    /// <param name=\"transform\">Transformation function</param>\n    /// <returns>`ScheduleTransformer`</returns>\n    [Pure]\n    public static ScheduleTransformer Transform(Func<Schedule, Schedule> transform) =>\n        new(transform);\n\n    /// <summary>\n    /// Schedule that runs forever\n    /// </summary>\n    public static readonly Schedule Forever =\n        SchForever.Default;\n    \n    /// <summary>\n    /// Schedule that never runs\n    /// </summary>\n    public static readonly Schedule Never =\n        SchNever.Default;\n\n    /// <summary>\n    /// Schedule that runs once\n    /// </summary>\n    public static readonly Schedule Once =\n        Forever.Take(1);\n\n    /// <summary>\n    /// A schedule transformer that will enforce the first retry has no delay\n    /// </summary>\n    public static readonly ScheduleTransformer NoDelayOnFirst =\n        Transform(s => s.Tail.Prepend(Duration.Zero));\n\n    /// <summary>\n    /// Repeats the schedule forever\n    /// </summary>\n    public static readonly ScheduleTransformer RepeatForever =\n        Transform(s => new SchRepeatForever(s));\n\n    /// <summary>\n    /// Schedule transformer that limits the schedule to run the specified number of times\n    /// </summary>\n    /// <param name=\"times\">number of times</param>\n    [Pure]\n    public static ScheduleTransformer recurs(int times) =>\n        Transform(s => s.Take(times));\n\n    /// <summary>\n    /// Schedule that recurs continuously with the given spacing\n    /// </summary>\n    /// <param name=\"space\">space</param>\n    [Pure]\n    public static Schedule spaced(Duration space) =>\n        Forever.Map(_ => space);\n\n    /// <summary>\n    /// Schedule that recurs continuously using a linear backoff\n    /// </summary>\n    /// <param name=\"seed\">seed</param>\n    /// <param name=\"factor\">optional factor to apply, default 1</param>\n    [Pure]\n    public static Schedule linear(Duration seed, double factor = 1) =>\n        new SchLinear(seed, factor);\n\n    /// <summary>\n    /// Schedule that recurs continuously using a exponential backoff\n    /// </summary>\n    /// <param name=\"seed\">seed</param>\n    /// <param name=\"factor\">optional factor to apply, default 2</param>\n    [Pure]\n    public static Schedule exponential(Duration seed, double factor = 2) =>\n        Forever.Map((_, i) => seed * Math.Pow(factor, i));\n\n    /// <summary>\n    /// Schedule that recurs continuously using a fibonacci based backoff\n    /// </summary>\n    /// <param name=\"seed\">seed</param>\n    [Pure]\n    public static Schedule fibonacci(Duration seed) =>\n        new SchFibonacci(seed);\n\n    internal static readonly Func<DateTime> LiveNowFn =\n        () => DateTime.Now;\n\n    /// <summary>\n    /// Schedule that runs for a given duration\n    /// </summary>\n    /// <param name=\"max\">max duration to run the schedule for</param>\n    /// <param name=\"currentTimeFn\">current time function</param>\n    [Pure]\n    public static Schedule upto(Duration max, Func<DateTime>? currentTimeFn = null) =>\n        new SchUpTo(max, currentTimeFn);\n\n    [Pure]\n    internal static Duration secondsToIntervalStart(DateTime startTime, DateTime currentTime, Duration interval) =>\n        interval - (currentTime - startTime).TotalMilliseconds % interval;\n\n    /// <summary>\n    /// Schedule that recurs on a fixed interval.\n    ///\n    /// If the action run between updates takes longer than the interval, then the\n    /// action will be run immediately, but re-runs will not \"pile up\".\n    ///\n    /// \n    ///     |-----interval-----|-----interval-----|-----interval-----|\n    ///     |---------action--------||action|-----|action|-----------|\n    /// \n    /// </summary>\n    /// <param name=\"interval\">schedule interval</param>\n    /// <param name=\"currentTimeFn\">current time function</param>\n    [Pure]\n    public static Schedule fixedInterval(Duration interval, Func<DateTime>? currentTimeFn = null) =>\n        new SchFixed(interval, currentTimeFn);\n\n    ///<summary>\n    /// A schedule that divides the timeline into `interval`-long windows, and sleeps\n    /// until the nearest window boundary every time it recurs.\n    ///\n    /// For example, `Windowed(10 * seconds)` would produce a schedule as follows:\n    /// \n    ///          10s        10s        10s       10s\n    ///     |----------|----------|----------|----------|\n    ///     |action------|sleep---|act|-sleep|action----|\n    /// \n    /// </summary>\n    /// <param name=\"interval\">schedule interval</param>\n    /// <param name=\"currentTimeFn\">current time function</param>\n    [Pure]\n    public static Schedule windowed(Duration interval, Func<DateTime>? currentTimeFn = null) =>\n        new SchWindowed(interval, currentTimeFn);\n\n    [Pure]\n    internal static int durationToIntervalStart(int intervalStart, int currentIntervalPosition, int intervalWidth)\n    {\n        var steps = intervalStart - currentIntervalPosition;\n        return steps > 0 ? steps : steps + intervalWidth;\n    }\n\n    [Pure]\n    internal static int roundBetween(int value, int min, int max) =>\n        value > max\n            ? max\n            : value < min\n                ? min\n                : value;\n\n    /// <summary>\n    /// Cron-like schedule that recurs every specified `second` of each minute\n    /// </summary>\n    /// <param name=\"second\">second of the minute, will be rounded to fit between 0 and 59</param>\n    /// <param name=\"currentTimeFn\">current time function</param>\n    [Pure]\n    public static Schedule secondOfMinute(int second, Func<DateTime>? currentTimeFn = null) =>\n        new SchSecondOfMinute(second, currentTimeFn);\n\n    /// <summary>\n    /// Cron-like schedule that recurs every specified `minute` of each hour\n    /// </summary>\n    /// <param name=\"minute\">minute of the hour, will be rounded to fit between 0 and 59</param>\n    /// <param name=\"currentTimeFn\">current time function</param>\n    [Pure]\n    public static Schedule minuteOfHour(int minute, Func<DateTime>? currentTimeFn = null) =>\n        new SchMinuteOfHour(minute, currentTimeFn);\n\n    /// <summary>\n    /// Cron-like schedule that recurs every specified `hour` of each day\n    /// </summary>\n    /// <param name=\"hour\">hour of the day, will be rounded to fit between 0 and 23</param>\n    /// <param name=\"currentTimeFn\">current time function</param>\n    [Pure]\n    public static Schedule hourOfDay(int hour, Func<DateTime>? currentTimeFn = null) =>\n        new SchHourOfDay(hour, currentTimeFn);\n\n    /// <summary>\n    /// Cron-like schedule that recurs every specified `day` of each week\n    /// </summary>\n    /// <param name=\"day\">day of the week</param>\n    /// <param name=\"currentTimeFn\">current time function</param>\n    [Pure]\n    public static Schedule dayOfWeek(DayOfWeek day, Func<DateTime>? currentTimeFn = null) =>\n        new SchDayOfWeek(day, currentTimeFn);\n\n    /// <summary>\n    /// A schedule transformer that limits the returned delays to max delay\n    /// </summary>\n    /// <param name=\"max\">max delay to return</param>\n    [Pure]\n    public static ScheduleTransformer maxDelay(Duration max) =>\n        Transform(s => new SchMaxDelay(s, max));\n\n    /// <summary>\n    /// Limits the schedule to the max cumulative delay\n    /// </summary>\n    /// <param name=\"max\">max delay to stop schedule at</param>\n    [Pure]\n    public static ScheduleTransformer maxCumulativeDelay(Duration max) => \n        Transform(s => new SchMaxCumulativeDelay(s, max));\n\n    /// <summary>\n    /// A schedule transformer that adds a random jitter to any returned delay\n    /// </summary>\n    /// <param name=\"minRandom\">min random milliseconds</param>\n    /// <param name=\"maxRandom\">max random milliseconds</param>\n    /// <param name=\"seed\">optional seed</param>\n    [Pure]\n    public static ScheduleTransformer jitter(Duration minRandom, Duration maxRandom, Option<int> seed = default) =>\n        Transform(s => new SchJitter1(s, minRandom, maxRandom, seed));\n\n    /// <summary>\n    /// A schedule transformer that adds a random jitter to any returned delay\n    /// </summary>\n    /// <param name=\"factor\">jitter factor based on the returned delay</param>\n    /// <param name=\"seed\">optional seed</param>\n    [Pure]\n    public static ScheduleTransformer jitter(double factor = 0.5, Option<int> seed = default) =>\n        Transform(s => new SchJitter2(s, factor, seed));\n\n    /// <summary>\n    /// Transforms the schedule by de-correlating each of the durations both up and down in a jittered way\n    /// </summary>\n    /// <remarks>\n    /// Given a linear schedule starting at 100. (100, 200, 300...)\n    /// Adding de-correlation to it might produce a result like this, (103.2342, 97.123, 202.3213, 197.321...)\n    /// The overall schedule runs twice as long but should be less correlated when used in parallel.\n    /// </remarks>\n    /// <param name=\"factor\">jitter factor based on the returned delay</param>\n    /// <param name=\"seed\">optional seed</param>\n    [Pure]\n    public static ScheduleTransformer decorrelate(double factor = 0.1, Option<int> seed = default) =>\n        Transform(s => new SchDecorrelate(s, factor, seed));\n\n    /// <summary>\n    /// Resets the schedule after a provided cumulative max duration\n    /// </summary>\n    /// <param name=\"max\">max delay to reset the schedule at</param>\n    [Pure]\n    public static ScheduleTransformer resetAfter(Duration max) =>\n        Transform(s => new SchResetAfter(s, max));\n\n    /// <summary>\n    /// Repeats the schedule n number of times\n    /// </summary>\n    /// <param name=\"times\">number of times to repeat the schedule</param>\n    /// <remarks>\n    /// NOTE: This repeats the entire schedule!  Use `Schedule.recurs(n)` for 'number of attempts'.\n    /// </remarks>\n    [Pure]\n    public static ScheduleTransformer repeat(int times) =>\n        Transform(s => new SchRepeat(s, times));\n\n    /// <summary>\n    /// Intersperse the provided duration(s) between each duration in the schedule\n    /// </summary>\n    /// <param name=\"duration\">schedule to intersperse</param>\n    [Pure]\n    public static ScheduleTransformer intersperse(Schedule schedule) =>\n        Transform(s => s.Bind(schedule.Prepend));\n\n    /// <summary>\n    /// Intersperse the provided duration(s) between each duration in the schedule\n    /// </summary>\n    /// <param name=\"durations\">1 or more durations to intersperse</param>\n    [Pure]\n    public static ScheduleTransformer intersperse(params Duration[] durations) =>\n        intersperse(TimeSeries(durations));\n    \n    [Obsolete(\"`Spaced` has been renamed to `spaced`\")]\n    public static Schedule Spaced(Duration space) => spaced(space);\n\n    [Obsolete(\"`Recurs` has been renamed to `recurs`\")]\n    public static ScheduleTransformer Recurs(int times) => recurs(times);\n\n    [Obsolete(\"`Exponential` has been renamed to `exponential`\")]\n    public static Schedule Exponential(Duration seed, double factor = 2) =>\n        exponential(seed, factor);\n\n    [Obsolete(\"`Fibonacci` has been renamed to `fibonacci`\")]\n    public static Schedule Fibonacci(Duration seed) =>\n        fibonacci(seed);\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Schedule/Schedule.DSL.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Time series of durations\n/// </summary>\ninternal record SchItems(Iterable<Duration> Items) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Items;\n}\n\n/// <summary>\n/// Functor map\n/// </summary>\ninternal record SchMap(Schedule Schedule, Func<Duration, Duration> F) : Schedule \n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Map(F);\n}\n\n/// <summary>\n/// Functor map\n/// </summary>\ninternal record SchMapIndex(Schedule Schedule, Func<Duration, int, Duration> F) : Schedule \n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Select(F);\n}\n\n/// <summary>\n/// Filter\n/// </summary>\ninternal record SchFilter(Schedule Schedule, Func<Duration, bool> Pred) : Schedule \n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Filter(Pred);\n}\n\n/// <summary>\n/// Functor bind\n/// </summary>\ninternal record SchBind(Schedule Schedule, Func<Duration, Schedule> BindF) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Bind(x => BindF(x).Run());\n}    \n\n/// <summary>\n/// Functor bind and project\n/// </summary>\ninternal record SchBind2(Schedule Schedule, Func<Duration, Schedule> BindF, Func<Duration, Duration, Duration> Project) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Bind(x => BindF(x).Run().Map(y => Project(x, y)));\n}\n\n/// <summary>\n/// Tail of sequence\n/// </summary>\ninternal record SchTail(Schedule Schedule) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Tail();\n}    \n\n/// <summary>\n/// Skip items in sequence\n/// </summary>\ninternal record SchSkip(Schedule Schedule, int Count) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Skip(Count);\n}    \n\n/// <summary>\n/// Take items in sequence\n/// </summary>\ninternal record SchTake(Schedule Schedule, int Count) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Take(Count);\n}\n\n/// <summary>\n/// Append in sequence\n/// </summary>\ninternal record SchCombine(Schedule Left, Schedule Right) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Left.Run().Combine(Right.Run());\n}    \n\n/// <summary>\n/// Interleave items in sequence\n/// </summary>\ninternal record SchInterleave(Schedule Left, Schedule Right) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Left.Run()\n            .Zip(Right.Run(), static (d1, d2) => new[] {d1, d2})\n            .SelectMany(x => x);\n}\n\n/// <summary>\n/// Union sequence\n/// </summary>\ninternal record SchUnion(Schedule Left, Schedule Right) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            using var aEnumerator = Left.Run().GetEnumerator();\n            using var bEnumerator = Right.Run().GetEnumerator();\n\n            var hasA = aEnumerator.MoveNext();\n            var hasB = bEnumerator.MoveNext();\n\n            while (hasA || hasB)\n            {\n                yield return hasA switch\n                             {\n                                 true when hasB => Math.Min(aEnumerator.Current, bEnumerator.Current),\n                                 true           => aEnumerator.Current,\n                                 _              => bEnumerator.Current\n                             };\n\n                hasA = hasA && aEnumerator.MoveNext();\n                hasB = hasB && bEnumerator.MoveNext();\n\n            }\n        }\n    }\n}\n\n/// <summary>\n/// Intersect sequence\n/// </summary>\ninternal record SchIntersect(Schedule Left, Schedule Right) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Left.Run()\n            .Zip(Right.Run())\n            .Map(static t => (Duration)Math.Max(t.Item1, t.Item2));\n}    \n\n/// <summary>\n/// Cons an item onto sequence\n/// </summary>\ninternal record SchCons(Duration Left, Schedule Right) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            yield return Left;\n            foreach (var r in Right.Run())\n            {\n                yield return r;\n            }\n        }\n    }\n}\n\ninternal record SchRepeatForever(Schedule Schedule) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            while (true)\n                foreach (var x in Schedule.Run())\n                    yield return x;\n        }\n    }\n}\n\ninternal record SchLinear(Duration Seed, double Factor) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            Duration delayToAdd  = Seed * Factor;\n            var      accumulator = Seed;\n\n            yield return accumulator;\n            while (true)\n            {\n                accumulator += delayToAdd;\n                yield return accumulator;\n            }\n        }\n    }\n}\n\ninternal record SchFibonacci(Duration Seed) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var last        = Duration.Zero;\n            var accumulator = Seed;\n\n            yield return accumulator;\n            while (true)\n            {\n                var current = accumulator;\n                accumulator += last;\n                last        =  current;\n                yield return accumulator;\n            }\n        }\n    }\n}\n\ninternal record SchForever : Schedule\n{\n    public static readonly Schedule Default = new SchForever();\n\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            while(true) yield return Duration.Zero;\n        }\n    }\n}\n\ninternal record SchNever : Schedule\n{\n    public static readonly Schedule Default = new SchNever();\n\n    public override Iterable<Duration> Run() =>\n        Iterable.empty<Duration>();\n}\n\ninternal record SchUpTo(Duration Max, Func<DateTime>? CurrentTimeFn = null) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var now       = CurrentTimeFn ?? LiveNowFn;\n            var startTime = now();\n        \n            while (now() - startTime < Max) \n                yield return Duration.Zero;\n        }\n    }\n}\n\ninternal record SchFixed(Duration Interval, Func<DateTime>? CurrentTimeFn = null) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var now         = CurrentTimeFn ?? LiveNowFn;\n            var startTime   = now();\n            var lastRunTime = startTime;\n            while (true)\n            {\n                var currentTime   = now();\n                var runningBehind = currentTime > lastRunTime + (TimeSpan)Interval;\n            \n                var boundary = Interval == Duration.Zero\n                                   ? Interval\n                                   : secondsToIntervalStart(startTime, currentTime, Interval);\n            \n                var sleepTime = boundary == Duration.Zero \n                                    ? Interval \n                                    : boundary;\n            \n                lastRunTime = runningBehind ? currentTime : currentTime + (TimeSpan)sleepTime;\n                yield return runningBehind ? Duration.Zero : sleepTime;\n            }\n        }\n    }\n}\n\ninternal record SchWindowed(Duration Interval, Func<DateTime>? CurrentTimeFn = null) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var now       = CurrentTimeFn ?? LiveNowFn;\n            var startTime = now();\n            while (true)\n            {\n                var currentTime = now();\n                yield return secondsToIntervalStart(startTime, currentTime, Interval);\n            }\n        }\n    }\n}\n\ninternal record SchSecondOfMinute(int Second, Func<DateTime>? CurrentTimeFn = null) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var now = CurrentTimeFn ?? LiveNowFn;\n            while (true)\n                yield return durationToIntervalStart(roundBetween(Second, 0, 59), now().Second, 60) * seconds;\n        }\n    }\n}\n\ninternal record SchMinuteOfHour(int Minute, Func<DateTime>? CurrentTimeFn = null) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var now = CurrentTimeFn ?? LiveNowFn;\n            while (true)\n                yield return durationToIntervalStart(roundBetween(Minute, 0, 59), now().Minute, 60) * minutes;\n        }\n    }\n}\n\ninternal record SchHourOfDay(int Hour, Func<DateTime>? CurrentTimeFn = null) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var now = CurrentTimeFn ?? LiveNowFn;\n            while (true)\n                yield return durationToIntervalStart(roundBetween(Hour, 0, 23), now().Hour, 24) * hours;\n        }\n    }\n}\n\ninternal record SchDayOfWeek(DayOfWeek Day, Func<DateTime>? CurrentTimeFn = null) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var now = CurrentTimeFn ?? LiveNowFn;\n            while (true)\n                yield return durationToIntervalStart((int)Day + 1, (int)now().DayOfWeek + 1, 7) * days;\n        }    \n    }\n}\n\ninternal record SchMaxDelay(Schedule Schedule, Duration Max) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Map(x => x > Max ? Max : x);\n}\n\ninternal record SchMaxCumulativeDelay(Schedule Schedule, Duration Max) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            var totalAppliedDelay = Duration.Zero;\n\n            foreach (var duration in Schedule.Run())\n            {\n                if (totalAppliedDelay >= Max) yield break;\n                totalAppliedDelay += duration;\n                yield return duration;\n            }\n        }\n    }\n}\n\ninternal record SchJitter1(Schedule Schedule, Duration MinRandom, Duration MaxRandom, Option<int> Seed) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Map(x => (Duration)(x + SingletonRandom.Uniform(MinRandom, MaxRandom, Seed)));\n}\n\ninternal record SchJitter2(Schedule Schedule, double Factor, Option<int> Seed) : Schedule\n{\n    public override Iterable<Duration> Run() =>\n        Schedule.Run().Map(x => (Duration)(x + SingletonRandom.Uniform(0, x * Factor, Seed)));\n}\n\ninternal record SchDecorrelate(Schedule Schedule, double Factor, Option<int> Seed) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            foreach(var currentMilliseconds in Schedule.Run())\n            {\n                var rand1 = SingletonRandom.Uniform(0, currentMilliseconds * Factor, Seed);\n                var rand2 = SingletonRandom.Uniform(0, currentMilliseconds * Factor, Seed);\n                yield return currentMilliseconds + rand1;\n                yield return currentMilliseconds - rand2;\n            }\n        }\n    }\n}\n\ninternal record SchResetAfter(Schedule Schedule, Duration Max) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            while (true)\n                foreach (var duration in (Schedule | maxCumulativeDelay(Max)).Run())\n                    yield return duration;\n        }\n    }\n}\n\ninternal record SchRepeat(Schedule Schedule, int Times) : Schedule\n{\n    public override Iterable<Duration> Run()\n    {\n        return Go().AsIterable();\n        IEnumerable<Duration> Go()\n        {\n            for (var i = 0; i < Times; i++)\n                foreach (var duration in Schedule.Run())\n                    yield return duration;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Schedule/Schedule.Extensions.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static class ScheduleExtensions\n{\n    /// <summary>\n    /// Converts a `Seq` of positive durations to a schedule\n    /// </summary>\n    /// <param name=\"seq\">Seq of positive durations</param>\n    /// <returns>schedule</returns>\n    [Pure]\n    public static Schedule ToSchedule(this Seq<Duration> seq) =>\n        Schedule.TimeSeries(seq);\n    \n    /// <summary>\n    /// Converts a `Arr` of positive durations to a schedule\n    /// </summary>\n    /// <param name=\"array\">array of positive durations</param>\n    /// <returns>schedule</returns>\n    [Pure]\n    public static Schedule ToSchedule(this Arr<Duration> array) =>\n        Schedule.TimeSeries(array);\n    \n    /// <summary>\n    /// Converts a `Lst` of positive durations to a schedule \n    /// </summary>\n    /// <param name=\"list\">list of positive durations</param>\n    /// <returns>schedule</returns>\n    [Pure]\n    public static Schedule ToSchedule(this Lst<Duration> list) =>\n        Schedule.TimeSeries(list);\n    \n    /// <summary>\n    /// Converts a `Set` of positive durations to a schedule\n    /// </summary>\n    /// <param name=\"set\">set of positive durations</param>\n    /// <returns>schedule</returns>\n    [Pure]\n    public static Schedule ToSchedule(this Set<Duration> set) =>\n        Schedule.TimeSeries(set);\n    \n    /// <summary>\n    /// Converts a `HashSet` of positive durations to a schedule\n    /// </summary>\n    /// <param name=\"hashSet\">hashset of positive durations</param>\n    /// <returns>schedule</returns>\n    [Pure]\n    public static Schedule ToSchedule(this HashSet<Duration> hashSet) =>\n        Schedule.TimeSeries(hashSet);\n\n    /// <summary>\n    /// Prepend a duration to the schedule\n    /// </summary>\n    /// <param name=\"value\">Duration to prepend</param>\n    /// <param name=\"s\">Schedule</param>\n    /// <returns>Schedule with the duration prepended</returns>\n    [Pure]\n    public static Schedule Cons(this Duration value, Schedule s) =>\n        s.Prepend(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Schedule/Schedule.Prelude.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Intersection of two schedules. As long as they are both running it returns the max duration\n    /// </summary>\n    /// <param name=\"a\">Schedule `a`</param>\n    /// <param name=\"b\">Schedule `b`</param>\n    /// <returns>Max of schedule `a` and `b` to the length of the shortest schedule</returns>\n    [Pure]\n    public static Schedule intersect(Schedule a, Schedule b) =>\n        a.Intersect(b);\n\n    /// <summary>\n    /// Union of two schedules. As long as any are running it returns the min duration of both or a or b\n    /// </summary>\n    /// <param name=\"a\">Schedule `a`</param>\n    /// <param name=\"b\">Schedule `b`</param>\n    /// <returns>Min of schedule `a` and `b` or `a` or `b` to the length of the longest schedule</returns>\n    [Pure]\n    public static Schedule union(Schedule a, Schedule b) =>\n        a.Union(b);\n\n    /// <summary>\n    /// Interleave two schedules together\n    /// </summary>\n    /// <param name=\"a\">Schedule `a`</param>\n    /// <param name=\"b\">Schedule `b`</param>\n    /// <returns>Returns the two schedules interleaved together</returns>\n    [Pure]\n    public static Schedule interleave(Schedule a, Schedule b) =>\n        a.Interleave(b);\n\n    /// <summary>\n    /// Append two schedules together\n    /// </summary>\n    /// <param name=\"a\">Schedule `a`</param>\n    /// <param name=\"b\">Schedule `b`</param>\n    /// <returns>Returns the two schedules appended</returns>\n    [Pure]\n    public static Schedule append(Schedule a, Schedule b) =>\n        a.Combine(b);\n\n    /// <summary>\n    /// Take `amount` durations from the `Schedule`\n    /// </summary>\n    /// <param name=\"s\">Schedule to take from</param>\n    /// <param name=\"amount\">Amount ot take</param>\n    /// <returns>Schedule with `amount` or less durations</returns>\n    [Pure]\n    public static Schedule take(Schedule s, int amount) =>\n        s.Take(amount);\n\n    /// <summary>\n    /// Skip `amount` durations from the `Schedule`\n    /// </summary>\n    /// <param name=\"s\">Schedule to skip durations from</param>\n    /// <param name=\"amount\">Amount ot skip</param>\n    /// <returns>Schedule with `amount` durations skipped</returns>\n    [Pure]\n    public static Schedule skip(Schedule s, int amount) =>\n        s.Skip(amount);\n\n    /// <summary>\n    /// Take all but the first duration from the schedule\n    /// </summary>\n    [Pure]\n    public static Schedule tail(Schedule s) =>\n        s.Tail;\n\n    /// <summary>\n    /// Functor map operation for Schedule\n    /// </summary>\n    /// <param name=\"s\">Schedule</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped schedule</returns>\n    [Pure]\n    public static Schedule map(Schedule s, Func<Duration, Duration> f) =>\n        s.Map(f);\n    \n    /// <summary>\n    /// Filter operation for Schedule\n    /// </summary>\n    /// <param name=\"s\">Schedule</param>\n    /// <param name=\"pred\">predicate</param>\n    /// <returns>Filtered schedule</returns>\n    [Pure]\n    public static Schedule filter(Schedule s, Func<Duration, bool> pred) =>\n        s.Filter(pred);\n\n    /// <summary>\n    /// Monad bind operation for Schedule\n    /// </summary>\n    /// <param name=\"s\">Schedule</param>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Chained schedule</returns>\n    [Pure]\n    public static Schedule bind(Schedule s, Func<Duration, Schedule> f) =>\n        s.Bind(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Schedule/Schedule.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A schedule is defined as a potentially infinite stream of durations, combined with mechanisms for composing them.\n/// </summary>\n/// <remarks>\n/// Used heavily by `repeat`, `retry`, and `fold` with the effect types.  Use the static methods to create parts\n/// of schedulers and then union them using `|` or intersect them using `＆`.  Union will take the minimum of the two\n/// schedules to the length of the longest, intersect will take the maximum of the two schedules to the length of the\n/// shortest.\n/// </remarks>\n/// <example>\n/// This example creates a schedule that repeats 5 times, with an exponential delay between each stage, starting\n/// at 10 milliseconds:\n/// \n///     var s = Schedule.recurs(5) | Schedule.exponential(10*ms)\n/// \n/// </example>\n/// <example>\n/// This example creates a schedule that repeats 5 times, with an exponential delay between each stage, starting\n/// at 10 milliseconds and with a maximum delay of 2000 milliseconds:\n/// \n///     var s = Schedule.recurs(5) | Schedule.exponential(10*ms) | Schedule.spaced(2000*ms)\n/// </example>\n/// <example>\n/// This example creates a schedule that repeats 5 times, with an exponential delay between each stage, starting\n/// at 10 milliseconds and with a minimum delay of 300 milliseconds:\n/// \n///     var s = Schedule.recurs(5) | Schedule.exponential(10*ms) ＆ Schedule.spaced(300*ms)\n/// </example>\npublic abstract partial record Schedule : Semigroup<Schedule>\n{\n    [Pure]\n    public static Schedule operator |(Schedule a, Schedule b) =>\n        a.Union(b);\n\n    [Pure]\n    public static Schedule operator |(Schedule a, ScheduleTransformer b) =>\n        b.Apply(a);\n\n    [Pure]\n    public static Schedule operator |(ScheduleTransformer a, Schedule b) =>\n        a.Apply(b);\n\n    [Pure]\n    public static Schedule operator &(Schedule a, Schedule b) =>\n        a.Intersect(b);\n\n    [Pure]\n    public static Schedule operator &(Schedule a, ScheduleTransformer b) =>\n        b.Apply(a);\n\n    [Pure]\n    public static Schedule operator &(ScheduleTransformer a, Schedule b) =>\n        a.Apply(b);\n\n    [Pure]\n    public static Schedule operator +(Schedule a, Schedule b) =>\n        a.Combine(b);\n\n    /// <summary>\n    /// Realise the underlying time-series of durations\n    /// </summary>\n    /// <returns>The underlying time-series of durations</returns>\n    [Pure]\n    public abstract Iterable<Duration> Run();\n\n    /// <summary>\n    /// Intersection of two schedules. As long as they are both running it returns the max duration\n    /// </summary>\n    /// <param name=\"b\">Schedule `b`</param>\n    /// <returns>Max of schedule `this` and `b` to the length of the shortest schedule</returns>\n    [Pure]\n    public Schedule Intersect(Schedule b) =>\n        new SchIntersect(this, b);\n\n    /// <summary>\n    /// Union of two schedules. As long as any are running it returns the min duration of both or a or b\n    /// </summary>\n    /// <param name=\"b\">Schedule `b`</param>\n    /// <returns>Min of schedule `this` and `b` or `this` or `b` to the length of the longest schedule</returns>\n    [Pure]\n    public Schedule Union(Schedule b) =>\n        new SchUnion(this, b);\n\n    /// <summary>\n    /// Interleave two schedules together\n    /// </summary>\n    /// <param name=\"b\">Schedule `b`</param>\n    /// <returns>Returns the two schedules interleaved together</returns>\n    [Pure]\n    public Schedule Interleave(Schedule b) =>\n        new SchInterleave(this, b);\n\n    /// <summary>\n    /// Append two schedules together\n    /// </summary>\n    /// <param name=\"b\">Schedule `b`</param>\n    /// <returns>Returns the two schedules appended</returns>\n    [Pure]\n    public Schedule Combine(Schedule b) =>\n        new SchCombine(this, b);\n\n    /// <summary>\n    /// Take `amount` durations from the `Schedule`\n    /// </summary>\n    /// <param name=\"s\">Schedule to take from</param>\n    /// <param name=\"amount\">Amount ot take</param>\n    /// <returns>Schedule with `amount` or less durations</returns>\n    [Pure]\n    public Schedule Take(int amount) =>\n        new SchTake(this, amount);\n\n    /// <summary>\n    /// Skip `amount` durations from the `Schedule`\n    /// </summary>\n    /// <param name=\"s\">Schedule to skip durations from</param>\n    /// <param name=\"amount\">Amount ot skip</param>\n    /// <returns>Schedule with `amount` durations skipped</returns>\n    [Pure]\n    public Schedule Skip(int amount) =>\n        new SchSkip(this, amount);\n\n    /// <summary>\n    /// Take all but the first duration from the schedule\n    /// </summary>\n    [Pure]\n    public Schedule Tail =>\n        new SchTail(this);\n\n    /// <summary>\n    /// Prepend a duration in-front of the rest of the scheduled durations\n    /// </summary>\n    /// <param name=\"value\">Duration to prepend</param>\n    /// <returns>Schedule with the duration prepended</returns>\n    [Pure]\n    public Schedule Prepend(Duration value) =>\n        new SchCons(value, this);\n\n    /// <summary>\n    /// Prepend a zero duration in-front of the rest of the scheduled durations\n    /// </summary>\n    /// <param name=\"value\">Duration to prepend</param>\n    /// <returns>Schedule with the duration prepended</returns>\n    [Pure]\n    public Schedule PrependZero =>\n        Prepend(Duration.Zero);\n\n    /// <summary>\n    /// Functor map operation for Schedule\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped schedule</returns>\n    [Pure]\n    public Schedule Map(Func<Duration, Duration> f) =>\n        new SchMap(this, f);\n\n    /// <summary>\n    /// Functor map operation for Schedule\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped schedule</returns>\n    [Pure]\n    public Schedule Map(Func<Duration, int, Duration> f) =>\n        new SchMapIndex(this, f);\n\n    /// <summary>\n    /// Filter operation for Schedule\n    /// </summary>\n    /// <param name=\"pred\">predicate</param>\n    /// <returns>Filtered schedule</returns>\n    [Pure]\n    public Schedule Filter(Func<Duration, bool> pred) =>\n        new SchFilter(this, pred);\n\n    /// <summary>\n    /// Filter operation for Schedule\n    /// </summary>\n    /// <param name=\"pred\">predicate</param>\n    /// <returns>Filtered schedule</returns>\n    [Pure]\n    public Schedule Where(Func<Duration, bool> pred) =>\n        new SchFilter(this, pred);\n\n    /// <summary>\n    /// Functor map operation for Schedule\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped schedule</returns>\n    [Pure]\n    public Schedule Select(Func<Duration, Duration> f) =>\n        new SchMap(this, f);\n\n    /// <summary>\n    /// Functor map operation for Schedule\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped schedule</returns>\n    [Pure]\n    public Schedule Select(Func<Duration, int, Duration> f) =>\n        new SchMapIndex(this, f);\n\n    /// <summary>\n    /// Monad bind operation for Schedule\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Chained schedule</returns>\n    [Pure]\n    public Schedule Bind(Func<Duration, Schedule> f) =>\n        new SchBind(this, f);\n\n    /// <summary>\n    /// Monad bind operation for Schedule\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Chained schedule</returns>\n    [Pure]\n    public Schedule SelectMany(Func<Duration, Schedule> f) =>\n        new SchBind(this, f);\n\n    /// <summary>\n    /// Monad bind and project operation for Schedule\n    /// </summary>\n    /// <param name=\"s\">Schedule</param>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    /// <returns>Chained schedule</returns>\n    [Pure]\n    public Schedule SelectMany(Func<Duration, Schedule> bind, Func<Duration, Duration, Duration> project) =>\n        new SchBind2(this, bind, project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Schedule/ScheduleTransformer.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Transforms a schedule into another schedule\n/// </summary>\npublic readonly struct ScheduleTransformer\n{\n    readonly Func<Schedule, Schedule> Map;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    /// <param name=\"map\">Mapping functor</param>\n    internal ScheduleTransformer(Func<Schedule, Schedule> map) =>\n        Map = map;\n\n    /// <summary>\n    /// Apply a schedule to the transformer\n    /// </summary>\n    /// <param name=\"schedule\">`Schedule` to run through the transformer</param>\n    /// <returns>`Schedule` that has been run through the transformer</returns>\n    public Schedule Apply(Schedule schedule) =>\n        Map?.Invoke(schedule) ?? schedule;\n\n    /// <summary>\n    /// Compose the two transformers into one\n    /// </summary>\n    /// <param name=\"f\">First transformer to run in the composition</param>\n    /// <param name=\"g\">Second transformer to run in the composition</param>\n    /// <returns>composition of the 2 transformers</returns>\n    public static ScheduleTransformer operator +(ScheduleTransformer f, ScheduleTransformer g) =>\n        new(x => g.Apply(f.Apply(x)));\n\n    public static implicit operator Schedule(ScheduleTransformer t) =>\n        Schedule.Forever | t;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Effects/Schedule/SingletonRandom.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Singleton source of randomness\n/// </summary>\ninternal static class SingletonRandom\n{\n    static readonly Random Random = new();\n    static readonly Func<int, Random> Provider = memoUnsafe((int seed) => new Random(seed));\n\n    /// <summary>\n    /// Returns a random floating-point number that is greater than or equal to `0.0`, and less than `1.0`\n    /// </summary>\n    internal static double NextDouble(Option<int> seed = default) =>\n        seed.IsSome\n            ? Provider(seed.Value).NextDouble()\n            : Random.NextDouble();\n\n    /// <summary>\n    /// Returns a random floating-point number that is greater than or equal to `a` and less than `b`\n    /// </summary>\n    internal static double Uniform(double a, double b, Option<int> seed = default)\n    {\n        if (a.Equals(b)) return a;\n        return a + (b - a) * NextDouble(seed);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Exceptions/Exceptions.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Some T not initialised\n/// </summary>\n[Serializable]\npublic class SomeNotInitialisedException : Exception\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public SomeNotInitialisedException(Type type)\n        :\n        base($\"Unitialised Some<{type.Name}>.\")\n    {\n    }\n}\n\n/// <summary>\n/// Value is none\n/// </summary>\n[Serializable]\npublic class ValueIsNoneException : Exception\n{\n    public static readonly ValueIsNoneException Default = new ValueIsNoneException();\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ValueIsNoneException()\n        : base(\"Value is none.\")\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ValueIsNoneException(string message) : base(message)\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ValueIsNoneException(string message, Exception innerException) : base(message, innerException)\n    {\n    }\n}\n\n/// <summary>\n/// Value is null\n/// </summary>\n[Serializable]\npublic class ValueIsNullException : Exception\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ValueIsNullException()\n        : base(\"Value is null.\")\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ValueIsNullException(string message) : base(message)\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ValueIsNullException(string message, Exception innerException) : base(message, innerException)\n    {\n    }\n}\n\n/// <summary>\n/// Result is null\n/// </summary>\n[Serializable]\npublic class ResultIsNullException : Exception\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ResultIsNullException()\n        : base(\"Result is null.\")\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ResultIsNullException(string message) : base(message)\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ResultIsNullException(string message, Exception innerException) : base(message, innerException)\n    {\n    }\n}\n\n/// <summary>\n/// Option T is none\n/// </summary>\n[Serializable]\npublic class OptionIsNoneException : Exception\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public OptionIsNoneException()\n        : base(\"Option isn't set.\")\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public OptionIsNoneException(string message) : base(message)\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public OptionIsNoneException(string message, Exception innerException) : base(message, innerException)\n    {\n    }\n}\n\n/// <summary>\n/// Either is not right\n/// </summary>\n[Serializable]\npublic class EitherIsNotRightException : Exception\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public EitherIsNotRightException()\n        : base(\"Either is not right.\")\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public EitherIsNotRightException(string message) : base(message)\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public EitherIsNotRightException(string message, Exception innerException) : base(message, innerException)\n    {\n    }\n}\n\n/// <summary>\n/// Either is not left\n/// </summary>\n[Serializable]\npublic class EitherIsNotLeftException : Exception\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public EitherIsNotLeftException()\n        : base(\"Either is not left.\")\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public EitherIsNotLeftException(string message) : base(message)\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public EitherIsNotLeftException(string message, Exception innerException) : base(message, innerException)\n    {\n    }\n}\n\n[Serializable]\npublic class NotAppendableException : Exception\n{\n    public NotAppendableException(Type t)\n        : base($\"Type '{t.Name}' not appendable: It's neither a CLR numeric-type, a string nor derived from IAppendable\")\n    {\n    }\n}\n\n[Serializable]\npublic class NotSubtractableException : Exception\n{\n    public NotSubtractableException(Type t)\n        : base($\"Type '{t.Name}' not subtractable: It's neither a CLR numeric-type, nor derived from ISubtractable\")\n    {\n    }\n}\n\n[Serializable]\npublic class NotMultiplicableException : Exception\n{\n    public NotMultiplicableException(Type t)\n        : base($\"Type '{t.Name}' not multiplicable: It's neither a CLR numeric-type, nor derived from IMultiplicable\")\n    {\n    }\n}\n\n[Serializable]\npublic class NotDivisibleException : Exception\n{\n    public NotDivisibleException(Type t)\n        : base($\"Type '{t.Name}' not divisible: It's neither a CLR numeric-type, nor derived from IDivisible\")\n    {\n    }\n}\n\n[Serializable]\npublic class RefValidationFailedException : Exception\n{\n    public RefValidationFailedException() :\n        base(\"Ref validation failed\")\n    {\n    }\n}\n\n[Serializable]\npublic class DeadlockException : Exception\n{\n    public DeadlockException() : base(\"Deadlock occured during atomic update\") { }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Extensions/ActionObservable.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Executes an action post-subscription.  This is useful when the action is \n/// going to publish to the observable.  A kind of request/response.\n/// Use the IObservable extension method: PostSubscribe(() => ...)\n/// </summary>\npublic class ActionObservable<T>(\n    Action PostSubscribeAction,\n    IObservable<T> SwitchTo)\n    : IObservable<T>\n{\n    public IDisposable Subscribe(IObserver<T> observer)\n    {\n        var subs = SwitchTo.Subscribe(observer);\n        PostSubscribeAction();\n        return subs;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Extensions/Compose.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static class ComposeExtensions\n{\n    /// <summary>\n    /// Function back composition\n    /// </summary>\n    /// <returns>v => g(f(v))</returns>\n    [Pure]\n    public static Func<A, C> BackCompose<A, B, C>(this Func<B, C> g, Func<A, B> f) =>\n        v => g(f(v));\n\n    /// <summary>\n    /// Function back composition\n    /// </summary>\n    /// <returns>() => g(f())</returns>\n    [Pure]\n    public static Func<B> BackCompose<A, B>(this Func<A, B> g, Func<A> f) =>\n        () => g(f());\n\n    /// <summary>\n    /// Action back composition\n    /// </summary>\n    /// <returns>v => g(f(v))</returns>\n    [Pure]\n    public static Action<A> BackCompose<A, B>(this Action<B> g, Func<A, B> f)\n        => v => g(f(v));\n\n    /// <summary>\n    /// Action back composition\n    /// </summary>\n    /// <returns>() => g(f())</returns>\n    [Pure]\n    public static Action BackCompose<A>(this Action<A> g, Func<A> f)\n        => () => g(f());\n\n    /// <summary>\n    /// Function composition\n    /// </summary>\n    /// <returns>v => g(f(v))</returns>\n    [Pure]\n    public static Func<A, C> Compose<A, B, C>(this Func<A, B> f, Func<B, C> g) =>\n        v => g(f(v));\n\n    /// <summary>\n    /// Function composition\n    /// </summary>\n    /// <returns>() => g(f())</returns>\n    [Pure]\n    public static Func<B> Compose<A, B>(this Func<A> f, Func<A, B> g) =>\n        () => g(f());\n\n    /// <summary>\n    /// Action composition\n    /// </summary>\n    /// <returns>v => g(f(v))</returns>\n    [Pure]\n    public static Action<A> Compose<A, B>(this Func<A, B> f, Action<B> g)\n        => v => g(f(v));\n\n    /// <summary>\n    /// Action composition\n    /// </summary>\n    /// <returns>() => g(f())</returns>\n    [Pure]\n    public static Action Compose<A>(this Func<A> f, Action<A> g)\n        => () => g(f());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Extensions/FuncExtensions.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static class FuncExtensions\n{\n    /// <summary>\n    /// Flip the arguments in a two argument function\n    /// </summary>\n    [Pure]\n    public static Func<B, A, C> Flip<A, B, C>(this Func<A, B, C> f) =>\n        (b, a) => f(a, b);\n\n    /// <summary>\n    /// Flip the arguments in a two argument function\n    /// </summary>\n    [Pure]\n    public static Func<B, Func<A, C>> Flip<A, B, C>(this Func<A, Func<B, C>> f) =>\n        b => a => f(a)(b);\n\n    extension<A, B, C>(Func<A, B> lhs)\n    {\n        /// <summary>\n        /// Function composition\n        /// </summary>\n        /// <param name=\"f\">First function</param>\n        /// <param name=\"g\">Second function</param>\n        /// <returns>Composed function</returns>\n        public static Func<A, C> operator >>(Func<A, B> f, Func<B, C> g) =>\n            x => g(f(x));\n    }\n    \n    extension<A, B, C>(Func<B, C> lhs)\n    {\n        /// <summary>\n        /// Function composition\n        /// </summary>\n        /// <param name=\"f\">First function</param>\n        /// <param name=\"g\">Second function</param>\n        /// <returns>Composed function</returns>\n        public static Func<A, C> operator <<(Func<B, C> g, Func<A, B> f) =>\n            x => g(f(x));        \n    }\n\n    extension<A, B>(Func<B, A> lhs)\n    {\n        /// <summary>\n        /// Function composition\n        /// </summary>\n        /// <param name=\"f\">Function</param>\n        /// <param name=\"x\">Input</param>\n        /// <returns>Result of invoking the function</returns>\n        public static Pure<A> operator >> (Func<B, A> f, Pure<B> x) =>\n            new(f(x.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Extensions/ObjectExt.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n#nullable disable   //TODO:  THIS IS TO RETAIN THE ORIGINAL CAPABILITY --- LEAVE IT DISABLED UNTIL YOU CAN PROVE IT WORKS OTHERWISE\n\npublic static class ObjectExt\n{\n    /// <summary>\n    /// Returns true if the value is null, and does so without\n    /// boxing of any value-types.  Value-types will always\n    /// return false.\n    /// </summary>\n    /// <example>\n    ///     int x = 0;\n    ///     string y = null;\n    ///     \n    ///     x.IsNull()  // false\n    ///     y.IsNull()  // true\n    /// </example>\n    /// <returns>True if the value is null, and does so without\n    /// boxing of any value-types.  Value-types will always\n    /// return false.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool IsNull<A>(this A value) =>\n        Check<A>.IsNull(value);\n}\n\ninternal static class Check<A>\n{\n    static readonly bool IsReferenceType;\n    static readonly bool IsNullable;\n\n    static Check()\n    {\n        IsNullable      = Nullable.GetUnderlyingType(typeof(A)) != null;\n        IsReferenceType = !typeof(A).GetTypeInfo().IsValueType;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static bool IsDefault(A value) =>\n        EqDefault<A>.Equals(value, default);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static bool IsNull(A value) =>\n        (IsReferenceType && ReferenceEquals(value, null)) || (IsNullable && value.Equals(default));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Extensions/ObservableExt.cs",
    "content": "﻿using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Observable extensions\n/// </summary>\npublic static class ObservableExt\n{\n    /// <summary>\n    /// Executes an action post-subscription.  This is useful when the action is \n    /// going to publish to the observable.  A kind of request/response.\n    /// </summary>\n    [Pure]\n    public static IObservable<T> PostSubscribe<T>(\n        this IObservable<T> self,\n        Action action) =>\n        new ActionObservable<T>(action, self);\n\n    /// <summary>\n    /// Executes an action post-subscription.  This is useful when the action is \n    /// going to publish to the observable.  A kind of request/response.\n    /// </summary>\n    [Pure]\n    public static IObservable<T> PostSubscribe<T>(\n        this IObservable<T> self,\n        Func<Unit> action) =>\n        new ActionObservable<T>(() => action(), self);\n\n    /// <summary>\n    /// Convert an `IObservable` to an `IAsyncEnumerable`\n    /// </summary>\n    public static IAsyncEnumerable<A> ToAsyncEnumerable<A>(\n        this IObservable<A> observable,\n        CancellationToken token) =>\n        Observe<A>.Run(observable, token);\n\n    class Observe<A> : IObserver<A>\n    {\n        readonly AutoResetEvent wait;\n        readonly ConcurrentQueue<Fin<A>> queue;\n\n        Observe(AutoResetEvent wait, ConcurrentQueue<Fin<A>> queue)\n        {\n            this.wait = wait;\n            this.queue = queue;\n        }\n\n        public static async IAsyncEnumerable<A> Run(\n            IObservable<A> observable, \n            [EnumeratorCancellation] CancellationToken token)\n        {\n            using var wait  = new AutoResetEvent(false);\n            var       queue = new ConcurrentQueue<Fin<A>>();\n            observable.Subscribe(new Observe<A>(wait, queue));\n\n            while (true)\n            {\n                await wait.WaitOneAsync(token).ConfigureAwait(false);\n                while (queue.TryDequeue(out var item))\n                {\n                    if (item.IsFail)\n                    {\n                        if (item.FailValue == Errors.None) yield break;\n                        if (item.FailValue == Errors.Cancelled) throw new OperationCanceledException();\n                        item.FailValue.Throw();\n                        yield break;\n                    }\n                    else\n                    {\n                        yield return item.SuccValue;\n                    }\n                }\n            }                \n        }\n\n        public void OnCompleted()\n        {\n            queue.Enqueue(Errors.None);\n            wait.Set();\n        }\n\n        public void OnError(Exception error)\n        {\n            queue.Enqueue(Error.New(error));\n            wait.Set();\n        }\n\n        public void OnNext(A value)\n        {\n            queue.Enqueue(value);\n            wait.Set();\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Extensions/Query.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Linq.Expressions;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class Query\n{\n    public static T head<T>(IQueryable<T> list) => list.First();\n\n    public static Option<T> headOrNone<T>(IQueryable<T> list) =>\n        list.FirstOrDefault() ?? Option<T>.None;\n\n    public static Either<L, R> headOrLeft<L, R>(IQueryable<R> list, L left) =>\n        list.FirstOrDefault() ?? Either.Left<L, R>(left);\n\n    public static IQueryable<T> tail<T>(IQueryable<T> list) =>\n        list.Skip(1);\n\n    public static IQueryable<R> map<T, R>(IQueryable<T> list, Expression<Func<T, R>> map) =>\n        list.Select(map);\n\n    public static IQueryable<R> map<T, R>(IQueryable<T> list, Expression<Func<int, T, R>> map)\n    {\n        var paramT = Expression.Parameter(typeof(T), \"t\");\n        var paramI = Expression.Parameter(typeof(int), \"i\");\n\n        return zip(list, Range(0, Int32.MaxValue),\n            Expression.Lambda<Func<T, int, R>>(\n                Expression.Invoke(map, paramI, paramT),\n                paramT,\n                paramI\n                ));\n    }\n\n    public static IQueryable<T> filter<T>(IQueryable<T> list, Expression<Func<T, bool>> predicate) =>\n        list.Where(predicate);\n\n    public static IQueryable<U> choose<T, U>(IQueryable<T> list, Expression<Func<T, Option<U>>> selector) =>\n        map(filter(map(list, selector), t => t.IsSome), t => t.Value!);\n\n    public static IQueryable<U> choose<T, U>(IQueryable<T> list, Expression<Func<int, T, Option<U>>> selector) =>\n        map(filter(map(list, selector), t => t.IsSome), t => t.Value!);\n\n    public static IQueryable<R> collect<T, R>(IQueryable<T> list, Expression<Func<T, IEnumerable<R>>> map)\n    {\n        var paramT = Expression.Parameter(typeof(T), \"t\");\n\n        return list.SelectMany(\n            Expression.Lambda<Func<T, IEnumerable<R>>>(\n                Expression.Invoke(map, paramT),\n                paramT\n                ));\n    }\n\n    public static int sum(IQueryable<int> list) =>\n        fold(list, 0, (x, s) => s + x);\n\n    public static float sum(IQueryable<float> list) =>\n        fold(list, 0.0f, (x, s) => s + x);\n\n    public static double sum(IQueryable<double> list) =>\n        fold(list, 0.0, (x, s) => s + x);\n\n    public static decimal sum(IQueryable<decimal> list) =>\n        fold(list, (decimal)0, (x, s) => s + x);\n\n    public static IQueryable<T> rev<T>(IQueryable<T> list) =>\n        list.Reverse();\n\n    public static IQueryable<T> append<T>(IQueryable<T> lhs, IQueryable<T> rhs) =>\n        lhs.Concat(rhs);\n\n    public static S fold<S, T>(IQueryable<T> list, S state, Expression<Func<S, T, S>> folder) =>\n        list.Aggregate(state, folder);\n\n    public static S foldBack<S, T>(IQueryable<T> list, S state, Expression<Func<S, T, S>> folder) =>\n        fold(rev(list), state, folder);\n\n    public static T reduce<T>(IQueryable<T> list, Expression<Func<T, T, T>> reducer) =>\n        match(headOrNone(list),\n            Some: x => fold(tail(list), x, reducer),\n            None: () => failwith<T>(\"Input list was empty\")\n        );\n\n    public static T reduceBack<T>(IQueryable<T> list, Expression<Func<T, T, T>> reducer) =>\n        reduce(rev(list), reducer);\n\n    public static Option<T> find<T>(IQueryable<T> list, Expression<Func<T, bool>> pred) =>\n        headOrNone(filter(list, pred));\n\n    public static Lst<T> freeze<T>(IQueryable<T> list) =>\n        toList(list);\n\n    public static IQueryable<V> zip<T, U, V>(IQueryable<T> list, IEnumerable<U> other, Expression<Func<T, U, V>> zipper) =>\n        Queryable.Zip(list, other, zipper);\n\n    public static int length<T>(IQueryable<T> list) =>\n        list.Count();\n\n    public static bool forall<T>(IQueryable<T> list, Expression<Func<T, bool>> pred) =>\n        list.All(pred);\n\n    public static IQueryable<T> distinct<T>(IQueryable<T> list) =>\n        Queryable.Distinct(list);\n\n    public static IQueryable<T> take<T>(IQueryable<T> list, int count) =>\n        list.Take(count);\n\n    public static IQueryable<T> takeWhile<T>(IQueryable<T> list, Expression<Func<T, bool>> pred) =>\n        list.TakeWhile(pred);\n\n    public static IQueryable<T> takeWhile<T>(IQueryable<T> list, Expression<Func<T, int, bool>> pred) =>\n        list.TakeWhile(pred);\n\n    public static bool exists<T>(IQueryable<T> list, Expression<Func<T, bool>> pred) =>\n        list.Any(pred);\n}\n\npublic static class QueryExtensions\n{\n    public static T Head<T>(this IQueryable<T> list) =>\n        Query.head(list);\n\n    public static Option<T> HeadOrNone<T>(this IQueryable<T> list) =>\n        Query.headOrNone(list);\n\n    public static Either<S, T> HeadOrLeft<S, T>(this IQueryable<T> list, S left) =>\n        Query.headOrLeft(list, left);\n\n    public static IQueryable<T> Tail<T>(this IQueryable<T> list) =>\n        Query.tail(list);\n\n    public static IQueryable<R> Map<T, R>(this IQueryable<T> list, Expression<Func<T, R>> map) =>\n        Query.map(list, map);\n\n    public static IQueryable<R> Map<T, R>(this IQueryable<T> list, Expression<Func<int, T, R>> map) =>\n        Query.map(list, map);\n\n    public static IQueryable<T> Filter<T>(this IQueryable<T> list, Expression<Func<T, bool>> predicate) =>\n        Query.filter(list, predicate);\n\n    public static IQueryable<U> Choose<T, U>(this IQueryable<T> list, Expression<Func<T, Option<U>>> selector) =>\n        Query.choose(list, selector);\n\n    public static IQueryable<U> Choose<T, U>(this IQueryable<T> list, Expression<Func<int, T, Option<U>>> selector) =>\n        Query.choose(list, selector);\n\n    public static IQueryable<R> Collect<T, R>(this IQueryable<T> list, Expression<Func<T, IEnumerable<R>>> map) =>\n        Query.collect(list, map);\n\n    public static IQueryable<T> Rev<T>(this IQueryable<T> list) =>\n        Query.rev(list);\n\n    public static IQueryable<T> Append<T>(this IQueryable<T> lhs, IQueryable<T> rhs) =>\n        Query.append(lhs, rhs);\n\n    public static S Fold<S, T>(this IQueryable<T> list, S state, Expression<Func<S, T, S>> folder) =>\n        Query.fold(list, state, folder);\n\n    public static S FoldBack<S, T>(this IQueryable<T> list, S state, Expression<Func<S, T, S>> folder) =>\n        Query.foldBack(list, state, folder);\n\n    public static T Reduce<T>(this IQueryable<T> list, Expression<Func<T, T, T>> reducer) =>\n        Query.reduce(list, reducer);\n\n    public static T ReduceBack<T>(this IQueryable<T> list, Expression<Func<T, T, T>> reducer) =>\n        Query.reduceBack(list, reducer);\n\n    public static Lst<T> Freeze<T>(this IQueryable<T> list) =>\n        Query.freeze(list);\n\n    public static IQueryable<V> Zip<T, U, V>(this IQueryable<T> list, IEnumerable<U> other,\n                                             Expression<Func<T, U, V>> zipper) =>\n        Query.zip(list, other, zipper);\n\n    public static int Length<T>(this IQueryable<T> list) =>\n        Query.length(list);\n\n    public static bool ForAll<T>(this IQueryable<T> list, Expression<Func<T, bool>> pred) =>\n        Query.forall(list, pred);\n\n    public static IQueryable<T> Distinct<T>(this IQueryable<T> list) =>\n        Query.distinct(list);\n\n    public static bool Exists<T>(this IQueryable<T> list, Expression<Func<T, bool>> pred) =>\n        Query.exists(list, pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Extensions/TryOutExt.cs",
    "content": "﻿using System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static class OutExtensions\n{\n    /// <summary>\n    /// Get a value out of a dictionary as Some, otherwise None.\n    /// </summary>\n    /// <typeparam name=\"K\">Key type</typeparam>\n    /// <typeparam name=\"V\">Value type</typeparam>\n    /// <param name=\"self\">Dictionary</param>\n    /// <param name=\"Key\">Key</param>\n    /// <returns>OptionT filled Some(value) or None</returns>\n    [Pure]\n    public static Option<V> TryGetValue<K, V>(this IDictionary<K, V> self, K Key) =>\n        self.TryGetValue(Key, out var value)\n            ? Optional(value)\n            : None;\n\n    /// <summary>\n    /// Get a value out of a dictionary as Some, otherwise None.\n    /// </summary>\n    /// <typeparam name=\"K\">Key type</typeparam>\n    /// <typeparam name=\"V\">Value type</typeparam>\n    /// <param name=\"self\">Dictionary</param>\n    /// <param name=\"ReadOnlyKey\">Key</param>\n    /// <returns>OptionT filled Some(value) or None</returns>\n    [Pure]\n    public static Option<V> TryGetValue<K, V>(this IReadOnlyDictionary<K, V> self, K ReadOnlyKey) =>\n        self.TryGetValue(ReadOnlyKey, out var value)\n            ? Optional(value)\n            : None;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Extensions/UnsafeValueAccess.cs",
    "content": "﻿using System.Buffers;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.UnsafeValueAccess;\n\npublic static class UnsafeValueAccessExtensions\n{\n    public static A? ValueUnsafe<A>(this Option<A> option) =>\n        option.IsSome\n            ? option.Value\n            : default;\n\n    public static A Value<A>(this Option<A> option) where A : struct =>\n        option.IsSome\n            ? option.Value\n            : default;\n\n    public static R Value<L, R>(this Either<L, R> either) where R : struct =>\n        either.IsRight\n            ? either.RightValue\n            : default;\n\n    public static R? ValueUnsafe<L, R>(this Either<L, R> either) =>\n        either.IsRight\n            ? either.RightValue\n            : default;\n\n    /// <summary>\n    /// This creates a Seq from an Array without any copying of data, so it's super fast\n    /// However because the input array is mutable it weakens the guarantees of the immutable Seq, so this is not\n    /// advised unless you know what you're doing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> ToSeqUnsafe<A>(this A[] value) =>\n        Seq.FromArray(value);\n\n    /// <summary>\n    /// This creates a Seq from an Array without any copying of data, so it's super fast\n    /// However because the input array is mutable it weakens the guarantees of the immutable Seq, so this is not\n    /// advised unless you know what you're doing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> ToSeqUnsafe<A>(this A[] value, int length) =>\n        Seq.FromArray(value, length);\n\n    /// <summary>\n    /// This creates a Seq from an Array without any copying of data, so it's super fast\n    /// However because the input array is mutable it weakens the guarantees of the immutable Seq, so this is not\n    /// advised unless you know what you're doing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static SeqLoan<A> ToSeqLoanUnsafe<A>(this A[] value, ArrayPool<A> pool) =>\n        new (value, pool, 0, value.Length);\n\n    /// <summary>\n    /// This creates a Seq from an Array without any copying of data, so it's super fast\n    /// However because the input array is mutable it weakens the guarantees of the immutable Seq, so this is not\n    /// advised unless you know what you're doing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static SeqLoan<A> ToSeqLoanUnsafe<A>(this A[] value, int length, ArrayPool<A> pool) =>\n        new (value, pool, 0, length);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Guard.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Used by various error-producing monads to have a contextual `where`\n/// </summary>\n/// <remarks>\n/// See `Prelude.guard(...)`\n/// </remarks>\npublic readonly struct Guard<E, A>\n{\n    public readonly bool Flag;\n    readonly Func<E> onFalse;\n\n    internal Guard(bool flag, Func<E> onFalse) =>\n        (Flag, this.onFalse) = (flag, onFalse ?? throw new ArgumentNullException(nameof(onFalse)));\n\n    internal Guard(bool flag, E onFalse)\n    {\n        if (isnull(onFalse)) throw new ArgumentNullException(nameof(onFalse));\n        (Flag, this.onFalse) = (flag, () => onFalse);\n    }\n\n    public Guard<E, B> Cast<B>() =>\n        new (Flag, OnFalse);\n        \n    public Func<E> OnFalse =>\n        onFalse ?? throw new InvalidOperationException(\n            \"Guard isn't initialised. It was probably created via new Guard() or default(Guard), and so it has no OnFalse handler\");\n\n    public Guard<E, C> SelectMany<C>(Func<E, Guard<E, Unit>> bind, Func<Unit, Unit, C> project) =>\n        Flag ? bind(default!).Cast<C>() : Cast<C>();\n\n    public Guard<E, B> Select<B>(Func<B, B> _) =>\n        Cast<B>();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Arr/Arr.Module.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic partial class Arr\n{\n    /// <summary>\n    /// Create an empty array\n    /// </summary>\n    [Pure]\n    public static Arr<T> empty<T>() =>\n        Arr<T>.Empty;\n\n    /// <summary>\n    /// Create a new empty array\n    /// </summary>\n    /// <returns>Lst T</returns>\n    [Pure]\n    public static Arr<T> create<T>() =>\n        Arr<T>.Empty;\n\n    /// <summary>\n    /// Create a singleton array\n    /// </summary>\n    /// <param name=\"value\">Single value</param>\n    /// <returns>Collection with a single item in it</returns>\n    [Pure]\n    public static Arr<A> singleton<A>(A value) =>\n        [value];\n    \n    /// <summary>\n    /// Create an array from a initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>Lst T</returns>\n    [Pure]\n    public static Arr<T> create<T>(ReadOnlySpan<T> items) =>\n        items.IsEmpty ? empty<T>() : new Arr<T>(items);    \n\n    /// <summary>\n    /// Create an array from a initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>Lst T</returns>\n    [Pure]\n    public static Arr<T> create<T>(params T[] items) =>\n        new (items);\n\n    /// <summary>\n    /// Create an array from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>Lst T</returns>\n    [Pure]\n    public static Arr<T> createRange<T>(IEnumerable<T> items) =>\n        new (items);\n\n    /// <summary>\n    /// Add an item to the array\n    /// </summary>\n    /// <param name=\"array\">Array</param>\n    /// <param name=\"value\">Item to add</param>\n    /// <returns>A new Lst T</returns>\n    [Pure]\n    public static Arr<T> add<T>(Arr<T> array, T value) =>\n        array.Add(value);\n\n    /// <summary>\n    /// Add a range of items to the array\n    /// </summary>\n    /// <param name=\"array\">Array</param>\n    /// <param name=\"value\">Items to add</param>\n    /// <returns>A new Lst T</returns>\n    [Pure]\n    public static Arr<T> addRange<T>(Arr<T> array, IEnumerable<T> value) =>\n        array.AddRange(value);\n\n    /// <summary>\n    /// Remove an item from the array\n    /// </summary>\n    /// <param name=\"array\">Array</param>\n    /// <param name=\"value\">value to remove</param>\n    /// <returns>A new Lst T</returns>\n    [Pure]\n    public static Arr<T> remove<T>(Arr<T> array, T value) =>\n        array.Remove(value);\n\n    /// <summary>\n    /// Remove an item at a specified index in the array\n    /// </summary>\n    /// <param name=\"array\">Array</param>\n    /// <param name=\"index\">Index of item to remove</param>\n    /// <returns>A new Lst T</returns>\n    [Pure]\n    public static Arr<T> removeAt<T>(Arr<T> array, int index) =>\n        array.RemoveAt(index);\n\n    /// <summary>\n    /// Reverses the array (Reverse in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Array item type</typeparam>\n    /// <param name=\"array\">Array to reverse</param>\n    /// <returns>Reversed list</returns>\n    [Pure]\n    public static T[] rev<T>(T[] array)\n    {\n        var l = array.Length;\n        var n = new T[l];\n        var i = 0;\n        var j = l - 1;\n        for (; i < l; i++, j--)\n        {\n            n[i] = array[j];\n        }\n        return n;\n    }\n\n    /// <summary>\n    /// Reverses the array (Reverse in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Array item type</typeparam>\n    /// <param name=\"array\">Array to reverse</param>\n    /// <returns>Reversed list</returns>\n    [Pure]\n    public static Arr<T> rev<T>(Arr<T> array) =>\n        array.Reverse();\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static A[] flatten<A>(A[][] ma) =>\n        ma.Bind(identity).ToArray();\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Arr<A> flatten<A>(Arr<Arr<A>> ma) =>\n        ma.Bind(identity);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Arr/Arr.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing static LanguageExt.Prelude;\nusing LanguageExt.Traits;\nusing LanguageExt.ClassInstances;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable array\n/// Native array O(1) read performance.  Modifications require copying of the entire \n/// array to generate the newly mutated version.  This is will be very expensive \n/// for large arrays.\n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\n[Serializable]\n[CollectionBuilder(typeof(Arr), nameof(Arr.create))]\npublic readonly struct Arr<A> :\n    IReadOnlyList<A>,\n    IEquatable<Arr<A>>,\n    IComparable<Arr<A>>,\n    Monoid<Arr<A>>,\n    IComparisonOperators<Arr<A>, Arr<A>, bool>,\n    IAdditionOperators<Arr<A>, Arr<A>, Arr<A>>,\n    IAdditiveIdentity<Arr<A>, Arr<A>>,\n    TokenStream<Arr<A>, A>,\n    IComparable,\n    K<Arr, A>\n{\n    /// <summary>\n    /// Empty array\n    /// </summary>\n    public static Arr<A> Empty { get; } = new (System.Array.Empty<A>());\n\n    readonly A[]? value;\n    readonly int start;\n    readonly int length;\n    readonly Atom<int>? hashCode;\n\n    A[] Value\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value ?? Empty.Value;\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr(IEnumerable<A> initial)\n    {\n        hashCode = Atom(0);\n        value = initial.ToArray();\n        start = 0;\n        length = value.Length;\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr(ReadOnlySpan<A> initial)\n    {\n        hashCode = Atom(0);\n        value = initial.ToArray();\n        start = 0;\n        length = value.Length;\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal Arr(A[] value)\n    {\n        hashCode = Atom(0);\n        this.value = value;\n        start = 0;\n        length = value.Length;\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal Arr(A[] value, int start, int length)\n    {\n        if(start < 0) throw new ArgumentOutOfRangeException(nameof(start));\n        if(start + length > value.Length) throw new ArgumentOutOfRangeException(nameof(length));\n        hashCode = Atom(0);\n        this.value = value;\n        this.start = start;\n        this.length = length;\n    }\n    \n    /// <summary>\n    /// Create a readonly span of this array.  This doesn't do any copying, so it is very fast.   \n    /// </summary>\n    /// <param name=\"start\">Offset from the beginning of the array</param>\n    /// <param name=\"count\">The number of items to take. This will be clamped\n    /// to the maximum number of items available</param>\n    /// <returns>A read-only span of values</returns>\n    /// <exception cref=\"IndexOutOfRangeException\">Thrown If the start index is outside the range of the array</exception>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan() =>\n        new (Value, start, length);\n\n    /// <summary>\n    /// Create a readonly sub-span of this array.  This doesn't do any copying, so is very fast, but be aware that any\n    /// items outside the splice are still active.   \n    /// </summary>\n    /// <param name=\"start\">Offset from the beginning of the array</param>\n    /// <returns>A read-only span of values</returns>\n    /// <exception cref=\"IndexOutOfRangeException\">Thrown If the start index is outside the range of the array</exception>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan(int start)\n    {\n        if (start < 0 || start >= length) throw new IndexOutOfRangeException(nameof(start));\n        var t = Math.Max(0, length - start);\n        return new(Value, this.start + start, t);\n    }\n\n    /// <summary>\n    /// Create a readonly sub-span of this array.  This doesn't do any copying, so is very fast, but be aware that any\n    /// items outside the splice are still active.   \n    /// </summary>\n    /// <param name=\"start\">Offset from the beginning of the array</param>\n    /// <param name=\"count\">The number of items to take. This will be clamped to the maximum number of items available</param>\n    /// <returns>A read-only span of values</returns>\n    /// <exception cref=\"IndexOutOfRangeException\">Thrown If the start index is outside the range of the array</exception>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan(int start, int count)\n    {\n        if (start < 0 || start >= length) throw new IndexOutOfRangeException(nameof(start));\n        var t = Math.Max(0, Math.Min(count, length - start));\n        return new(Value, this.start + start, t);\n    }\n    \n    /// <summary>\n    /// Create a subarray of this array.  This doesn't do any copying, so is very fast, but be aware that any items\n    /// outside the splice are still active.   \n    /// </summary>\n    /// <param name=\"start\">Offset from the beginning of the array</param>\n    /// <returns></returns>\n    /// <exception cref=\"IndexOutOfRangeException\">Thrown If the start index is outside the range of the array</exception>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Splice(int start)\n    {\n        var arr = Value;\n        if (start < 0 || start >= length) throw new IndexOutOfRangeException(nameof(start));\n        var t = Math.Max(0, length - start);\n        return new Arr<A>(arr, this.start + start, t);   \n    }\n    \n    /// <summary>\n    /// Create a subarray of this array.  This doesn't do any copying, so is very fast, but be aware that any items\n    /// outside the splice are still active.   \n    /// </summary>\n    /// <param name=\"start\">Offset from the beginning of the array</param>\n    /// <param name=\"count\">The number of items to take. This will be clamped to the maximum number of items available</param>\n    /// <returns></returns>\n    /// <exception cref=\"IndexOutOfRangeException\">Thrown If the start index is outside the range of the array</exception>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Splice(int start, int count)\n    {\n        var arr = Value;\n        if (start < 0 || start >= length) throw new IndexOutOfRangeException(nameof(start));\n        var t = Math.Max(0, Math.Min(count, length - start));\n        return new Arr<A>(arr, this.start + start, t);   \n    }\n    \n    [Pure]\n    public Arr<A> Tail =>\n        IsEmpty\n            ? this\n            : Splice(1, length - 1);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Arr<A>(A[] xs) =>\n        new (xs);\n\n    /// <summary>\n    /// Head lens\n    /// </summary>\n    [Pure]\n    public static Lens<Arr<A>, A> head => Lens<Arr<A>, A>.New(\n        Get: la => la.Count == 0 ? throw new IndexOutOfRangeException() : la[0],\n        Set: a => la => la.Count == 0 ? throw new IndexOutOfRangeException() : la.SetItem(0, a));\n\n    /// <summary>\n    /// Head or none lens\n    /// </summary>\n    [Pure]\n    public static Lens<Arr<A>, Option<A>> headOrNone => Lens<Arr<A>, Option<A>>.New(\n        Get: la => la.Count == 0 ? None : Some(la[0]),\n        Set: a => la => la.Count == 0 || a.IsNone ? la : la.SetItem(0, a.Value!));\n\n    /// <summary>\n    /// Last lens\n    /// </summary>\n    [Pure]\n    public static Lens<Arr<A>, A> last => Lens<Arr<A>, A>.New(\n        Get: la => la.Count == 0 ? throw new IndexOutOfRangeException() : la[^1],\n        Set: a => la => la.Count == 0 ? throw new IndexOutOfRangeException() : la.SetItem(la.Count - 1, a));\n\n    /// <summary>\n    /// Last or none lens\n    /// </summary>\n    [Pure]\n    public static Lens<Arr<A>, Option<A>> lastOrNone => Lens<Arr<A>, Option<A>>.New(\n        Get: la => la.Count == 0 ? None : Some(la[^1]),\n        Set: a => la => la.Count == 0 || a.IsNone ? la : la.SetItem(la.Count - 1, a.Value!));\n\n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Arr<A>, A> item(int index) => Lens<Arr<A>, A>.New(\n        Get: la => la.Count == 0 ? throw new IndexOutOfRangeException() : la[index],\n        Set: a => la => la.Count == 0 ? throw new IndexOutOfRangeException() : la.SetItem(index, a));\n\n    /// <summary>\n    /// Item or none at index lens\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Arr<A>, Option<A>> itemOrNone(int index) => Lens<Arr<A>, Option<A>>.New(\n        Get: la => la.Count < index - 1 ? None : Some(la[index]),\n        Set: a => la => la.Count < index - 1 || a.IsSome ? la : la.SetItem(index, a.Value!));\n\n    /// <summary>\n    /// Lens map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Arr<A>, Arr<B>> map<B>(Lens<A, B> lens) => Lens<Arr<A>, Arr<B>>.New(\n        Get: la => la.Map(lens.Get),\n        Set: lb => la => la.Zip(lb).Map(ab => lens.Set(ab.Item2, ab.Item1)).ToArr());\n\n    /// <summary>\n    /// Index accessor\n    /// </summary>\n    [Pure]\n    public A this[Index index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => index.IsFromEnd switch\n               {\n                   false => Value[start          + index.Value],\n                   true  => Value[start + length - index.Value - 1]\n               };\n    }\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = result is null\n    ///     Singleton collection = result is A\n    ///     More                 = result is (A, Seq〈A〉) -- head and tail\n    ///\n    ///  Example:\n    ///\n    ///     var res = arr.Case switch\n    ///     {\n    ///       \n    ///        A value         => ...,\n    ///        (var x, var xs) => ...,\n    ///        _               => ...\n    ///     }\n    ///\n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty\n            ? null\n            : Count == 1\n                ? this[0]\n                : toSeq(this).Case;\n\n    /// <summary>\n    /// Is the stack empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value == null || length == 0;\n    }\n\n    /// <summary>\n    /// Number of items in the stack\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value == null ? 0 : length;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value == null ? 0 : length;\n    }\n\n    [Pure]\n    int IReadOnlyCollection<A>.Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Count;\n    }\n\n    [Pure]\n    A IReadOnlyList<A>.this[int index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value[start + index];\n    }\n\n    /// <summary>\n    /// Add an item to the end of the array\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Add(A valueToAdd)\n    {\n        var self = Value;\n        return self.Length == 0 \n                   ? new Arr<A>([valueToAdd]) \n                   : Insert(self.Length, valueToAdd);\n    }\n\n    /// <summary>\n    /// Add a range of items to the end of the array\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> AddRange(IEnumerable<A> items) =>\n        InsertRange(Count, items);\n\n    /// <summary>\n    /// Clear the array\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Enumerator GetEnumerator() =>\n        new (this);\n\n    public struct Enumerator\n    {\n        readonly A[] arr;\n        int index;\n        int end;\n\n        internal Enumerator(in Arr<A> arr)\n        {\n            this.arr = arr.Value;\n            index = arr.start -1;\n            end = arr.start   + arr.length;\n        }\n\n        public readonly A Current => arr[index];\n\n        public bool MoveNext() => ++index < end;\n    }\n\n    /// <summary>\n    /// Find the index of an item\n    /// </summary>\n    [Pure]\n    public int IndexOf(A item, int index = 0, int count = -1, IEqualityComparer<A>? equalityComparer = null)\n    {\n        var eq = equalityComparer ?? EqualityComparer<A>.Default;\n\n        for (; index >= 0 && index < length && count != 0; index++, count--)\n        {\n            if (eq.Equals(item, this[index])) return index;\n        }\n        return -1;\n    }\n\n    /// <summary>\n    /// Find the index of an item\n    /// </summary>\n    [Pure]\n    public int LastIndexOf(A item, int index = -1, int count = -1, IEqualityComparer<A>? equalityComparer = null)\n    {\n        var eq = equalityComparer ?? EqualityComparer<A>.Default;\n\n        var arr = Value;\n        index = index < 0 ? length - 1 : index;\n\n        for (; index >= 0 && index < length && count != 0; index--, count--)\n        {\n            if (eq.Equals(item, this[index])) return index;\n        }\n        return -1;\n    }\n\n    /// <summary>\n    /// Find the index of an item\n    /// </summary>\n    [Pure]\n    public int IndexOf<EQ>(A item, int index = 0, int count = -1) where EQ : Eq<A>\n    {\n        var arr = Value;\n        for (; index < length && count != 0; index++, count--)\n        {\n            if (EQ.Equals(item, this[index])) return index;\n        }\n        return -1;\n    }\n\n    /// <summary>\n    /// Find the index of an item\n    /// </summary>\n    [Pure]\n    public int LastIndexOf<EQ>(A item, int index = -1, int count = -1) where EQ : Eq<A>\n    {\n        var arr = Value;\n        index = index < 0 ? length - 1 : index;\n\n        for (; index >= 0 && index < length && count != 0; index--, count--)\n        {\n            if (EQ.Equals(item, this[index])) return index;\n        }\n        return -1;\n    }\n\n    /// <summary>\n    /// Insert value at specified index\n    /// </summary>\n    [Pure]\n    public Arr<A> Insert(int index, A valueToInsert)\n    {\n        var arr = Value;\n        if (index < 0 || index > Length) throw new IndexOutOfRangeException(nameof(index));\n        if (length == 0)\n        {\n            return new Arr<A>([valueToInsert]);\n        }\n\n        var xs = new A[length + 1];\n        xs[index] = valueToInsert;\n\n        if (index != 0)\n        {\n            System.Array.Copy(arr, start, xs, 0, index);\n        }\n        if (index != arr.Length)\n        {\n            System.Array.Copy(arr, start + index, xs, index + 1, length - index);\n        }\n        return new Arr<A>(xs);\n    }\n\n    /// <summary>\n    /// Insert range of values at specified index\n    /// </summary>\n    [Pure]\n    public Arr<A> InsertRange(int index, IEnumerable<A> items)\n    {\n        var arr = Value;\n        if (index < 0 || index > Length) throw new IndexOutOfRangeException(nameof(index));\n\n        if (length == 0)\n        {\n            return new Arr<A>(items);\n        }\n\n        var insertArr = items.ToArray();\n\n        var count = insertArr.Length;\n        if (count == 0)\n        {\n            return this;\n        }\n\n        var newArray = new A[length + count];\n\n        if (index != 0)\n        {\n            System.Array.Copy(arr, start, newArray, 0, index);\n        }\n        if (index != arr.Length)\n        {\n            System.Array.Copy(arr, start + index, newArray, index + count, length - index);\n        }\n        insertArr.CopyTo(newArray, index);\n\n        return new Arr<A>(newArray);\n    }\n\n    /// <summary>\n    /// Remove an item from the array\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Remove(A valueToRemove) =>\n        Remove<EqDefault<A>>(valueToRemove);\n\n    /// <summary>\n    /// Remove an item from the array\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Remove(A valueToRemove, IEqualityComparer<A> equalityComparer)\n    {\n        var index = IndexOf(valueToRemove, 0, -1, equalityComparer);\n        return index < 0\n                   ? this\n                   : RemoveAt(index);\n    }\n\n    /// <summary>\n    /// Remove an item from the array\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Remove<EQ>(A valueToRemove) where EQ : Eq<A>\n    {\n        var index = IndexOf<EQ>(valueToRemove);\n        return index < 0\n                   ? this\n                   : RemoveAt(index);\n    }\n\n    /// <summary>\n    /// Remove all items that match a predicate\n    /// </summary>\n    [Pure]\n    public Arr<A> RemoveAll(Predicate<A> pred)\n    {\n        if (IsEmpty) return this;\n\n        List<int>? removeIndices = null;\n        for (var i = 0; i < Length; i++)\n        {\n            if (pred(this[i]))\n            {\n                if (removeIndices == null)\n                {\n                    removeIndices = new List<int>();\n                }\n                removeIndices.Add(i);\n            }\n        }\n\n        return removeIndices != null\n                   ? RemoveAtRange(removeIndices)\n                   : this;\n    }\n\n    [Pure]\n    private Arr<A> RemoveAtRange(List<int> remove)\n    {\n        var arr = Value;\n        if (remove.Count == 0) return this;\n\n        var newArray         = new A[length - remove.Count];\n        var copied           = 0;\n        var removed          = 0;\n        var lastIndexRemoved = -1;\n        foreach (var item in remove)\n        {\n            var copyLength = lastIndexRemoved == -1 ? item : (item - lastIndexRemoved - 1);\n            System.Array.Copy(arr, start + copied + removed, newArray, copied, copyLength);\n            removed++;\n            copied += copyLength;\n            lastIndexRemoved = item;\n        }\n        System.Array.Copy(arr, start + copied + removed, newArray, copied, length - (copied + removed));\n        return new Arr<A>(newArray);\n    }\n\n    /// <summary>\n    /// Remove item at location\n    /// </summary>\n    /// <param name=\"index\"></param>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> RemoveAt(int index) =>\n        RemoveRange(index, 1);\n\n    /// <summary>\n    /// Remove a range of items\n    /// </summary>\n    [Pure]\n    public Arr<A> RemoveRange(int index, int count)\n    {\n        var arr = Value;\n        if (index < 0 || index > Length) throw new IndexOutOfRangeException(nameof(index));\n        if (!(count >= 0 && index + count <= Length)) throw new IndexOutOfRangeException(nameof(index));\n        if (count == 0) return this;\n\n        var newArray = new A[length - count];\n        System.Array.Copy(arr, start, newArray, 0, index);\n        System.Array.Copy(arr, start + index + count, newArray, index, length - index - count);\n        return new Arr<A>(newArray);\n    }\n\n    /// <summary>\n    /// Set an item at the specified index\n    /// </summary>\n    [Pure]\n    public Arr<A> SetItem(int index, A valueToSet)\n    {\n        var arr = Value;\n        if (index < 0 || index >= arr.Length) throw new IndexOutOfRangeException(nameof(index));\n\n        var newArray = new A[Length];\n        System.Array.Copy(arr, start, newArray, 0, length);\n        newArray[index] = valueToSet;\n        return new Arr<A>(newArray);\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Value.GetEnumerator();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<A> IEnumerable<A>.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Value.AsEnumerable().GetEnumerator();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> AsIterable() =>\n        Iterable.createRange(this);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> ToSeq() =>\n        toSeq(this);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(this, Count);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(this, separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(this, separator);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> Skip(int amount)\n    {\n        var s = start;\n        var e = start + length;\n        return Iterable.createRange(Go(s, e, Value));\n        static IEnumerable<A> Go(int s, int e, A[] v)\n        {\n            for (var i = s; i < e; i++)\n            {\n                yield return v[i];\n            }\n        }\n    }\n        //Value.Skip(start + amount).AsIterable();\n\n    /// <summary>\n    /// Reverse the order of the items in the array\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Reverse()\n    {\n        var l = Count;\n        var n = new A[l];\n        var v = Value;\n        var i = 0;\n        var j = l - 1;\n        for (; i < l; i++, j--)\n        {\n            n[i] = v[j + start];\n        }\n        return new Arr<A>(n);\n    }\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Do(Action<A> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<B> Map<B>(Func<A, B> map)\n    {\n        var arr      = Value;\n        var newArray = new B[length];\n        for (var i = 0; i < length; i++)\n        {\n            newArray[i] = map(arr[start + i]);\n        }\n        return new Arr<B>(newArray);\n    }\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Arr<B>> Traverse<F, B>(Func<A, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, Arr<B>> TraverseM<M, B>(Func<A, K<M, B>> f) \n        where M : Monad<M> =>\n        M.Map(x => x.As(), Traversable.traverseM(f, this));\n    \n    /// <summary>\n    /// Filter\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Filter(Func<A, bool> pred) =>\n        RemoveAll(x => !pred(x));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Arr<A> operator +(Arr<A> lhs, A rhs) =>\n        lhs.Add(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Arr<A> operator +(A lhs, Arr<A> rhs) =>\n        rhs.Insert(0, lhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Arr<A> operator +(Arr<A> lhs, Arr<A> rhs) =>\n        rhs.InsertRange(0, lhs);\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Arr<A> operator |(Arr<A> x, K<Arr, A> y) =>\n        x.Choose(y).As();\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Arr<A> operator |(K<Arr, A> x, Arr<A> y) =>\n        x.Choose(y).As();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> Combine(Arr<A> rhs) =>\n        rhs.InsertRange(0, this);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is Arr<A> @as && Equals(@as);\n\n    /// <summary>\n    /// Get the hash code\n    /// Lazily (and once only) calculates the hash from the elements in the array\n    /// Empty array hash == 0\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode()\n    {\n        if (hashCode is null)\n            return CalcHashCode();\n        \n        var self = this;\n        return hashCode == 0\n            ? hashCode.Swap(_ => self.CalcHashCode())\n            : hashCode;\n    }\n\n    int CalcHashCode() =>\n        FNV32.Hash<HashableDefault<A>, A>(Value, start, length);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(object? obj) =>\n        obj is Arr<A> t ? CompareTo(t) : 1;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(Arr<A> other)\n    {\n        if (Count != other.Count) return false;\n\n        var ia = GetEnumerator();\n        var ib = other.GetEnumerator();\n        while (ia.MoveNext() && ib.MoveNext())\n        {\n            if (!EqDefault<A>.Equals(ia.Current, ib.Current)) return false;\n        }\n        return true;\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(Arr<A> other)\n    {\n        if (Count < other.Count) return -1;\n        if (Count > other.Count) return 1;\n\n        var ia = GetEnumerator();\n        var ib = other.GetEnumerator();\n        while (ia.MoveNext() && ib.MoveNext())\n        {\n            var cmp = OrdDefault<A>.Compare(ia.Current, ib.Current);\n            if (cmp != 0) return cmp;\n        }\n        return 0;\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(Arr<A> lhs, Arr<A> rhs) =>\n        lhs.Equals(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(Arr<A> lhs, Arr<A> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<B> Bind<B>(Func<A, Arr<B>> f)\n    {\n        var res = new List<B>();\n\n        foreach (var t in this)\n        {\n            foreach (var u in f(t))\n            {\n                res.Add(u);\n            }\n        }\n        return new Arr<B>(res);\n    }\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Arr<A>(SeqEmpty _) =>\n        Empty;\n    \n    public static bool operator >(Arr<A> left, Arr<A> right) =>\n        left.CompareTo(right) > 0;\n    \n    public static bool operator >=(Arr<A> left, Arr<A> right) =>\n        left.CompareTo(right) >= 0;\n    \n    public static bool operator <(Arr<A> left, Arr<A> right) =>\n        left.CompareTo(right) < 0;\n    \n    public static bool operator <=(Arr<A> left, Arr<A> right) =>\n        left.CompareTo(right) <= 0;\n\n    public static Arr<A> AdditiveIdentity => \n        Empty;\n\n    static bool TokenStream<Arr<A>, A>.IsTab(A token) =>\n        false;\n\n    static bool TokenStream<Arr<A>, A>.IsNewline(A token) => \n        false;\n\n    static ReadOnlySpan<char> TokenStream<Arr<A>, A>.TokenToString(A token) => \n        (token?.ToString() ?? \"\").AsSpan() ;\n\n    static Arr<A> TokenStream<Arr<A>, A>.TokenToChunk(in A token) => \n        Arr.singleton(token);\n\n    static Arr<A> TokenStream<Arr<A>, A>.TokensToChunk(in ReadOnlySpan<A> token) => \n        [..token];\n\n    static ReadOnlySpan<A> TokenStream<Arr<A>, A>.ChunkToTokens(in Arr<A> tokens) => \n        tokens.As().AsSpan();\n\n    static int TokenStream<Arr<A>, A>.ChunkLength(in Arr<A> tokens) => \n        tokens.As().Count;\n\n    static bool TokenStream<Arr<A>, A>.Take1(in Arr<A> stream, out A head, out Arr<A> tail)\n    {\n        var s = stream.As();\n        if (s.IsEmpty)\n        {\n            head = default!;\n            tail = stream;\n            return false;\n        }\n        else\n        {\n            head = s[0];\n            tail = s.Tail;\n            return true;\n        }\n    }\n\n    static bool TokenStream<Arr<A>, A>.Take(int amount, in Arr<A> stream, out Arr<A> head, out Arr<A> tail)\n    {\n        // If the requested length `amount` is 0 (or less), `false` should\n        // not be returned, instead `true` and `(out Empty, out stream)` should be returned.\n        if (amount <= 0)\n        {\n            head = Empty;\n            tail = stream;\n            return true;\n        }\n\n        // If the requested length is greater than 0 and the stream is\n        // empty, `false` should be returned indicating end-of-input.\n        if (stream.Length <= 0)\n        {\n            head = Empty;\n            tail = stream;\n            return false;\n        }\n        \n        // In other cases, take chunk of length `amount` (or shorter if the\n        // stream is not long enough) from the input stream and return the\n        // chunk along with the rest of the stream.\n        amount = Math.Min(amount, stream.Length);\n        var start = stream.start;\n        var value = stream.Value;\n        head = new Arr<A>(value, start, amount);\n        tail = new Arr<A>(value, start + amount, stream.Length - amount);\n        return true;\n    }\n\n    static void TokenStream<Arr<A>, A>.TakeWhile(Func<A, bool> predicate, in Arr<A> stream, out Arr<A> head, out Arr<A> tail)\n    {\n        var s       = stream.As();\n        var array   = s.Value;\n        var start   = s.start;\n        var length  = s.length;\n        var current = start;\n        var offset  = 0;\n        while(current < length)\n        {\n            if (predicate(array[current]))\n            {\n                current++;\n                offset++;\n            }\n            else\n            {\n                head = new Arr<A>(array, start, current - start);\n                tail = new Arr<A>(array, current, length - offset);\n                return;\n            }\n        }\n        head = stream;\n        tail = Empty;\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Arr/Extensions/Arr.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ArrExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Arr<B> Map<A, B>(this Func<A, B> f, K<Arr, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Arr<B> Map<A, B>(this Func<A, B> f, Arr<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Arr<B> Action<A, B>(this Arr<A> ma, K<Arr, B> mb) =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Arr<B> Action<A, B>(this K<Arr, A> ma, K<Arr, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Arr<B> Apply<A, B>(this Arr<Func<A, B>> mf, K<Arr, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Arr<B> Apply<A, B>(this K<Arr, Func<A, B>> mf, K<Arr, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Arr/Extensions/Arr.Extensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ArrExtensions\n{\n    public static Arr<A> As<A>(this K<Arr, A> xs) =>\n        (Arr<A>)xs;\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static A[] Flatten<A>(this A[][] ma) =>\n        ma.Bind(identity).ToArray();\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Arr<A> Flatten<A>(this Arr<Arr<A>> ma) =>\n        ma.Bind(identity);\n\n    [Pure]\n    public static Arr<A> Filter<A>(this Arr<A> ma, Func<A, bool> f) =>\n        Where(ma, f);\n\n    [Pure]\n    public static Arr<A> Where<A>(this Arr<A> ma, Func<A, bool> f)\n    {\n        var mb = new List<A>();\n        foreach (var a in ma)\n        {\n            if (f(a))\n            {\n                mb.Add(a);\n            }\n        }\n        return new Arr<A>(mb);\n    }\n\n    [Pure]\n    public static Arr<B> Map<A, B>(this Arr<A> ma, Func<A, B> f) =>\n        Select(ma, f);\n\n    [Pure]\n    public static Arr<B> Select<A, B>(this Arr<A> ma, Func<A, B> f)\n    {\n        var mb = new B[ma.Count];\n        var index = 0;\n        foreach (var a in ma)\n        {\n            mb[index] = f(a);\n            index++;\n        }\n        return new Arr<B>(mb);\n    }\n\n    [Pure]\n    public static Arr<B> Bind<A, B>(this Arr<A> ma, Func<A, Arr<B>> f) =>\n        SelectMany(ma, f);\n\n    [Pure]\n    public static Arr<B> SelectMany<A, B>(this Arr<A> ma, Func<A, Arr<B>> f)\n    {\n        var mb = new List<B>();\n        foreach (var a in ma)\n        {\n            foreach (var b in f(a))\n            {\n                mb.Add(b);\n            }\n        }\n        return new Arr<B>(mb.ToArray());\n    }\n\n    [Pure]\n    public static Arr<C> SelectMany<A, B, C>(this Arr<A> ma, Func<A, Arr<B>> bind, Func<A, B, C> project)\n    {\n        var mc = new List<C>();\n        foreach (var a in ma)\n        {\n            foreach (var b in bind(a))\n            {\n                mc.Add(project(a, b));\n            }\n        }\n        return new Arr<C>(mc.ToArray());\n    }\n    \n    /// <summary>\n    /// Convert to a queryable \n    /// </summary>\n    [Pure]\n    public static IQueryable<A> AsQueryable<A>(this Arr<A> source) =>\n        // NOTE TO FUTURE ME: Don't delete this thinking it's not needed!\n        // NOTE FROM FUTURE ME: Next time you leave a message for your future self, explain your reasoning.\n        source.AsEnumerable().AsQueryable();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Arr/Operators/Arr.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ArrExtensions\n{\n    extension<A>(K<Arr, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Arr<A> operator +(K<Arr, A> ma) =>\n            (Arr<A>)ma;\n        \n        public static Arr<A> operator >> (K<Arr, A> ma, Lower lower) =>\n            (Arr<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Arr/Prelude/Arr.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Arr<B> map<A, B>(Func<A, B> f, K<Arr, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Arr<B> action<A, B>(K<Arr, A> ma, K<Arr, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Arr<B> apply<A, B>(K<Arr, Func<A, B>> mf, K<Arr, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Arr/Trait/Arr.TraitImpl.cs",
    "content": "using System;\nusing System.Linq;\nusing LanguageExt.Traits;\nusing System.Collections.Generic;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class Arr : \n    Monad<Arr>, \n    Traversable<Arr>, \n    Alternative<Arr>,\n    MonoidK<Arr>,\n    Natural<Arr, Seq>,\n    Natural<Arr, Iterable>,\n    Natural<Arr, Lst>,\n    Natural<Arr, Set>,\n    Natural<Arr, HashSet>\n{\n    static K<Arr, B> Monad<Arr>.Bind<A, B>(K<Arr, A> ma, Func<A, K<Arr, B>> f)\n    {\n        return new Arr<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var x in ma.As())\n            {\n                foreach (var y in f(x).As())\n                {\n                    yield return y;\n                }\n            }\n        }\n    }\n\n    static K<Arr, B> Monad<Arr>.Recur<A, B>(A value, Func<A, K<Arr, Next<A, B>>> f) =>\n        createRange(Monad.enumerableRecur(value, x =>f(x).As().AsEnumerable()));\n\n    static K<Arr, B> Functor<Arr>.Map<A, B>(Func<A, B> f, K<Arr, A> ma) => \n        ma.As().Map(f);\n\n    static K<Arr, A> Applicative<Arr>.Pure<A>(A value) =>\n        singleton(value);\n\n    static K<Arr, B> Applicative<Arr>.Apply<A, B>(K<Arr, Func<A, B>> mf, K<Arr, A> ma) \n    {\n        var ff   = mf.As();\n        if(ff.IsEmpty) return Arr<B>.Empty;\n        var fa   = ma.As();\n        var size = ff.Count * fa.Count;\n        var bs   = new B[size];\n        var ix   = 0;\n        foreach (var f in ff)\n        {\n            foreach (var a in fa)\n            {\n                bs[ix] = f(a);\n                ix++;\n            }\n        }\n        return new Arr<B>(bs);\n    }    \n\n    static K<Arr, B> Applicative<Arr>.Apply<A, B>(K<Arr, Func<A, B>> mf, Memo<Arr, A> ma)\n    {\n        var ff   = mf.As();\n        if(ff.IsEmpty) return Arr<B>.Empty;\n        var fa   = ma.Value.As();\n        var size = ff.Count * fa.Count;\n        var bs   = new B[size];\n        var ix   = 0;\n        foreach (var f in ff)\n        {\n            foreach (var a in fa)\n            {\n                bs[ix] = f(a);\n                ix++;\n            }\n        }\n        return new Arr<B>(bs);\n    }    \n\n    static K<Arr, A> MonoidK<Arr>.Empty<A>() =>\n        Arr<A>.Empty;\n\n    static K<Arr, A> Alternative<Arr>.Empty<A>() =>\n        Arr<A>.Empty;\n\n    static K<Arr, A> SemigroupK<Arr>.Combine<A>(K<Arr, A> ma, K<Arr, A> mb) =>\n        ma.As() + mb.As();\n    \n    static K<Arr, A> Choice<Arr>.Choose<A>(K<Arr, A> ma, K<Arr, A> mb) => \n        ma.IsEmpty ? mb : ma;\n\n    static K<Arr, A> Choice<Arr>.Choose<A>(K<Arr, A> ma, Memo<Arr, A> mb) => \n        ma.IsEmpty ? mb.Value : ma;\n\n    static int Foldable<Arr>.Count<A>(K<Arr, A> ta) =>\n        ta.As().Count;\n\n    static bool Foldable<Arr>.IsEmpty<A>(K<Arr, A> ta) =>\n        ta.As().IsEmpty;\n\n    static S Foldable<Arr>.FoldWhile<A, S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S state, K<Arr, A> ta)\n    {\n        var arr = ta.As();\n        foreach (var x in arr)\n        {\n            if (!predicate((state, x))) return state;\n            state = f(x)(state);\n        }\n        return state;\n    }\n\n    static S Foldable<Arr>.FoldBackWhile<A, S>(Func<S, Func<A, S>> f, Func<(S State, A Value), bool> predicate, S state, K<Arr, A> ta) \n    {\n        var arr = ta.As();\n        for (var i = arr.Length - 1; i >= 0; i--)\n        {\n            var x = arr[i];\n            if (!predicate((state, x))) return state;\n            state = f(state)(x);\n        }\n        return state;\n    }\n\n    static Fold<A, S> Foldable<Arr>.FoldStep<A, S>(K<Arr, A> ta, S initialState)\n    {\n        var array = ta.As();\n        var count = array.Length;\n        if(count == 0) return Fold.Done<A, S>(initialState);\n        var index = 0;\n        return go(initialState);\n        \n        Fold<A, S> go(S state)\n        {\n            if (index == count)\n            {\n                return Fold.Done<A, S>(state);\n            }\n            else\n            {\n                return Fold.Loop(state, array[index++], go);\n            }\n        }\n    }\n\n    static Fold<A, S> Foldable<Arr>.FoldStepBack<A, S>(K<Arr, A> ta, S initialState)\n    {\n        var array = ta.As();\n        var count = array.Length;\n        if(count == 0) return Fold.Done<A, S>(initialState);\n        var index = count;\n        return go(initialState);\n        \n        Fold<A, S> go(S state)\n        {\n            if (index == 0)\n            {\n                return Fold.Done<A, S>(state);\n            }\n            else\n            {\n                return Fold.Loop(state, array[--index], go);\n            }\n        }\n    }\n\n    static Option<A> Foldable<Arr>.At<A>(K<Arr, A> ta, Index index)\n    {\n        var arr = ta.As();\n        return index.Value >= 0 && index.Value < arr.Length\n                   ? Some(arr[index])\n                   : Option<A>.None;\n    }\n\n    static Arr<A> Foldable<Arr>.ToArr<A>(K<Arr, A> ta) =>\n        ta.As();\n\n    static Lst<A> Foldable<Arr>.ToLst<A>(K<Arr, A> ta) =>\n        new(ta.As());\n\n    static Iterable<A> Foldable<Arr>.ToIterable<A>(K<Arr, A> ta) =>\n        ta.As().AsIterable();\n    \n    static Seq<A> Foldable<Arr>.ToSeq<A>(K<Arr, A> ta) =>\n        Seq.FromArray(ta.As().ToArray());\n    \n    static K<F, K<Arr, B>> Traversable<Arr>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Arr, A> ta)\n    {\n        return Foldable.fold(addItem, F.Pure(new SeqStrict<B>(new B[ta.As().Count], 0, 0, 0, 0)), ta)\n                       .Map(bs => new Arr<B>(bs.data.AsSpan().Slice(bs.start, bs.Count)).Kind());\n\n        Func<K<F, SeqStrict<B>>, K<F, SeqStrict<B>>> addItem(A value) =>\n            state =>\n                Applicative.lift((bs, b) => (SeqStrict<B>)bs.Add(b), state, f(value));                                            \n    }\n\n    static K<F, K<Arr, B>> Traversable<Arr>.TraverseM<F, A, B>(Func<A, K<F, B>> f, K<Arr, A> ta) \n    {\n        return Foldable.fold(addItem, F.Pure(new SeqStrict<B>(new B[ta.As().Count], 0, 0, 0, 0)), ta)\n                       .Map(bs => new Arr<B>(bs.data.AsSpan().Slice(bs.start, bs.Count)).Kind());\n\n        Func<K<F, SeqStrict<B>>, K<F, SeqStrict<B>>> addItem(A value) =>\n            state =>\n                state.Bind(\n                    bs => f(value).Bind(\n                        b => F.Pure((SeqStrict<B>)bs.Add(b)))); \n    }\n\n    static K<Seq, A> Natural<Arr, Seq>.Transform<A>(K<Arr, A> fa) => \n        toSeq(fa.As().ToSeq());\n\n    static K<Iterable, A> Natural<Arr, Iterable>.Transform<A>(K<Arr, A> fa) => \n        fa.As().AsIterable();\n\n    static K<Lst, A> Natural<Arr, Lst>.Transform<A>(K<Arr, A> fa) => \n        toList(fa.As());\n\n    static K<Set, A> Natural<Arr, Set>.Transform<A>(K<Arr, A> fa) => \n        toSet(fa.As());\n\n    static K<HashSet, A> Natural<Arr, HashSet>.Transform<A>(K<Arr, A> fa) => \n        toHashSet(fa.As());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/BiMap/BiMap.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Map type indexed both on the A and B for rapid lookup of either\n/// </summary>\n/// <typeparam name=\"A\">A</typeparam>\n/// <typeparam name=\"B\">B</typeparam>\n[Serializable]\npublic readonly struct BiMap<A, B> :\n    IEnumerable<(A Left, B Right)>,\n    IComparable<BiMap<A, B>>,\n    IEquatable<BiMap<A, B>>,\n    IComparable\n{\n    readonly Map<A, B> Left;\n    readonly Map<B, A> Right;\n\n    BiMap(Map<A, B> left, Map<B, A> right)\n    {\n        Left = left;\n        Right = right;\n    }\n\n    public BiMap(IEnumerable<(A Left, B Right)> items) : this(items, true)\n    { }\n\n    public BiMap(IEnumerable<(A Left, B Right)> items, bool tryAdd) : \n        this(new Map<A, B>(items), new Map<B, A>(items.Select(pair => (pair.Right, pair.Left)))) { }\n\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public BiMap<A, B> Add(A left, B right) =>\n        new (Left.Add(left, right), Right.Add(right, left));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public BiMap<A, B> TryAdd(A left, B right) =>\n        new (Left.TryAdd(left, right), Right.TryAdd(right, left));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> AddRange(IEnumerable<(A, B)> range) =>\n        new (Left.AddRange(range), Right.AddRange(range.Select(pair => (pair.Item2, pair.Item1))));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> AddRange(IEnumerable<Tuple<A, B>> range) =>\n        new (Left.AddRange(range), Right.AddRange(range.Select(pair => (pair.Item2, pair.Item1))));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> AddRange(IEnumerable<KeyValuePair<A, B>> range) =>\n        new (Left.AddRange(range), Right.AddRange(range.Select(pair => (pair.Value, pair.Key))));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> TryAddRange(IEnumerable<(A, B)> range) =>\n        new (Left.TryAddRange(range), Right.TryAddRange(range.Select(pair => (pair.Item2, pair.Item1))));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> TryAddRange(IEnumerable<Tuple<A, B>> range) =>\n        new (Left.TryAddRange(range), Right.TryAddRange(range.Select(pair => (pair.Item2, pair.Item1))));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> TryAddRange(IEnumerable<KeyValuePair<A, B>> range) =>\n        new (Left.TryAddRange(range), Right.TryAddRange(range.Select(pair => (pair.Value, pair.Key))));\n\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> AddOrUpdateRange(IEnumerable<Tuple<A, B>> range) =>\n        new (Left.AddOrUpdateRange(range), Right.AddOrUpdateRange(range.Select(pair => (pair.Item2, pair.Item1))));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> AddOrUpdateRange(IEnumerable<(A, B)> range) =>\n        new (Left.AddOrUpdateRange(range), Right.AddOrUpdateRange(range.Select(pair => (pair.Item2, pair.Item1))));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public BiMap<A, B> AddOrUpdateRange(IEnumerable<KeyValuePair<A, B>> range) =>\n        new (Left.AddOrUpdateRange(range), Right.AddOrUpdateRange(range.Select(pair => (pair.Value, pair.Key))));\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public BiMap<A, B> Remove(A left) =>\n        new (Left.Remove(left), Left.Find(left).Map(Right.Remove).IfNone(Right));\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public BiMap<A, B> Remove(B right) =>\n        new (Right.Find(right).Map(Left.Remove).IfNone(Left), Right.Remove(right));\n\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>value</returns>\n    [Pure]\n    public A this[B value] => Right[value];\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>value</returns>\n    [Pure]\n    public B this[A value] => Left[value];\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty => Left.IsEmpty;\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count => Left.Count;\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length => Left.Length;\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public BiMap<A, B> SetItem(A left, B right) =>\n        new (Left.SetItem(left, right), Right.SetItem(right, left));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public BiMap<A, B> TrySetItem(A left, B right) =>\n        new (Left.TrySetItem(left, right), Right.SetItem(right, left));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public BiMap<A, B> AddOrUpdate(A left, B right) =>\n        new (Left.AddOrUpdate(left, right), Right.AddOrUpdate(right, left));\n\n\n\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n\n    [Pure]\n    public bool ContainsKey(A value) => Left.ContainsKey(value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool ContainsKey(B value) => Right.ContainsKey(value);\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    public BiMap<A, B> Clear() => default;\n\n    /// <summary>\n    /// Enumerable of map lefts in-order\n    /// </summary>\n    [Pure]\n    public Iterable<A> LeftKeys => Left.Keys;\n\n    /// <summary>\n    /// Enumerable of map rights in-order\n    /// </summary>\n    [Pure]\n    public Iterable<B> RightKeys => Right.Keys;\n\n    /// <summary>\n    /// Enumerable of map lefts in-rights-order\n    /// </summary>\n    [Pure]\n    public Iterable<B> LeftValues => Left.Values;\n\n    /// <summary>\n    /// Enumerable of map rights in-lefts-order\n    /// </summary>\n    [Pure]\n    public Iterable<A> RightValues => Right.Values;\n\n    /// <summary>\n    /// Convert the map to an `IReadOnlyDictionary`\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public IReadOnlyDictionary<A, B> ToDictionaryLeft() => Left;\n\n    /// <summary>\n    /// Convert the map to an `IReadOnlyDictionary`\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public IReadOnlyDictionary<B, A> ToDictionaryRight() => Right;\n\n    /// <summary>\n    /// Enumerable of in-order tuples that make up the map\n    /// </summary>\n    /// <returns>Tuples</returns>\n    [Pure]\n    [Obsolete(\"Use Pairs instead\")]\n    public Iterable<(A Key, B Value)> Tuples =>\n        Left.Pairs;\n\n    /// <summary>\n    /// Enumerable of in-order tuples that make up the map\n    /// </summary>\n    /// <returns>Tuples</returns>\n    [Pure]\n    public Iterable<(A Key, B Value)> Pairs =>\n        Left.Pairs;\n\n    [Pure]\n    public Seq<(A Key, B Value)> ToSeq() =>\n        Prelude.toSeq(this);\n\n    [Pure]\n    public bool Equals(BiMap<A, B> y) =>\n        Left.Equals(y.Left);\n\n\n\n    [Pure]\n    public Option<B> Find(A value) => Left.Find(value);\n\n    [Pure]\n    public Option<A> Find(B value) => Right.Find(value);\n\n    [Pure]\n    public MapEnumerator<A, B> GetEnumerator() =>\n        Left.GetEnumerator();\n\n    [Pure]\n    IEnumerator<(A Left, B Right)> IEnumerable<(A Left, B Right)>.GetEnumerator() =>\n        Left.GetEnumerator();\n\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Left.GetEnumerator();\n\n    [Pure]\n    public int CompareTo(BiMap<A, B> rhs) =>\n        Left.CompareTo(rhs.Left);\n\n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj is BiMap<A, B> t ? CompareTo(t) : 1;\n        \n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is BiMap<A, B> bm && Equals(bm);\n\n    [Pure]\n    public static bool operator ==(BiMap<A, B> lhs, BiMap<A, B> rhs) =>\n        lhs.Left.Equals(rhs.Left);\n\n    [Pure]\n    public static bool operator !=(BiMap<A, B> lhs, BiMap<A, B> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public static bool operator <(BiMap<A, B> lhs, BiMap<A, B> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    [Pure]\n    public static bool operator <=(BiMap<A, B> lhs, BiMap<A, B> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    [Pure]\n    public static bool operator >(BiMap<A, B> lhs, BiMap<A, B> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    [Pure]\n    public static bool operator >=(BiMap<A, B> lhs, BiMap<A, B> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    [Pure]\n    public static BiMap<A, B> operator +(BiMap<A, B> lhs, BiMap<A, B> rhs) =>\n        new (lhs.Left + rhs.Left, lhs.Right + rhs.Right);\n\n    [Pure]\n    public static BiMap<A, B> operator -(BiMap<A, B> lhs, BiMap<A, B> rhs) =>\n        new (lhs.Left - rhs.Left, lhs.Right - rhs.Right);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Left.GetHashCode();\n\n\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    public static implicit operator BiMap<A, B>(SeqEmpty _) =>\n        default;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Eq.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Unsorted immutable hash-map\n/// </summary>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value</typeparam>\n[CollectionBuilder(typeof(HashMap), nameof(HashMap.createRange))]\npublic readonly struct HashMap<EqK, K, V> :\n    IReadOnlyDictionary<K, V>,\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<HashMap<EqK, K, V>>,\n    Monoid<HashMap<EqK, K, V>>,\n    IEqualityOperators<HashMap<EqK, K, V>, HashMap<EqK, K, V>, bool>,\n    IAdditionOperators<HashMap<EqK, K, V>, HashMap<EqK, K, V>, HashMap<EqK, K, V>>,\n    ISubtractionOperators<HashMap<EqK, K, V>, HashMap<EqK, K, V>, HashMap<EqK, K, V>>,\n    IAdditiveIdentity<HashMap<EqK, K, V>, HashMap<EqK, K, V>>,\n    K<HashMapEq<EqK, K>, V>\n    where EqK : Eq<K>\n{\n    [Pure]\n    public static HashMap<EqK, K, V> Empty { get; } = new(TrieMap<EqK, K, V>.Empty);\n\n    readonly TrieMap<EqK, K, V> value;\n\n    internal TrieMap<EqK, K, V> Value => \n        value ?? TrieMap<EqK, K, V>.Empty;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal HashMap(TrieMap<EqK, K, V> value) =>\n        this.value = value;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap(IEnumerable<(K Key, V Value)> items) : this(items, true)\n    { }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap(IEnumerable<(K Key, V Value)> items, bool tryAdd) =>\n        value = new TrieMap<EqK, K, V>(items, tryAdd);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static HashMap<EqK, K, V> Wrap(TrieMap<EqK, K, V> value) =>\n        new (value);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static HashMap<EqK, K, U> Wrap<U>(TrieMap<EqK, K, U> value) =>\n        new (value);\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public V this[K key]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value[key];\n    }\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Filter(Func<V, bool> pred) =>\n        Wrap(Value.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Filter(Func<K, V, bool> pred) =>\n        Wrap(Value.Filter(pred));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, U> Map<U>(Func<V, U> mapper) =>\n        Wrap(Value.Map(mapper));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, U> Map<U>(Func<K, V, U> mapper) =>\n        Wrap(Value.Map(mapper));\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Add(K key, V value) =>\n        Wrap(Value.Add(key, value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TryAdd(K key, V value) =>\n        Wrap(Value.TryAdd(key, value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddOrUpdate(K key, V value) =>\n        Wrap(Value.AddOrUpdate(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddOrUpdate(K key, Func<V, V> Some, Func<V> None) =>\n        Wrap(Value.AddOrUpdate(key, Some, None));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddOrUpdate(K key, Func<V, V> Some, V None) =>\n        Wrap(Value.AddOrUpdate(key, Some, None));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddRange(IEnumerable<(K, V)> range) =>\n        Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TryAddRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TryAddRange(IEnumerable<(K, V)> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TryAddRange(IEnumerable<KeyValuePair<K, V>> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddOrUpdateRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddOrUpdateRange(IEnumerable<(K, V)> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Remove(K key) =>\n        Wrap(Value.Remove(key));\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<V> Find(K key) =>\n        Value.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<V> FindSeq(K key) =>\n        Value.FindAll(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) =>\n        Value.Find(key,Some,None);\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (HashMap<EqK, K, V> Map, V Value) FindOrAdd(K key, Func<V> None) =>\n        Value.FindOrAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (HashMap<EqK, K, V>, V Value) FindOrAdd(K key, V value) =>\n        Value.FindOrAdd(key, value).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (HashMap<EqK, K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Func<Option<V>> None) =>\n        Value.FindOrMaybeAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (HashMap<EqK, K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Option<V> None) =>\n        Value.FindOrMaybeAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> SetItem(K key, V value) =>\n        Wrap(Value.SetItem(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> SetItem(K key, Func<V, V> Some) =>\n        Wrap(Value.SetItem(key, Some));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TrySetItem(K key, V value) =>\n        Wrap(Value.TrySetItem(key, value));\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TrySetItem(K key, Func<V, V> Some) =>\n        Wrap(Value.SetItem(key, Some));\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ContainsKey(K key) =>\n        Value.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(K key, V value) =>\n        Value.Contains(key, value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains<EqV>(K key, V value) where EqV : Eq<V> =>\n        Value.Contains<EqV>(key, value);\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Clear() =>\n        Wrap(Value.Clear());\n\n    /// <summary>\n    /// Atomically adds a range of items to the map\n    /// </summary>\n    /// <param name=\"pairs\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> AddRange(IEnumerable<KeyValuePair<K, V>> pairs) =>\n        Wrap(Value.AddRange(pairs));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> SetItems(IEnumerable<KeyValuePair<K, V>> items) =>\n        Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> SetItems(IEnumerable<Tuple<K, V>> items) =>\n        Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> SetItems(IEnumerable<(K, V)> items) =>\n        Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TrySetItems(IEnumerable<KeyValuePair<K, V>> items) =>\n        Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TrySetItems(IEnumerable<Tuple<K, V>> items) =>\n        Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TrySetItems(IEnumerable<(K, V)> items) =>\n        Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> TrySetItems(IEnumerable<K> keys, Func<V, V> Some) =>\n        Wrap(Value.TrySetItems(keys, Some));\n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New map with the items removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> RemoveRange(IEnumerable<K> keys) =>\n        Wrap(Value.RemoveRange(keys));\n\n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(KeyValuePair<K, V> pair) =>\n        Value.Contains(pair.Key, pair.Value);\n\n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains<EqV>(KeyValuePair<K, V> pair) where EqV : Eq<V> =>\n        Value.Contains<EqV>(pair.Key, pair.Value);\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.Keys;\n    }\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.Values;\n    }\n\n    /// <summary>\n    /// Map the map the a dictionary\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(\n        Func<(K Key, V Value), KR> keySelector, \n        Func<(K Key, V Value), VR> valueSelector)\n        where KR : notnull =>\n        Value.AsIterable().ToDictionary(keySelector, valueSelector);\n\n    #region IEnumerable interface\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Value.GetEnumerator();\n\n    [Pure]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        toSeq(Value.AsIterable());\n\n    /// <summary>\n    /// Allocation free conversion to a TrackingHashMap\n    /// </summary>\n    [Pure]\n    public HashMap<EqK, K, V> ToTrackingHashMap() =>\n        new (value);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    public Iterable<(K Key, V Value)> AsEnumerable() =>\n        Value.AsIterable();\n\n    #endregion\n        \n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator HashMap<EqK, K, V>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(HashMap<EqK, K, V> lhs, HashMap<EqK, K, V> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(HashMap<EqK, K, V> lhs, HashMap<EqK, K, V> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> operator +(HashMap<EqK, K, V> lhs, HashMap<EqK, K, V> rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Combine(HashMap<EqK, K, V> rhs) =>\n        Wrap(Value.Append(rhs.Value));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> operator -(HashMap<EqK, K, V> lhs, HashMap<EqK, K, V> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Subtract(HashMap<EqK, K, V> rhs) =>\n        Wrap(Value.Subtract(rhs.Value));\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSubsetOf(IEnumerable<K> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSupersetOf(IEnumerable<K> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(IEnumerable<K> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(HashMap<EqK, K, V> other) =>\n        Value.IsSubsetOf(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSupersetOf(IEnumerable<K> rhs) =>\n        Value.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Overlaps(IEnumerable<K> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Intersect(IEnumerable<K> rhs) =>\n        Wrap(Value.Intersect(rhs));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Intersect(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.Intersect(rhs));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Intersect(IEnumerable<(K Key, V Value)> rhs, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.Intersect(rhs, Merge));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Except(IEnumerable<K> rhs) =>\n        Wrap(Value.Except(rhs));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Except(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.Except(rhs));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> SymmetricExcept(HashMap<EqK, K, V> rhs) =>\n        Wrap(Value.SymmetricExcept(rhs.Value));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> SymmetricExcept(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.SymmetricExcept(rhs));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Union(IEnumerable<(K, V)> rhs) =>\n        this.TryAddRange(rhs);\n        \n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Union(IEnumerable<(K, V)> other, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.Union(other, static (_, v) => v, static (_, v) => v, Merge));\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the right-hand side, but not the left-hand-side.\n    /// This allows the `V2` value-type to be mapped to the target `V` value-type. \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Union<W>(\n        IEnumerable<(K, W)> other, \n        WhenMissing<K, W, V> MapRight, \n        WhenMatched<K, V, W, V> Merge) =>\n        Wrap(Value.Union(other, static (_, v) => v, MapRight, Merge));\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the left-hand side, but not the right-hand-side.\n    /// This allows the `V` value-type to be mapped to the target `V2` value-type. \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, W> Union<W>(\n        IEnumerable<(K, W)> other, \n        WhenMissing<K, V, W> MapLeft, \n        WhenMatched<K, V, W, W> Merge) =>\n        Wrap(Value.Union(other, MapLeft, static (_, v) => v, Merge));\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing MapLeft` function is called when there is a key in the left-hand side, but not the\n    /// right-hand-side.   This allows the `V` value-type to be mapped to the target `R` value-type. \n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing MapRight` function is called when there is a key in the right-hand side, but not the\n    /// left-hand-side.   This allows the `V2` value-type to be mapped to the target `R` value-type. \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, R> Union<W, R>(\n        IEnumerable<(K, W)> other, \n        WhenMissing<K, V, R> MapLeft, \n        WhenMissing<K, W, R> MapRight, \n        WhenMatched<K, V, W, R> Merge) =>\n        Wrap(Value.Union(other, MapLeft, MapRight, Merge));            \n\n    /// <summary>\n    /// Equality of keys\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is HashMap<EqK, K, V> hm && Equals(hm);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(HashMap<EqK, K, V> other) =>\n        Value.Equals<EqDefault<V>>(other.Value);\n\n    /// <summary>\n    /// Equality of keys and values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals<EqV>(HashMap<EqK, K, V> other) where EqV : Eq<V> =>\n        Value.Equals<EqV>(other.Value);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool EqualKeys(HashMap<EqK, K, V> other) =>\n        Value.Equals<EqTrue<V>>(other.Value);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Do(Action<V> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, U> Select<U>(Func<V, U> mapper) =>\n        Map(mapper);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, U> Select<U>(Func<K, V, U> mapper) =>\n        Map(mapper);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Where(Func<V, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<EqK, K, V> Where(Func<K, V, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<K, V, bool> pred)\n    {\n        foreach (var item in AsEnumerable())\n        {\n            if (!pred(item.Key, item.Value)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        AsEnumerable().Map(kv => (kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<V, bool> pred) =>\n        Values.ForAll(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<K, V, bool> pred)\n    {\n        foreach (var item in AsEnumerable())\n        {\n            if (pred(item.Key, item.Value)) return true;\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<(K Key, V Value), bool> pred) =>\n        AsEnumerable().Map(kv => (kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<V, bool> pred) =>\n        Values.Exists(pred);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<K, V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Key, item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<Tuple<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new Tuple<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<(K Key, V Value)> action)\n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<KeyValuePair<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new KeyValuePair<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        AsEnumerable().Fold(state, (s, x) => folder(s, x.Key, x.Value));\n    \n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() =>\n        AsEnumerable().Map(p => new KeyValuePair<K, V>(p.Key, p.Value)).GetEnumerator();\n    \n    [Pure]\n    IEnumerable<K> IReadOnlyDictionary<K, V>.Keys => Keys;\n    \n    [Pure]\n    IEnumerable<V> IReadOnlyDictionary<K, V>.Values => Values;\n\n    /// <summary>\n    /// Get a IReadOnlyDictionary for this map.  No mapping is required, so this is very fast.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IReadOnlyDictionary<K, V> ToReadOnlyDictionary() =>\n        this;\n\n    [Pure]\n    public bool TryGetValue(K key, out V value)\n    {\n        var v = Find(key);\n        if (v.IsSome)\n        {\n            value = (V)v;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(ValueTuple<(K, V)> items) =>\n        new (new[] { items.Item1 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15, items.Item16 });\n\n    public static HashMap<EqK, K, V> AdditiveIdentity => \n        Empty;    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Extensions.Eq.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class HashMapExtensions\n{\n    public static HashMap<EqKey, Key, V> As<EqKey, Key, V>(this K<HashMapEq<EqKey, Key>, V> ma)\n        where EqKey : Eq<Key> =>\n        (HashMap<EqKey, Key, V>)ma;\n    \n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> ToHashMap<EqK, K, V>(this IEnumerable<(K, V)> items)\n        where EqK : Eq<K> =>\n        new(items);\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, (K1, K2), V> ToHashMap<EqK, K1, K2, V>(this IEnumerable<(K1, K2, V)> items)\n        where EqK : Eq<(K1, K2)> =>\n        new (items.Select(x => ((x.Item1, x.Item2), x.Item3)));\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, (K1, K2, K3), V> ToHashMap<EqK, K1, K2, K3, V>(this IEnumerable<(K1, K2, K3, V)> items)\n        where EqK : Eq<(K1, K2, K3)> =>\n        new (items.Select(x => ((x.Item1, x.Item2, x.Item3), x.Item4)));\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, (K1, K2, K3, K4), V> ToHashMap<EqK, K1, K2, K3, K4, V>(this IEnumerable<(K1, K2, K3, K4, V)> items)\n        where EqK : Eq<(K1, K2, K3, K4)> =>\n        new (items.Select(x => ((x.Item1, x.Item2, x.Item3, x.Item4), x.Item5)));\n        \n    /// <summary>\n    /// Convert to a queryable \n    /// </summary>\n    [Pure]\n    public static IQueryable<(K Key, V Value)> AsQueryable<EqK, K, V>(this HashMap<EqK, K, V> source)\n        where EqK : Eq<K> =>\n        // NOTE TO FUTURE ME: Don't delete this thinking it's not needed!\n        source.Value.AsQueryable();\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class HashMapExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashMap<Key, B> Map<Key, A, B>(this Func<A, B> f, K<HashMap<Key>, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashMap<Key, B> Map<Key, A, B>(this Func<A, B> f, HashMap<Key, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashMap<EqKey, Key, B> Map<EqKey, Key, A, B>(this Func<A, B> f, K<HashMapEq<EqKey, Key>, A> ma)\n        where EqKey : Eq<Key> =>\n        ma.As().Map(f);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashMap<EqKey, Key, B> Map<EqKey, Key, A, B>(this Func<A, B> f, HashMap<EqKey, Key, A> ma)\n        where EqKey : Eq<Key> =>\n        ma.Map(f);\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Extensions.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class HashMapExtensions\n{\n    public static HashMap<Key, V> As<Key, V>(this K<HashMap<Key>, V> ma) =>\n        (HashMap<Key, V>)ma;\n    \n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> ToHashMap<K, V>(this IEnumerable<(K, V)> items) =>\n        new(items);\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<(K1, K2), V> ToHashMap<K1, K2, V>(this IEnumerable<(K1, K2, V)> items) =>\n        new (items.Select(x => ((x.Item1, x.Item2), x.Item3)));\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<(K1, K2, K3), V> ToHashMap<K1, K2, K3, V>(this IEnumerable<(K1, K2, K3, V)> items) =>\n        new (items.Select(x => ((x.Item1, x.Item2, x.Item3), x.Item4)));\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<(K1, K2, K3, K4), V> ToHashMap<K1, K2, K3, K4, V>(this IEnumerable<(K1, K2, K3, K4, V)> items) =>\n        new (items.Select(x => ((x.Item1, x.Item2, x.Item3, x.Item4), x.Item5)));\n        \n    /// <summary>\n    /// Convert to a queryable \n    /// </summary>\n    [Pure]\n    public static IQueryable<(K Key, V Value)> AsQueryable<K, V>(this HashMap<K, V> source) =>\n        // NOTE TO FUTURE ME: Don't delete this thinking it's not needed!\n        source.Value.AsQueryable();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Module.Eq.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable hash-map module\n/// </summary>\npublic partial class HashMap\n{\n    /// <summary>\n    /// Clears all items from the map\n    /// </summary>\n    /// <param name=\"map\">Map to clear</param>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> clear<EqK, K, V>(HashMap<EqK, K, V> map) where EqK : Eq<K> =>\n        HashMap<EqK, K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new empty Map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> empty<EqK, K, V>() where EqK : Eq<K> =>\n        HashMap<EqK, K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new empty HashMap\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> create<EqK, K, V>() where EqK : Eq<K> =>\n        HashMap<EqK, K, V>.Empty;\n\n    /// <summary>\n    /// Create a singleton collection\n    /// </summary>\n    /// <param name=\"value\">Single value</param>\n    /// <returns>Collection with a single item in it</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> singleton<EqK, K, V>(K key, V value) where EqK : Eq<K> =>\n        [(key, value)];\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> create<EqK, K, V>(Tuple<K, V> head, params Tuple<K, V>[] tail) \n        where EqK : Eq<K> =>\n        createRange<EqK, K, V>(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> create<EqK, K, V>((K, V) head, params (K, V)[] tail)\n        where EqK : Eq<K> =>\n        createRange<EqK, K, V>(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> create<EqK, K, V>(KeyValuePair<K, V> head, params KeyValuePair<K, V>[] tail)\n        where EqK : Eq<K> =>\n        createRange<EqK, K, V>(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> createRange<EqK, K, V>(IEnumerable<Tuple<K, V>> keyValues)\n        where EqK : Eq<K> =>\n        createRange<EqK, K, V>(keyValues.Select(static kv => (kv.Item1, kv.Item2)));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> createRange<EqK, K, V>(IEnumerable<(K, V)> keyValues)\n        where EqK : Eq<K> =>\n        new (new TrieMap<EqK, K, V>(keyValues));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> createRange<EqK, K, V>(ReadOnlySpan<(K, V)> keyValues)\n        where EqK : Eq<K> =>\n        keyValues.IsEmpty\n            ? HashMap<EqK, K, V>.Empty\n            : new (new TrieMap<EqK, K, V>(keyValues));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static HashMap<EqK, K, V> createRange<EqK, K, V>(IEnumerable<KeyValuePair<K, V>> keyValues)\n        where EqK : Eq<K> =>\n        createRange<EqK, K, V>(keyValues.Select(static kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> add<EqK, K, V>(HashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.Add(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> tryAdd<EqK, K, V>(HashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.TryAdd(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addOrUpdate<EqK, K, V>(HashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.AddOrUpdate(key, value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addOrUpdate<EqK, K, V>(HashMap<EqK, K, V> map, K key, Func<V, V> Some, Func<V> None) where EqK : Eq<K> =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addOrUpdate<EqK, K, V>(HashMap<EqK, K, V> map, K key, Func<V, V> Some, V None) where EqK : Eq<K> =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> keyValues) where EqK : Eq<K> =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<(K, V)> keyValues) where EqK : Eq<K> =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) where EqK : Eq<K> =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> tryAddRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> keyValues) where EqK : Eq<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> tryAddRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<(K, V)> keyValues) where EqK : Eq<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> tryAddRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) where EqK : Eq<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addOrUpdateRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> range) where EqK : Eq<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addOrUpdateRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<(K, V)> range) where EqK : Eq<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> addOrUpdateRange<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> range) where EqK : Eq<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> remove<EqK, K, V>(HashMap<EqK, K, V> map, K key) where EqK : Eq<K> =>\n        map.Remove(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool containsKey<EqK, K, V>(HashMap<EqK, K, V> map, K key) where EqK : Eq<K> =>\n        map.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool contains<EqK, K, V>(HashMap<EqK, K, V> map, KeyValuePair<K, V> kv) where EqK : Eq<K> =>\n        map.Contains(kv.Key, kv.Value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool contains<EqK, K, V>(HashMap<EqK, K, V> map, Tuple<K, V> kv) where EqK : Eq<K> =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool contains<EqK, K, V>(HashMap<EqK, K, V> map, (K, V) kv) where EqK : Eq<K> =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> setItem<EqK, K, V>(HashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.SetItem(key, value);\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> trySetItem<EqK, K, V>(HashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.TrySetItem(key, value);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map (Some), and then putting \n    /// it back. Silently fails if the value doesn't exist.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> trySetItem<EqK, K, V>(HashMap<EqK, K, V> map, K key, Func<V, V> Some) where EqK : Eq<K> =>\n        map.TrySetItem(key, Some);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> setItems<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> setItems<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<(K, V)> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> setItems<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> trySetItems<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> trySetItems<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<(K, V)> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> trySetItems<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> items) where EqK : Eq<K> =>\n        map.TrySetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> trySetItems<EqK, K, V>(HashMap<EqK, K, V> map, IEnumerable<K> keys, Func<V, V> Some) where EqK : Eq<K> =>\n        map.TrySetItems(keys, Some);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<V> find<EqK, K, V>(HashMap<EqK, K, V> map, K key) where EqK : Eq<K> =>\n        map.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IEnumerable<V> findSeq<EqK, K, V>(HashMap<EqK, K, V> map, K key) where EqK : Eq<K> =>\n        map.FindSeq(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static R find<EqK, K, V, R>(HashMap<EqK, K, V> map, K key, Func<V, R> Some, Func<R> None) where EqK : Eq<K> =>\n        map.Find(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> setItem<EqK, K, V>(HashMap<EqK, K, V> map, K key, Func<V, V> mapper) where EqK : Eq<K> =>\n        map.SetItem(key, mapper);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit iter<EqK, K, V>(HashMap<EqK, K, V> map, Action<V> action) where EqK : Eq<K> =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit iter<EqK, K, V>(HashMap<EqK, K, V> map, Action<K, V> action) where EqK : Eq<K> =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool forall<EqK, K, V>(HashMap<EqK, K, V> map, Func<V, bool> pred) where EqK : Eq<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool forall<EqK, K, V>(HashMap<EqK, K, V> map, Func<K, V, bool> pred) where EqK : Eq<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool forall<EqK, K, V>(HashMap<EqK, K, V> map, Func<(K Key, V Value), bool> pred) where EqK : Eq<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, U> map<EqK, K, T, U>(HashMap<EqK, K, T> map, Func<T, U> f) where EqK : Eq<K> =>\n        map.Select(f);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, U> map<EqK, K, T, U>(HashMap<EqK, K, T> map, Func<K, T, U> f) where EqK : Eq<K> =>\n        map.Select(f);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> filter<EqK, K, V>(HashMap<EqK, K, V> map, Func<V, bool> predicate) where EqK : Eq<K> =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<EqK, K, V> filter<EqK, K, V>(HashMap<EqK, K, V> map, Func<K, V, bool> predicate) where EqK : Eq<K> =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int length<EqK, K, T>(HashMap<EqK, K, T> map) where EqK : Eq<K> =>\n        map.Count;\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static S fold<EqK, S, K, V>(HashMap<EqK, K, V> map, S state, Func<S, K, V, S> folder) where EqK : Eq<K> =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool exists<EqK, K, V>(HashMap<EqK, K, V> map, Func<K, V, bool> pred) where EqK : Eq<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool exists<EqK, K, V>(HashMap<EqK, K, V> map, Func<(K Key, V Value), bool> pred) where EqK : Eq<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool exists<EqK, K, V>(HashMap<EqK, K, V> map, Func<V, bool> pred) where EqK : Eq<K> =>\n        map.Exists(pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Module.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable hash-map module\n/// </summary>\npublic static partial class HashMap\n{\n    /// <summary>\n    /// Clears all items from the map\n    /// </summary>\n    /// <param name=\"map\">Map to clear</param>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> clear<K, V>(HashMap<K, V> map) =>\n        HashMap<K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new empty HashMap \n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> empty<K, V>() =>\n        HashMap<K, V>.Empty;\n\n    /// <summary>\n    /// Create a singleton collection\n    /// </summary>\n    /// <param name=\"value\">Single value</param>\n    /// <returns>Collection with a single item in it</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> singleton<K, V>((K, V) value) =>\n        [value];\n\n    /// <summary>\n    /// Create a singleton collection\n    /// </summary>\n    /// <param name=\"value\">Single value</param>\n    /// <returns>Collection with a single item in it</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> singleton<K, V>(K key, V value) =>\n        [(key, value)];\n        \n    /// <summary>\n    /// Creates a new empty HashMap \n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> create<K, V>() =>\n        HashMap<K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> create<K, V>(Tuple<K, V> head, params Tuple<K, V>[] tail) =>\n        createRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> create<K, V>((K, V) head, params (K, V)[] tail) =>\n        createRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static HashMap<K, V> create<K, V>(KeyValuePair<K, V> head, params KeyValuePair<K, V>[] tail) =>\n        createRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> createRange<K, V>(IEnumerable<Tuple<K, V>> keyValues) =>\n        createRange(keyValues.Select(static kv => (kv.Item1, kv.Item2)));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> createRange<K, V>(IEnumerable<(K, V)> keyValues) =>\n        new (new TrieMap<EqDefault<K>, K, V>(keyValues));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> createRange<K, V>(ReadOnlySpan<(K, V)> keyValues) =>\n        keyValues.IsEmpty\n            ? HashMap<K, V>.Empty\n            : new(new TrieMap<EqDefault<K>, K, V>(keyValues));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> createRange<K, V>(IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        createRange(keyValues.Select(static kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> add<K, V>(HashMap<K, V> map, K key, V value) =>\n        map.Add(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> tryAdd<K, V>(HashMap<K, V> map, K key, V value) =>\n        map.TryAdd(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addOrUpdate<K, V>(HashMap<K, V> map, K key, V value) =>\n        map.AddOrUpdate(key, value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addOrUpdate<K, V>(HashMap<K, V> map, K key, Func<V, V> Some, Func<V> None) =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addOrUpdate<K, V>(HashMap<K, V> map, K key, Func<V, V> Some, V None) =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addRange<K, V>(HashMap<K, V> map, IEnumerable<Tuple<K, V>> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addRange<K, V>(HashMap<K, V> map, IEnumerable<(K, V)> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addRange<K, V>(HashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> tryAddRange<K, V>(HashMap<K, V> map, IEnumerable<Tuple<K, V>> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> tryAddRange<K, V>(HashMap<K, V> map, IEnumerable<(K, V)> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> tryAddRange<K, V>(HashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addOrUpdateRange<K, V>(HashMap<K, V> map, IEnumerable<Tuple<K, V>> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addOrUpdateRange<K, V>(HashMap<K, V> map, IEnumerable<(K, V)> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> addOrUpdateRange<K, V>(HashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> remove<K, V>(HashMap<K, V> map, K key) =>\n        map.Remove(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool containsKey<K, V>(HashMap<K, V> map, K key) =>\n        map.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool contains<K, V>(HashMap<K, V> map, KeyValuePair<K, V> kv) =>\n        map.Contains(kv.Key, kv.Value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool contains<K, V>(HashMap<K, V> map, Tuple<K, V> kv) =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool contains<K, V>(HashMap<K, V> map, (K, V) kv) =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> setItem<K, V>(HashMap<K, V> map, K key, V value) =>\n        map.SetItem(key, value);\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> trySetItem<K, V>(HashMap<K, V> map, K key, V value) =>\n        map.TrySetItem(key, value);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map (Some), and then putting \n    /// it back. Silently fails if the value doesn't exist.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> trySetItem<K, V>(HashMap<K, V> map, K key, Func<V, V> Some) =>\n        map.TrySetItem(key, Some);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> setItems<K, V>(HashMap<K, V> map, IEnumerable<Tuple<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> setItems<K, V>(HashMap<K, V> map, IEnumerable<(K, V)> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> setItems<K, V>(HashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> trySetItems<K, V>(HashMap<K, V> map, IEnumerable<Tuple<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> trySetItems<K, V>(HashMap<K, V> map, IEnumerable<(K, V)> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> trySetItems<K, V>(HashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> items) =>\n        map.TrySetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> trySetItems<K, V>(HashMap<K, V> map, IEnumerable<K> keys, Func<V, V> Some) =>\n        map.TrySetItems(keys, Some);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<V> find<K, V>(HashMap<K, V> map, K key) =>\n        map.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static R find<K, V, R>(HashMap<K, V> map, K key, Func<V, R> Some, Func<R> None) =>\n        map.Find(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> setItem<K, V>(HashMap<K, V> map, K key, Func<V, V> mapper) =>\n        map.SetItem(key, mapper);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit iter<K, V>(HashMap<K, V> map, Action<V> action) =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit iter<K, V>(HashMap<K, V> map, Action<K, V> action) =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool forall<K, V>(HashMap<K, V> map, Func<V, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool forall<K, V>(HashMap<K, V> map, Func<K, V, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool forall<K, V>(HashMap<K, V> map, Func<(K Key, V Value), bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, U> map<K, T, U>(HashMap<K, T> map, Func<T, U> f) =>\n        map.Select(f);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, U> map<K, T, U>(HashMap<K, T> map, Func<K, T, U> f) =>\n        map.Select(f);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> filter<K, V>(HashMap<K, V> map, Func<V, bool> predicate) =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> filter<K, V>(HashMap<K, V> map, Func<K, V, bool> predicate) =>\n        map.Filter(predicate);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashMap<Key, B> map<Key, A, B>(Func<A, B> f, K<HashMap<Key>, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashMap<EqKey, Key, B> map<EqKey, Key, A, B>(this Func<A, B> f, K<HashMapEq<EqKey, Key>, A> ma)\n        where EqKey : Eq<Key> =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Trait.Implementations.Eq.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class HashMapEq<EqKey, Key> : \n    Foldable<HashMapEq<EqKey, Key>>, \n    MonoidK<HashMapEq<EqKey, Key>>,\n    Functor<HashMapEq<EqKey, Key>>\n    where EqKey : Eq<Key>\n{\n    static int Foldable<HashMapEq<EqKey, Key>>.Count<A>(K<HashMapEq<EqKey, Key>, A> ta) =>\n        ta.As().Count;\n\n    static bool Foldable<HashMapEq<EqKey, Key>>.IsEmpty<A>(K<HashMapEq<EqKey, Key>, A> ta) =>\n        ta.As().IsEmpty;\n\n    static K<HashMapEq<EqKey, Key>, A> SemigroupK<HashMapEq<EqKey, Key>>.Combine<A>(K<HashMapEq<EqKey, Key>, A> lhs, K<HashMapEq<EqKey, Key>, A> rhs) =>\n        lhs.As() + rhs.As();\n\n    static K<HashMapEq<EqKey, Key>, A> MonoidK<HashMapEq<EqKey, Key>>.Empty<A>() =>\n        HashMap<EqKey, Key, A>.Empty;\n\n    public static K<HashMapEq<EqKey, Key>, B> Map<A, B>(Func<A, B> f, K<HashMapEq<EqKey, Key>, A> ma) =>\n        new HashMap<EqKey, Key, B>(ma.As().Value.Select(kv => (kv.Key, f(kv.Value))));\n    \n    static Fold<A, S> Foldable<HashMapEq<EqKey, Key>>.FoldStep<A, S>(K<HashMapEq<EqKey, Key>, A> ta, S initialState)\n    {\n        var iter = ta.As().Values.GetIterator();\n        return go(initialState);\n        Fold<A, S> go(S state)\n        {\n            if (iter.IsEmpty)\n            {\n                return Fold.Done<A, S>(state);\n            }\n            else\n            {\n                iter = iter.Tail.Split();\n                return Fold.Loop(state, iter.Head, go);\n            }\n        }\n    }\n\n    static Fold<A, S> Foldable<HashMapEq<EqKey, Key>>.FoldStepBack<A, S>(K<HashMapEq<EqKey, Key>, A> ta, S initialState) =>\n        // Order is undefined in a HashMap, so reversing the order makes no sense,\n        // so let's take the most efficient option:\n        ta.FoldStep(initialState);\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.Trait.Implementations.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class HashMap<Key> : \n    Foldable<HashMap<Key>>, \n    Functor<HashMap<Key>>, \n    MonoidK<HashMap<Key>>\n{\n    static K<HashMap<Key>, B> Functor<HashMap<Key>>.Map<A, B>(Func<A, B> f, K<HashMap<Key>, A> ma)\n    {\n        return new HashMap<Key, B>(Go());\n        IEnumerable<(Key, B)> Go()\n        {\n            foreach (var x in ma.As())\n            {\n                yield return (x.Key, f(x.Value));\n            }\n        }\n    }\n    \n    static int Foldable<HashMap<Key>>.Count<A>(K<HashMap<Key>, A> ta) =>\n        ta.As().Count;\n\n    static bool Foldable<HashMap<Key>>.IsEmpty<A>(K<HashMap<Key>, A> ta) =>\n        ta.As().IsEmpty;\n\n    static K<HashMap<Key>, A> SemigroupK<HashMap<Key>>.Combine<A>(K<HashMap<Key>, A> lhs, K<HashMap<Key>, A> rhs) =>\n        lhs.As() + rhs.As();\n\n    static K<HashMap<Key>, A> MonoidK<HashMap<Key>>.Empty<A>() =>\n        HashMap<Key, A>.Empty;\n    \n    static Fold<A, S> Foldable<HashMap<Key>>.FoldStep<A, S>(K<HashMap<Key>, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().Values.GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }      \n        \n    static Fold<A, S> Foldable<HashMap<Key>>.FoldStepBack<A, S>(K<HashMap<Key>, A> ta, S initialState) =>\n        // Order is undefined in a HashMap, so reversing the order makes no sense,\n        // so let's take the most efficient option:\n        ta.FoldStep(initialState);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashMap/HashMap.cs",
    "content": "﻿using LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing System.Linq;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\n#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Unsorted immutable hash-map\n/// </summary>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value</typeparam>\n[CollectionBuilder(typeof(HashMap), nameof(HashMap.createRange))]\npublic readonly struct HashMap<K, V> :\n    IReadOnlyDictionary<K, V>,\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<HashMap<K, V>>,\n    IEqualityOperators<HashMap<K, V>, HashMap<K, V>, bool>,\n    IAdditionOperators<HashMap<K, V>, HashMap<K, V>, HashMap<K, V>>,\n    ISubtractionOperators<HashMap<K, V>, HashMap<K, V>, HashMap<K, V>>,\n    IAdditiveIdentity<HashMap<K, V>, HashMap<K, V>>,\n    Monoid<HashMap<K, V>>,\n    K<HashMap<K>, V>\n{\n    [Pure] \n    public static HashMap<K, V> Empty { get; } = new(TrieMap<EqDefault<K>, K, V>.Empty);\n\n    readonly TrieMap<EqDefault<K>, K, V> value;\n\n    internal TrieMap<EqDefault<K>, K, V> Value => \n        value ?? TrieMap<EqDefault<K>, K, V>.Empty;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal HashMap(TrieMap<EqDefault<K>, K, V> value) =>\n        this.value = value;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap(IEnumerable<(K Key, V Value)> items) \n        : this(items, true)\n    { }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap(IEnumerable<(K Key, V Value)> items, bool tryAdd) =>\n        value = new TrieMap<EqDefault<K>, K, V>(items, tryAdd);\n\n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<HashMap<K, V>, V> item(K key) => Lens<HashMap<K, V>, V>.New(\n        Get: la => la[key],\n        Set: a => la => la.AddOrUpdate(key, a)\n    );\n\n    /// <summary>\n    /// Item or none at index lens\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<HashMap<K, V>, Option<V>> itemOrNone(K key) => Lens<HashMap<K, V>, Option<V>>.New(\n        Get: la => la.Find(key),\n        Set: a => la => a.Match(Some: x => la.AddOrUpdate(key, x), None: () => la.Remove(key))\n    );\n\n    /// <summary>\n    /// Lens map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<HashMap<K, V>, HashMap<K, B>> map<B>(Lens<V, B> lens) => Lens<HashMap<K, V>, HashMap<K, B>>.New(\n        Get: la => la.Map(lens.Get),\n        Set: lb => la =>\n                   {\n                       foreach (var item in lb)\n                       {\n                           la = la.AddOrUpdate(item.Key, lens.Set(item.Value, la[item.Key]));\n                       }\n                       return la;\n                   });\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static HashMap<K, V> Wrap(TrieMap<EqDefault<K>, K, V> value) =>\n        new (value);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static HashMap<K, U> Wrap<U>(TrieMap<EqDefault<K>, K, U> value) =>\n        new (value);\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public V this[K key]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value[key];\n    }\n    \n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Filter(Func<V, bool> pred) =>\n        Wrap(Value.Filter(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Filter(Func<K, V, bool> pred) =>\n        Wrap(Value.Filter(pred));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, U> Map<U>(Func<V, U> mapper) =>\n        Wrap(Value.Map(mapper));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, U> Map<U>(Func<K, V, U> mapper) =>\n        Wrap(Value.Map(mapper));\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"valueToAdd\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Add(K key, V valueToAdd) =>\n        Wrap(Value.Add(key, valueToAdd));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"valueToAdd\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TryAdd(K key, V valueToAdd) =>\n        Wrap(Value.TryAdd(key, valueToAdd));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddOrUpdate(K key, V value) =>\n        Wrap(Value.AddOrUpdate(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddOrUpdate(K key, Func<V, V> Some, Func<V> None) =>\n        Wrap(Value.AddOrUpdate(key, Some, None));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddOrUpdate(K key, Func<V, V> Some, V None) =>\n        Wrap(Value.AddOrUpdate(key, Some, None));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TryAddRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TryAddRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TryAddRange(IEnumerable<KeyValuePair<K, V>> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddOrUpdateRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddOrUpdateRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Remove(K key) =>\n        Wrap(Value.Remove(key));\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<V> Find(K key) =>\n        Value.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) =>\n        Value.Find(key, Some, None);\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (HashMap<K, V> Map, V Value) FindOrAdd(K key, Func<V> None) =>\n        Value.FindOrAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"valueToFindOrAdd\">value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (HashMap<K, V>, V Value) FindOrAdd(K key, V valueToFindOrAdd) =>\n        Value.FindOrAdd(key, valueToFindOrAdd).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (HashMap<K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Func<Option<V>> None) =>\n        Value.FindOrMaybeAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (HashMap<K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Option<V> None) =>\n        Value.FindOrMaybeAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"valueToSet\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> SetItem(K key, V valueToSet) =>\n        Wrap(Value.SetItem(key, valueToSet));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> SetItem(K key, Func<V, V> Some) =>\n        Wrap(Value.SetItem(key, Some));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"valueToSet\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TrySetItem(K key, V valueToSet) =>\n        Wrap(Value.TrySetItem(key, valueToSet));\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TrySetItem(K key, Func<V, V> Some) =>\n        Wrap(Value.TrySetItem(key, Some));\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ContainsKey(K key) =>\n        Value.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key and value in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(K key, V value) =>\n        Value.Contains(key, value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains<EqV>(V value) where EqV : Eq<V> =>\n        Value.Contains<EqV>(value);\n\n    /// <summary>\n    /// Checks for existence of a key and value in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains<EqV>(K key, V value) where EqV : Eq<V> =>\n        Value.Contains<EqV>(key, value);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map\n    /// </summary>\n    /// <param name=\"pairs\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> AddRange(IEnumerable<KeyValuePair<K, V>> pairs) =>\n        Wrap(Value.AddRange(pairs));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> SetItems(IEnumerable<KeyValuePair<K, V>> items) =>\n        Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> SetItems(IEnumerable<Tuple<K, V>> items) =>\n        Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> SetItems(IEnumerable<(K Key, V Value)> items) =>\n        Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TrySetItems(IEnumerable<KeyValuePair<K, V>> items) =>\n        Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TrySetItems(IEnumerable<Tuple<K, V>> items) =>\n        Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TrySetItems(IEnumerable<(K Key, V Value)> items) =>\n        Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> TrySetItems(IEnumerable<K> keys, Func<V, V> Some) =>\n        Wrap(Value.TrySetItems(keys, Some));\n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New map with the items removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> RemoveRange(IEnumerable<K> keys) =>\n        Wrap(Value.RemoveRange(keys));\n\n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains((K Key, V Value) pair) =>\n        Value.Contains(pair.Key, pair.Value);\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.Keys;\n    }\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.Values;\n    }\n\n    /// <summary>\n    /// Map the map the a dictionary\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(\n        Func<(K Key, V Value), KR> keySelector, \n        Func<(K Key, V Value), VR> valueSelector)\n        where KR : notnull =>\n        AsIterable().ToDictionary(x => keySelector(x), x => valueSelector(x));\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// Allocation free conversion to a TrackingHashMap\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> ToTrackingHashMap() =>\n        new (value);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K Key, V Value)> AsIterable() =>\n        Value.AsIterable();\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator HashMap<K, V>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(HashMap<K, V> lhs, HashMap<K, V> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(HashMap<K, V> lhs, HashMap<K, V> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> operator +(HashMap<K, V> lhs, HashMap<K, V> rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Combine(HashMap<K, V> rhs) =>\n        Wrap(Value.Append(rhs.Value));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashMap<K, V> operator -(HashMap<K, V> lhs, HashMap<K, V> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Subtract(HashMap<K, V> rhs) =>\n        Wrap(Value.Subtract(rhs.Value));\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSubsetOf(IEnumerable<K> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsProperSupersetOf(IEnumerable<K> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(IEnumerable<K> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSubsetOf(HashMap<K, V> other) =>\n        Value.IsSubsetOf(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool IsSupersetOf(IEnumerable<K> rhs) =>\n        Value.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Intersect(IEnumerable<K> rhs) =>\n        Wrap(Value.Intersect(rhs));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Intersect(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.Intersect(rhs));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Intersect(IEnumerable<(K Key, V Value)> rhs, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.Intersect(rhs, Merge));\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Overlaps(IEnumerable<K> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Except(IEnumerable<K> rhs) =>\n        Wrap(Value.Except(rhs));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Except(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.Except(rhs));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> SymmetricExcept(HashMap<K, V> rhs) =>\n        Wrap(Value.SymmetricExcept(rhs.Value));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> SymmetricExcept(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.SymmetricExcept(rhs));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Union(IEnumerable<(K, V)> rhs) =>\n        this.TryAddRange(rhs);\n        \n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Union(IEnumerable<(K, V)> other, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.Union(other, static (_, v) => v, static (_, v) => v, Merge));\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the right-hand side, but not the left-hand-side.\n    /// This allows the `V2` value-type to be mapped to the target `V` value-type. \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Union<W>(IEnumerable<(K, W)> other, WhenMissing<K, W, V> MapRight, WhenMatched<K, V, W, V> Merge) =>\n        Wrap(Value.Union(other, static (_, v) => v, MapRight, Merge));\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the left-hand side, but not the right-hand-side.\n    /// This allows the `V` value-type to be mapped to the target `V2` value-type. \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, W> Union<W>(IEnumerable<(K, W)> other, WhenMissing<K, V, W> MapLeft, WhenMatched<K, V, W, W> Merge) =>\n        Wrap(Value.Union(other, MapLeft, static (_, v) => v, Merge));\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing MapLeft` function is called when there is a key in the left-hand side, but not the\n    /// right-hand-side.   This allows the `V` value-type to be mapped to the target `R` value-type. \n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing MapRight` function is called when there is a key in the right-hand side, but not the\n    /// left-hand-side.   This allows the `V2` value-type to be mapped to the target `R` value-type. \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, R> Union<W, R>(IEnumerable<(K, W)> other, \n                                     WhenMissing<K, V, R> MapLeft, \n                                     WhenMissing<K, W, R> MapRight, \n                                     WhenMatched<K, V, W, R> Merge) =>\n        Wrap(Value.Union(other, MapLeft, MapRight, Merge));\n\n    \n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is HashMap<K, V> hm && Equals(hm);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(HashMap<K, V> other) =>\n        Value.Equals<EqDefault<V>>(other.Value);\n\n    /// <summary>\n    /// Equality of keys and values with `EqV` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals<EqV>(HashMap<K, V> other) where EqV : Eq<V> =>\n        Value.Equals<EqV>(other.Value);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool EqualsKeys(HashMap<K, V> other) =>\n        Value.Equals<EqTrue<V>>(other.Value);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Do(Action<V> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, U> Select<U>(Func<V, U> mapper) =>\n        Map(mapper);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, U> Select<U>(Func<K, V, U> mapper) =>\n        Map(mapper);\n    \n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Where(Func<V, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public HashMap<K, V> Where(Func<K, V, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<K, V, bool> pred)\n    {\n        foreach (var item in AsIterable())\n        {\n            if (!pred(item.Key, item.Value)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        AsIterable().Map(kv => (kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<K, V, bool> pred)\n    {\n        foreach (var item in AsIterable())\n        {\n            if (pred(item.Key, item.Value)) return true;\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<(K Key, V Value), bool> pred) =>\n        AsIterable().Map(kv => (kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<K, V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Key, item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<(K Key, V Value)> action)\n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() =>\n        AsIterable().Map(p => new KeyValuePair<K, V>(p.Key, p.Value)).GetEnumerator();\n    \n    [Pure]\n    IEnumerable<K> IReadOnlyDictionary<K, V>.Keys => Keys;\n    \n    [Pure]\n    IEnumerable<V> IReadOnlyDictionary<K, V>.Values => Values;\n\n    [Pure]\n    public bool TryGetValue(K key, out V value)\n    {\n        var v = Find(key);\n        if (v.IsSome)\n        {\n            value = (V)v;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n    \n    /// <summary>\n    /// Get a IReadOnlyDictionary for this map.  No mapping is required, so this is very fast.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IReadOnlyDictionary<K, V> ToReadOnlyDictionary() =>\n        this;\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(ValueTuple<(K, V)> items) =>\n        new (new[] { items.Item1 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15 });\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator HashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        new (new[] { items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15, items.Item16 });\n\n    public static HashMap<K, V> AdditiveIdentity => \n        Empty;    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/Extensions/HashSet.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class HashSetExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashSet<B> Map<A, B>(this Func<A, B> f, K<HashSet, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashSet<B> Map<A, B>(this Func<A, B> f, HashSet<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static HashSet<B> Action<A, B>(this HashSet<A> ma, K<HashSet, B> mb) =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static HashSet<B> Action<A, B>(this K<HashSet, A> ma, K<HashSet, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static HashSet<B> Apply<A, B>(this HashSet<Func<A, B>> mf, K<HashSet, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static HashSet<B> Apply<A, B>(this K<HashSet, Func<A, B>> mf, K<HashSet, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/Extensions/HashSet.Extensions.cs",
    "content": "﻿\nusing System;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class HashSetExtensions\n{\n    [Pure]\n    public static HashSet<A> As<A>(this K<HashSet, A> ma) =>\n        (HashSet<A>)ma;\n    \n    /// <summary>\n    /// Convert to a queryable \n    /// </summary>\n    [Pure]\n    public static IQueryable<A> AsQueryable<A>(this HashSet<A> source) =>\n        // NOTE TO FUTURE ME: Don't delete this thinking it's not needed!\n        source.Value.AsQueryable();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/HashSet.Eq.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Unsorted immutable hash-set\n/// </summary>\n/// <typeparam name=\"A\">Key type</typeparam>\n[CollectionBuilder(typeof(HashSet), nameof(HashSet.createRange))]\npublic readonly struct HashSet<EqA, A> :\n    IEnumerable<A>,\n    IEquatable<HashSet<EqA, A>>,\n    IEqualityOperators<HashSet<EqA, A>, HashSet<EqA, A>, bool>,\n    IAdditionOperators<HashSet<EqA, A>, HashSet<EqA, A>, HashSet<EqA, A>>,\n    ISubtractionOperators<HashSet<EqA, A>, HashSet<EqA, A>, HashSet<EqA, A>>,\n    IAdditiveIdentity<HashSet<EqA, A>, HashSet<EqA, A>>,\n    Monoid<HashSet<EqA, A>>\n    where EqA : Eq<A>\n{\n    public static HashSet<EqA, A> Empty { get; } = new (TrieSet<EqA, A>.Empty);\n\n    readonly TrieSet<EqA, A> value;\n    TrieSet<EqA, A> Value => value ?? TrieSet<EqA, A>.Empty;\n\n    internal HashSet(TrieSet<EqA, A> value)\n    {\n        this.value = value;\n    }\n\n    HashSet<EqA, A> Wrap(TrieSet<EqA, A> value) =>\n        new (value);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    public HashSet(IEnumerable<A> items) : this(items, true)\n    {\n    }\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    public HashSet(IEnumerable<A> items, bool tryAdd) =>\n        value = new TrieSet<EqA, A>(items, tryAdd);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    public HashSet(ReadOnlySpan<A> items) : this(items, true)\n    {\n    }\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    public HashSet(ReadOnlySpan<A> items, bool tryAdd) =>\n        value = new TrieSet<EqA, A>(items, tryAdd);\n\n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    public static Lens<HashSet<EqA, A>, bool> item(A key) => Lens<HashSet<EqA, A>, bool>.New(\n        Get: la => la.Contains(key),\n        Set: a => la => a ? la.AddOrUpdate(key) : la.Remove(key));\n\n    /// <summary>\n    /// Lens map\n    /// </summary>\n    [Pure]\n    public static Lens<HashSet<EqA, A>, HashSet<EqA, A>> map(Lens<A, A> lens) => \n        Lens<HashSet<EqA, A>, HashSet<EqA, A>>.New(\n            Get: la => la.Map<EqA, A>(lens.Get),\n            Set: lb => la =>\n                       {\n                           foreach (var item in lb)\n                           {\n                               la = la.Find(item).Match(Some: x => la.AddOrUpdate(lens.Set(x, item)), None: () => la);\n                           }\n                           return la;\n                       });\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public A this[A key] =>\n        Value[key];\n\n    /// <summary>\n    /// Is the set empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the set\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public HashSet<EqA, A> Do(Action<A> f)\n    {\n        IterableExtensions.AsIterable(this).Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public HashSet<EqR, R> Map<EqR, R>(Func<A, R> mapper) where EqR : Eq<R>\n    {\n        IEnumerable<R> Yield(TrieSet<EqA, A> map, Func<A, R> f)\n        {\n            foreach (var item in map)\n            {\n                yield return f(item);\n            }\n        }\n        return new HashSet<EqR, R>(Yield(Value, mapper));\n    }\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public HashSet<EqA, A> Map(Func<A, A> mapper) =>\n        Map<EqA, A>(mapper);\n    \n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public HashSet<EqA, A> Filter(Func<A, bool> pred)\n    {\n        IEnumerable<A> Yield(TrieSet<EqA, A> map, Func<A, bool> f)\n        {\n            foreach (var item in map)\n            {\n                if (f(item))\n                {\n                    yield return item;\n                }\n            }\n        }\n        return new HashSet<EqA, A>(Yield(Value, pred));\n    }\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public HashSet<EqR, R> Select<EqR, R>(Func<A, R> mapper) where EqR : Eq<R> =>\n        Map<EqR, R>(mapper);\n\n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public HashSet<EqA, A> Where(Func<A, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public HashSet<EqA, A> Add(A key) =>\n        Wrap(Value.Add(key));\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public HashSet<EqA, A> TryAdd(A key) =>\n        Wrap(Value.TryAdd(key));\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public HashSet<EqA, A> AddOrUpdate(A key) =>\n        Wrap(Value.AddOrUpdate(key));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New HSet with the items added</returns>\n    [Pure]\n    public HashSet<EqA, A> AddRange(IEnumerable<A> range) =>\n        Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists, it's ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New HSet with the items added</returns>\n    [Pure]\n    public HashSet<EqA, A> TryAddRange(IEnumerable<A> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists then replace it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New HSet with the items added</returns>\n    [Pure]\n    public HashSet<EqA, A> AddOrUpdateRange(IEnumerable<A> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically removes an item from the set\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public HashSet<EqA, A> Remove(A key) =>\n        Wrap(Value.Remove(key));\n\n    /// <summary>\n    /// Retrieve a value from the set by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Option<A> Find(A key) =>\n        Value.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the set by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Seq<A> FindSeq(A key) =>\n        Find(key).ToSeq();\n\n    /// <summary>\n    /// Retrieve a value from the set by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public R Find<R>(A key, Func<A, R> Some, Func<R> None) =>\n        Find(key).Match(Some, None);\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a key</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if the key is null</exception>\n    /// <returns>New HSet with the item added</returns>\n    [Pure]\n    public HashSet<EqA, A> SetItem(A key) =>\n        Wrap(Value.SetItem(key));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a key</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if the key is null</exception>\n    /// <returns>New HSet with the item added</returns>\n    [Pure]\n    public HashSet<EqA, A> TrySetItem(A key) =>\n        Wrap(Value.TrySetItem(key));\n\n    /// <summary>\n    /// Checks for existence of a key in the set\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the set</returns>\n    [Pure]\n    public bool Contains(A key) =>\n        Value.ContainsKey(key);\n\n    /// <summary>\n    /// Clears all items from the set\n    /// </summary>\n    /// <remarks>Functionally equivalent to calling HSet.empty as the original structure is untouched</remarks>\n    /// <returns>Empty HSet</returns>\n    [Pure]\n    public HashSet<EqA, A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Atomically sets a series of items\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New HSet with the items set</returns>\n    [Pure]\n    public HashSet<EqA, A> SetItems(IEnumerable<A> items) =>\n        Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items.  If any of the items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New HSet with the items set</returns>\n    [Pure]\n    public HashSet<EqA, A> TrySetItems(IEnumerable<A> items) =>\n        Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically removes a list of keys from the set\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New HSet with the items removed</returns>\n    [Pure]\n    public HashSet<EqA, A> RemoveRange(IEnumerable<A> keys) =>\n        Wrap(Value.RemoveRange(keys));\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Value.GetEnumerator();\n\n    [Pure]\n    public Seq<A> ToSeq() =>\n        toSeq(this);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(this, Count);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(this, separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(this, separator);\n\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        Iterable.createRange(this);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator HashSet<EqA, A>(SeqEmpty _) =>\n        Empty;\n\n    [Pure]\n    public static HashSet<EqA, A> operator +(HashSet<EqA, A> lhs, HashSet<EqA, A> rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure]\n    public HashSet<EqA, A> Combine(HashSet<EqA, A> rhs) =>\n        Wrap(Value.Append(rhs.Value));\n\n    [Pure]\n    public static HashSet<EqA, A> operator -(HashSet<EqA, A> lhs, HashSet<EqA, A> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    public HashSet<EqA, A> Subtract(HashSet<EqA, A> rhs) =>\n        Wrap(Value.Subtract(rhs.Value));\n\n    [Pure]\n    public static bool operator ==(HashSet<EqA, A> lhs, HashSet<EqA, A> rhs) =>\n        lhs.Equals(rhs);\n\n    [Pure]\n    public static bool operator !=(HashSet<EqA, A> lhs, HashSet<EqA, A> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public bool Equals(HashSet<EqA, A> other) =>\n        Value.Equals(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<A> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<A> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<A> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<A> rhs) =>\n        Value.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public HashSet<EqA, A> Intersect(IEnumerable<A> rhs) =>\n        Wrap(Value.Intersect(rhs));\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<A> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public HashSet<EqA, A> Except(IEnumerable<A> rhs) =>\n        Wrap(Value.Except(rhs));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public HashSet<EqA, A> SymmetricExcept(HashSet<EqA, A> rhs) =>\n        Wrap(Value.SymmetricExcept(rhs.Value));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public HashSet<EqA, A> SymmetricExcept(IEnumerable<A> rhs) =>\n        Wrap(Value.SymmetricExcept(rhs));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public HashSet<EqA, A> Union(IEnumerable<A> rhs) =>\n        TryAddRange(rhs);\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public Unit CopyTo(A[] array, int index)\n    {\n        var       max  = array.Length;\n        using var iter = GetEnumerator();\n        for (var i = index; i < max && iter.MoveNext(); i++)\n        {\n            array[i] = iter.Current;\n        }\n        return default;\n    }\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public Unit CopyTo(System.Array array, int index)\n    {\n        var       max  = array.Length;\n        using var iter = GetEnumerator();\n        for (var i = index; i < max && iter.MoveNext(); i++)\n        {\n            array.SetValue(iter.Current, i);\n        }\n        return default;\n    }\n\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is HashSet<EqA, A> hs && Equals(hs);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    public HashSet<B> Bind<B>(Func<A, HashSet<B>> f)\n    {\n        var self = this;\n\n        IEnumerable<B> Yield()\n        {\n            foreach (var x in self.AsIterable())\n            {\n                foreach (var y in f(x))\n                {\n                    yield return y;\n                }\n            }\n        }\n        return new HashSet<B>(Yield(), true);\n    }\n\n    [Pure]\n    public HashSet<C> SelectMany<B, C>(Func<A, HashSet<B>> bind, Func<A, B, C> project)\n    {\n        var self = this;\n\n        IEnumerable<C> Yield()\n        {\n            foreach (var x in self.AsIterable())\n            {\n                foreach (var y in bind(x))\n                {\n                    yield return project(x, y);\n                }\n            }\n        }\n        return new HashSet<C>(Yield(), true);\n    }\n    \n    public static HashSet<EqA, A> AdditiveIdentity => \n        Empty;    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/HashSet.Module.Eq.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable hash-set module\n/// </summary>\npublic partial class HashSet\n{\n    /// <summary>\n    /// True if the set has no elements\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>True if the set has no elements</returns>\n    [Pure]\n    public static bool isEmpty<EqT, T>(HashSet<EqT, T> set) where EqT : Eq<T> =>\n        set.IsEmpty;\n\n    /// <summary>\n    /// Create a new empty set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>Empty HSet</returns>\n    [Pure]\n    public static HashSet<EqT, T> create<EqT, T>() where EqT : Eq<T> =>\n        HashSet<EqT, T>.Empty;\n\n    /// <summary>\n    /// Create a singleton collection\n    /// </summary>\n    /// <param name=\"value\">Single value</param>\n    /// <returns>Collection with a single item in it</returns>\n    [Pure]\n    public static HashSet<EqA, A> singleton<EqA, A>(A value) where EqA : Eq<A> =>\n        [value];\n\n    /// <summary>\n    /// Create a new set pre-populated with the items in range\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"range\">Range of items</param>\n    /// <returns>HSet</returns>\n    [Pure]\n    public static HashSet<EqA, A> createRange<EqA, A>(ReadOnlySpan<A> range) where EqA : Eq<A> =>\n        range.IsEmpty \n            ? HashSet<EqA, A>.Empty \n            : new (range);\n\n    /// <summary>\n    /// Create a new set pre-populated with the items in range\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"range\">Range of items</param>\n    /// <returns>HSet</returns>\n    [Pure]\n    public static HashSet<EqT, T> createRange<EqT, T>(IEnumerable<T> range) where EqT : Eq<T> =>\n        new (range);\n\n    /// <summary>\n    /// Create a new empty set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>Empty HSet</returns>\n    [Pure]\n    public static HashSet<EqT, T> empty<EqT, T>() where EqT : Eq<T> =>\n        HashSet<EqT, T>.Empty;\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the HSet</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public static HashSet<EqT, T> add<EqT, T>(HashSet<EqT, T> set, T value) where EqT : Eq<T> =>\n        set.Add(value);\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the HSet</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public static HashSet<EqT, T> tryAdd<EqT, T>(HashSet<EqT, T> set, T value) where EqT : Eq<T> =>\n        set.TryAdd(value);\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the HSet</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public static HashSet<EqT, T> addOrUpdate<EqT, T>(HashSet<EqT, T> set, T value) where EqT : Eq<T> =>\n        set.AddOrUpdate(value);\n\n    /// <summary>\n    /// Attempts to find an item in the set.  \n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"value\">Value to find</param>\n    /// <returns>Some(T) if found, None otherwise</returns>\n    [Pure]\n    public static Option<T> find<EqT, T>(HashSet<EqT, T> set, T value) where EqT : Eq<T> =>\n        set.Find(value);\n\n    /// <summary>\n    /// Check the existence of an item in the set using a \n    /// predicate.\n    /// </summary>\n    /// <remarks>Note this scans the entire set.</remarks>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if predicate returns true for any item</returns>\n    [Pure]\n    public static bool exists<EqT, T>(HashSet<EqT, T> set, Func<T, bool> pred) where EqT : Eq<T> =>\n        set.AsIterable().Exists(pred);\n\n    /// <summary>\n    /// Returns true if both sets contain the same elements\n    /// </summary>\n    [Pure]\n    public static bool equals<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.Equals(setB);\n\n    /// <summary>\n    /// Get the number of elements in the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <returns>Number of elements</returns>\n    [Pure]\n    public static int length<EqT, T>(HashSet<EqT, T> set) where EqT : Eq<T> =>\n        set.Count();\n\n    /// <summary>\n    /// Returns setA - setB.  Only the items in setA that are not in \n    /// setB will be returned.\n    /// </summary>\n    [Pure]\n    public static HashSet<EqT, T> subtract<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.Except(setB);\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set A</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public static HashSet<EqT, T> union<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.Union(setB);\n\n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public static HashSet<EqT, T> filter<EqT, T>(HashSet<EqT, T> set, Func<T, bool> pred) where EqT : Eq<T> =>\n        set.Filter(pred);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the set. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Set element type</typeparam>\n    /// <param name=\"set\">Set to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S fold<EqT, T, S>(HashSet<EqT, T> set, S state, Func<S, T, S> folder) where EqT : Eq<T> =>\n        set.AsIterable().Fold(state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the set. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Set element type</typeparam>\n    /// <param name=\"set\">Set to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBack<EqT, T, S>(HashSet<EqT, T> set, S state, Func<S, T, S> folder) where EqT : Eq<T> =>\n        set.AsIterable().FoldBack(state, folder);\n\n    /// <summary>\n    /// Returns the elements that are in both setA and setB\n    /// </summary>\n    [Pure]\n    public static HashSet<EqT, T> intersect<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.Intersect(setB);\n\n    /// <summary>\n    /// Returns the elements that are in both setA and setB\n    /// </summary>\n    [Pure]\n    public static HashSet<EqT, T> except<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.Except(setB);\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public static HashSet<EqT, T> symmetricExcept<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.SymmetricExcept(setB);\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to transform the source values.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static HashSet<EqR, R> map<EqT, EqR, T, R>(HashSet<EqT, T> set, Func<T, R> mapper) \n        where EqT : Eq<T>\n        where EqR : Eq<R>  =>\n        set.Map<EqR, R>(mapper);\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static HashSet<EqT, T> map<EqT, T>(HashSet<EqT, T> set, Func<T, T> mapper) where EqT : Eq<T> =>\n        set.Map(mapper);\n\n    /// <summary>\n    /// Returns True if the value is in the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if the item 'value' is in the Set 'set'</returns>\n    [Pure]\n    public static bool contains<EqT, T>(HashSet<EqT, T> set, T value) where EqT : Eq<T> =>\n        set.Contains(value);\n\n    /// <summary>\n    /// Removes an item from the set (if it exists)\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>New set with item removed</returns>\n    [Pure]\n    public static HashSet<EqT, T> remove<EqT, T>(HashSet<EqT, T> set, T value) where EqT : Eq<T> =>\n        set.Remove(value);\n\n    /// <summary>\n    /// Returns True if setB is a subset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a subset of setA</returns>\n    [Pure]\n    public static bool isSubHSet<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.IsSubsetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a superset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a superset of setA</returns>\n    [Pure]\n    public static bool isSuperHSet<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.IsSupersetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a proper subset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a proper subset of setA</returns>\n    [Pure]\n    public static bool isProperSubHSet<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.IsProperSubsetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a proper superset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a proper subset of setA</returns>\n    [Pure]\n    public static bool isProperSuperHSet<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.IsProperSupersetOf(setB);\n\n    /// <summary>\n    /// Returns True if setA overlaps setB\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True if setA overlaps setB</returns>\n    [Pure]\n    public static bool overlaps<EqT, T>(HashSet<EqT, T> setA, HashSet<EqT, T> setB) where EqT : Eq<T> =>\n        setA.Overlaps(setB);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/HashSet.Module.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable hash-set module\n/// </summary>\npublic partial class HashSet\n{\n    /// <summary>\n    /// True if the set has no elements\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>True if the set has no elements</returns>\n    [Pure]\n    public static bool isEmpty<T>(HashSet<T> set) =>\n        set.IsEmpty;\n\n    /// <summary>\n    /// Create a new empty set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>Empty HSet</returns>\n    [Pure]\n    public static HashSet<T> create<T>() =>\n        HashSet<T>.Empty;\n\n    /// <summary>\n    /// Create a singleton collection\n    /// </summary>\n    /// <param name=\"value\">Single value</param>\n    /// <returns>Collection with a single item in it</returns>\n    [Pure]\n    public static HashSet<A> singleton<A>(A value) =>\n        [value];\n\n    /// <summary>\n    /// Create a new set pre-populated with the items in range\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"range\">Range of items</param>\n    /// <returns>HSet</returns>\n    [Pure]\n    public static HashSet<T> createRange<T>(IEnumerable<T> range) =>\n        new (range);\n\n    /// <summary>\n    /// Create a new set pre-populated with the items in range\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"range\">Range of items</param>\n    /// <returns>HSet</returns>\n    [Pure]\n    public static HashSet<T> createRange<T>(ReadOnlySpan<T> range) =>\n        range.IsEmpty \n            ? HashSet<T>.Empty \n            : new (range);\n\n    /// <summary>\n    /// Create a new empty set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>Empty HSet</returns>\n    [Pure]\n    public static HashSet<T> empty<T>() =>\n        HashSet<T>.Empty;\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the HSet</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public static HashSet<T> add<T>(HashSet<T> set, T value) =>\n        set.Add(value);\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the HSet</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public static HashSet<T> tryAdd<T>(HashSet<T> set, T value) =>\n        set.TryAdd(value);\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the HSet</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public static HashSet<T> addOrUpdate<T>(HashSet<T> set, T value) =>\n        set.AddOrUpdate(value);\n\n    /// <summary>\n    /// Attempts to find an item in the set.  \n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"value\">Value to find</param>\n    /// <returns>Some(T) if found, None otherwise</returns>\n    [Pure]\n    public static Option<T> find<T>(HashSet<T> set, T value) =>\n        set.Find(value);\n\n    /// <summary>\n    /// Check the existence of an item in the set using a \n    /// predicate.\n    /// </summary>\n    /// <remarks>Note this scans the entire set.</remarks>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if predicate returns true for any item</returns>\n    [Pure]\n    public static bool exists<T>(HashSet<T> set, Func<T, bool> pred) =>\n        set.Exists(pred);\n\n    /// <summary>\n    /// Returns true if both sets contain the same elements\n    /// </summary>\n    [Pure]\n    public static bool equals<T>(HashSet<T> setA, HashSet<T> setB) =>\n        setA.Equals(setB);\n\n    /// <summary>\n    /// Get the number of elements in the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <returns>Number of elements</returns>\n    [Pure]\n    public static int length<T>(HashSet<T> set) =>\n        set.Count();\n\n    /// <summary>\n    /// Returns setA - setB.  Only the items in setA that are not in \n    /// setB will be returned.\n    /// </summary>\n    [Pure]\n    public static HashSet<T> subtract<T>(HashSet<T> setA, HashSet<T> setB) =>\n        setA.Except(setB);\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set A</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public static HashSet<T> union<T>(HashSet<T> setA, HashSet<T> setB) =>\n        setA.Union(setB);\n\n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public static HashSet<T> filter<T>(HashSet<T> set, Func<T, bool> pred) =>\n        set.Filter(pred);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the set. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Set element type</typeparam>\n    /// <param name=\"set\">Set to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S fold<T, S>(HashSet<T> set, S state, Func<S, T, S> folder) =>\n        set.Fold(state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the set. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Set element type</typeparam>\n    /// <param name=\"set\">Set to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBack<T, S>(HashSet<T> set, S state, Func<S, T, S> folder) =>\n        set.FoldBack(state, folder);\n\n    /// <summary>\n    /// Returns the elements that are in both setA and setB\n    /// </summary>\n    [Pure]\n    public static HashSet<T> intersect<T>(HashSet<T> setA, IEnumerable<T> setB) =>\n        setA.Intersect(setB);\n\n    /// <summary>\n    /// Returns the elements that are in both setA and setB\n    /// </summary>\n    [Pure]\n    public static HashSet<T> except<T>(HashSet<T> setA, IEnumerable<T> setB) =>\n        setA.Except(setB);\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public static HashSet<T> symmetricExcept<T>(HashSet<T> setA, IEnumerable<T> setB) =>\n        setA.SymmetricExcept(setB);\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static HashSet<R> map<T, R>(HashSet<T> set, Func<T, R> mapper) =>\n        set.Map(mapper);\n\n    /// <summary>\n    /// Returns True if the value is in the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if the item 'value' is in the Set 'set'</returns>\n    [Pure]\n    public static bool contains<T>(HashSet<T> set, T value) =>\n        set.Contains(value);\n\n    /// <summary>\n    /// Removes an item from the set (if it exists)\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>New set with item removed</returns>\n    [Pure]\n    public static HashSet<T> remove<T>(HashSet<T> set, T value) =>\n        set.Remove(value);\n\n    /// <summary>\n    /// Returns True if setB is a subset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a subset of setA</returns>\n    [Pure]\n    public static bool isSubHSet<T>(HashSet<T> setA, IEnumerable<T> setB) =>\n        setA.IsSubsetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a superset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a superset of setA</returns>\n    [Pure]\n    public static bool isSuperHSet<T>(HashSet<T> setA, IEnumerable<T> setB) =>\n        setA.IsSupersetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a proper subset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a proper subset of setA</returns>\n    [Pure]\n    public static bool isProperSubHSet<T>(HashSet<T> setA, IEnumerable<T> setB) =>\n        setA.IsProperSubsetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a proper superset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a proper subset of setA</returns>\n    [Pure]\n    public static bool isProperSuperHSet<T>(HashSet<T> setA, IEnumerable<T> setB) =>\n        setA.IsProperSupersetOf(setB);\n\n    /// <summary>\n    /// Returns True if setA overlaps setB\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True if setA overlaps setB</returns>\n    [Pure]\n    public static bool overlaps<T>(HashSet<T> setA, IEnumerable<T> setB) =>\n        setA.Overlaps(setB);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/HashSet.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Unsorted immutable hash-set\n/// </summary>\n/// <typeparam name=\"A\">Key type</typeparam>\n[CollectionBuilder(typeof(HashSet), nameof(HashSet.createRange))]\npublic readonly struct HashSet<A> :\n    IEnumerable<A>,\n    IEquatable<HashSet<A>>,\n    IEqualityOperators<HashSet<A>, HashSet<A>, bool>,\n    IAdditionOperators<HashSet<A>, HashSet<A>, HashSet<A>>,\n    ISubtractionOperators<HashSet<A>, HashSet<A>, HashSet<A>>,\n    IAdditiveIdentity<HashSet<A>, HashSet<A>>,\n    Monoid<HashSet<A>>,\n    K<HashSet, A>\n{\n    public static HashSet<A> Empty { get; } = new (TrieSet<EqDefault<A>, A>.Empty);\n\n    readonly TrieSet<EqDefault<A>, A> value;\n    internal TrieSet<EqDefault<A>, A> Value => value ?? TrieSet<EqDefault<A>, A>.Empty;\n\n    internal HashSet(TrieSet<EqDefault<A>, A> value)\n    {\n        this.value = value;\n    }\n\n    HashSet<A> Wrap(TrieSet<EqDefault<A>, A> value) =>\n        new (value);\n\n    static HashSet<B> Wrap<B>(TrieSet<EqDefault<B>, B> value) =>\n        new (value);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    public HashSet(ReadOnlySpan<A> items) =>\n        value = new TrieSet<EqDefault<A>, A>(items);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    public HashSet(ReadOnlySpan<A> items, bool tryAdd) =>\n        value = new TrieSet<EqDefault<A>, A>(items, tryAdd);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    public HashSet(IEnumerable<A> items) =>\n        value = new TrieSet<EqDefault<A>, A>(items);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    public HashSet(IEnumerable<A> items, bool tryAdd) =>\n        value = new TrieSet<EqDefault<A>, A>(items, tryAdd);\n\n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    public static Lens<HashSet<A>, bool> item(A key) => Lens<HashSet<A>, bool>.New(\n        Get: la => la.Contains(key),\n        Set: a => la => a ? la.AddOrUpdate(key) : la.Remove(key)\n    );\n\n    /// <summary>\n    /// Lens map\n    /// </summary>\n    [Pure]\n    public static Lens<HashSet<A>, HashSet<A>> map<B>(Lens<A, A> lens) => Lens<HashSet<A>, HashSet<A>>.New(\n        Get: la => la.Map(lens.Get),\n        Set: lb => la =>\n                   {\n                       foreach (var item in lb)\n                       {\n                           la = la.Find(item).Match(Some: x => la.AddOrUpdate(lens.Set(x, item)), None: () => la);\n                       }\n                       return la;\n                   });\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public A this[A key] =>\n        Value[key];\n\n    /// <summary>\n    /// Is the set empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the set\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n        \n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public HashSet<A> Do(Action<A> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public HashSet<R> Map<R>(Func<A, R> mapper)\n    {\n        IEnumerable<R> Yield(TrieSet<EqDefault<A>, A> map, Func<A, R> f)\n        {\n            foreach (var item in map)\n            {\n                yield return f(item);\n            }\n        }\n        return new HashSet<R>(Yield(Value, mapper));\n    }\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, HashSet<B>> Traverse<F, B>(Func<A, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, HashSet<B>> TraverseM<M, B>(Func<A, K<M, B>> f) \n        where M : Monad<M> =>\n        M.Map(x => x.As(), Traversable.traverseM(f, this));\n    \n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public HashSet<A> Filter(Func<A, bool> pred)\n    {\n        IEnumerable<A> Yield(TrieSet<EqDefault<A>, A> map, Func<A, bool> f)\n        {\n            foreach (var item in map)\n            {\n                if (f(item))\n                {\n                    yield return item;\n                }\n            }\n        }\n        return new HashSet<A>(Yield(Value, pred));\n    }\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public HashSet<R> Select<R>(Func<A, R> mapper) =>\n        Map(mapper);\n\n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">HSet</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public HashSet<A> Where(Func<A, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public HashSet<A> Add(A key) =>\n        Wrap(Value.Add(key));\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public HashSet<A> TryAdd(A key) =>\n        Wrap(Value.TryAdd(key));\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public HashSet<A> AddOrUpdate(A key) =>\n        Wrap(Value.AddOrUpdate(key));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New HSet with the items added</returns>\n    [Pure]\n    public HashSet<A> AddRange(IEnumerable<A> range) =>\n        Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists, it's ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New HSet with the items added</returns>\n    [Pure]\n    public HashSet<A> TryAddRange(IEnumerable<A> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists then replace it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New HSet with the items added</returns>\n    [Pure]\n    public HashSet<A> AddOrUpdateRange(IEnumerable<A> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically removes an item from the set\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public HashSet<A> Remove(A key) =>\n        Wrap(Value.Remove(key));\n\n    /// <summary>\n    /// Retrieve a value from the set by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Option<A> Find(A key) =>\n        Value.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the set by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Seq<A> FindSeq(A key) =>\n        Find(key).ToSeq();\n\n    /// <summary>\n    /// Retrieve a value from the set by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public R Find<R>(A key, Func<A, R> Some, Func<R> None) =>\n        Find(key).Match(Some, None);\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a key</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if the key is null</exception>\n    /// <returns>New HSet with the item added</returns>\n    [Pure]\n    public HashSet<A> SetItem(A key) =>\n        Wrap(Value.SetItem(key));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a key</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if the key is null</exception>\n    /// <returns>New HSet with the item added</returns>\n    [Pure]\n    public HashSet<A> TrySetItem(A key) =>\n        Wrap(Value.TrySetItem(key));\n\n    /// <summary>\n    /// Checks for existence of a key in the set\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the set</returns>\n    [Pure]\n    public bool Contains(A key) =>\n        Value.ContainsKey(key);\n\n    /// <summary>\n    /// Clears all items from the set\n    /// </summary>\n    /// <remarks>Functionally equivalent to calling HSet.empty as the original structure is untouched</remarks>\n    /// <returns>Empty HSet</returns>\n    [Pure]\n    public HashSet<A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Atomically sets a series of items\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New HSet with the items set</returns>\n    [Pure]\n    public HashSet<A> SetItems(IEnumerable<A> items) =>\n        Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items.  If any of the items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New HSet with the items set</returns>\n    [Pure]\n    public HashSet<A> TrySetItems(IEnumerable<A> items) =>\n        Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically removes a list of keys from the set\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New HSet with the items removed</returns>\n    [Pure]\n    public HashSet<A> RemoveRange(IEnumerable<A> keys) =>\n        Wrap(Value.RemoveRange(keys));\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Value.GetEnumerator();\n\n    [Pure]\n    public Seq<A> ToSeq() =>\n        toSeq(this);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(this, Count);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(this, separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(this, separator);\n\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        IterableExtensions.AsIterable(this);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator HashSet<A>(SeqEmpty _) =>\n        Empty;\n        \n    [Pure]\n    public static HashSet<A> operator +(HashSet<A> lhs, HashSet<A> rhs) =>\n        lhs.Combine(rhs);\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashSet<A> operator |(HashSet<A> x, K<HashSet, A> y) =>\n        x.Choose(y).As();\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static HashSet<A> operator |(K<HashSet, A> x, HashSet<A> y) =>\n        x.Choose(y).As();\n    \n    [Pure]\n    public HashSet<A> Combine(HashSet<A> rhs) =>\n        Wrap(Value.Append(rhs.Value));\n\n    [Pure]\n    public static HashSet<A> operator -(HashSet<A> lhs, HashSet<A> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    public HashSet<A> Subtract(HashSet<A> rhs) =>\n        Wrap(Value.Subtract(rhs.Value));\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    [Pure]\n    public static bool operator ==(HashSet<A> lhs, HashSet<A> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// In-equality\n    /// </summary>\n    [Pure]\n    public static bool operator !=(HashSet<A> lhs, HashSet<A> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    [Pure]\n    public bool Equals(HashSet<A> other) =>\n        Value.Equals(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<A> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<A> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<A> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<A> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<A> rhs) =>\n        Value.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public HashSet<A> Intersect(IEnumerable<A> rhs) =>\n        Wrap(Value.Intersect(rhs));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public HashSet<A> Except(IEnumerable<A> rhs) =>\n        Wrap(Value.Except(rhs));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public HashSet<A> SymmetricExcept(HashSet<A> rhs) =>\n        Wrap(Value.SymmetricExcept(rhs.Value));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public HashSet<A> SymmetricExcept(IEnumerable<A> rhs) =>\n        Wrap(Value.SymmetricExcept(rhs));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public HashSet<A> Union(IEnumerable<A> rhs) =>\n        this.TryAddRange(rhs);\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public Unit CopyTo(A[] array, int index)\n    {\n        var       max  = array.Length;\n        using var iter = GetEnumerator();\n        for (var i = index; i < max && iter.MoveNext(); i++)\n        {\n            array[i] = iter.Current;\n        }\n\n        return default;\n    }\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public Unit CopyTo(Array array, int index)\n    {\n        var       max  = array.Length;\n        using var iter = GetEnumerator();\n        for (var i = index; i < max && iter.MoveNext(); i++)\n        {\n            array.SetValue(iter.Current, i);\n        }\n        return default;\n    }\n\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is HashSet<A> hs && Equals(hs);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    public HashSet<B> Bind<B>(Func<A, HashSet<B>> f)\n    {\n        var self = this;\n\n        IEnumerable<B> Yield()\n        {\n            foreach (var x in self.AsIterable())\n            {\n                foreach (var y in f(x))\n                {\n                    yield return y;\n                }\n            }\n        }\n        return new HashSet<B>(Yield(), true);\n    }\n\n    [Pure]\n    public HashSet<C> SelectMany<B, C>(Func<A, HashSet<B>> bind, Func<A, B, C> project)\n    {\n        var self = this;\n\n        IEnumerable<C> Yield()\n        {\n            foreach (var x in self.AsIterable())\n            {\n                foreach (var y in bind(x))\n                {\n                    yield return project(x, y);\n                }\n            }\n        }\n        return new HashSet<C>(Yield(), true);\n    }\n    \n    public static HashSet<A> AdditiveIdentity => \n        Empty;    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/Operators/HashSet.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class HashSetExtensions\n{\n    extension<A>(K<HashSet, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static HashSet<A> operator +(K<HashSet, A> ma) =>\n            (HashSet<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/Prelude/HashSet.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static HashSet<B> map<A, B>(Func<A, B> f, K<HashSet, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static HashSet<B> action<A, B>(K<HashSet, A> ma, K<HashSet, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static HashSet<B> apply<A, B>(K<HashSet, Func<A, B>> mf, K<HashSet, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/HashSet/Trait/HashSet.TraitImpl.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class HashSet : \n    Monad<HashSet>, \n    MonoidK<HashSet>,\n    Alternative<HashSet>, \n    Traversable<HashSet>\n{\n    static K<HashSet, B> Monad<HashSet>.Recur<A, B>(A value, Func<A, K<HashSet, Next<A, B>>> f) =>\n        createRange(Monad.enumerableRecur(value, x =>f(x).As().AsEnumerable()));\n    \n    static K<HashSet, B> Monad<HashSet>.Bind<A, B>(K<HashSet, A> ma, Func<A, K<HashSet, B>> f)\n    {\n        return new HashSet<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var x in ma.As())\n            {\n                foreach (var y in f(x).As())\n                {\n                    yield return y;\n                }\n            }\n        }\n    }\n\n    static K<HashSet, B> Functor<HashSet>.Map<A, B>(Func<A, B> f, K<HashSet, A> ma)\n    {\n        return new HashSet<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var x in ma.As())\n            {\n                yield return f(x);\n            }\n        }\n    }\n\n    static K<HashSet, A> Applicative<HashSet>.Pure<A>(A value) =>\n        singleton(value);\n\n    static K<HashSet, B> Applicative<HashSet>.Apply<A, B>(K<HashSet, Func<A, B>> mf, K<HashSet, A> ma)\n    {\n        var ff = mf.As();\n        if(ff.IsEmpty) return HashSet<B>.Empty;\n        \n        return new HashSet<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var f in mf.As())\n            {\n                foreach (var a in ma.As())\n                {\n                    yield return f(a);\n                }\n            }\n        }\n    }    \n\n    static K<HashSet, B> Applicative<HashSet>.Apply<A, B>(K<HashSet, Func<A, B>> mf, Memo<HashSet, A> ma)\n    {\n        var ff = mf.As();\n        if(ff.IsEmpty) return HashSet<B>.Empty;\n        return new HashSet<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var f in mf.As())\n            {\n                foreach (var a in ma.Value.As())\n                {\n                    yield return f(a);\n                }\n            }\n        }\n    }      \n\n    static K<HashSet, A> MonoidK<HashSet>.Empty<A>() =>\n        HashSet<A>.Empty;\n\n    static K<HashSet, A> Alternative<HashSet>.Empty<A>() =>\n        HashSet<A>.Empty;\n\n    static K<HashSet, A> SemigroupK<HashSet>.Combine<A>(K<HashSet, A> ma, K<HashSet, A> mb) =>\n        ma.As() + mb.As();\n    \n    static K<HashSet, A> Choice<HashSet>.Choose<A>(K<HashSet, A> ma, K<HashSet, A> mb) => \n        ma.IsEmpty ? mb : ma;\n    \n    static K<HashSet, A> Choice<HashSet>.Choose<A>(K<HashSet, A> ma, Memo<HashSet, A> mb) => \n        ma.IsEmpty ? mb.Value : ma;\n    \n    static bool Foldable<HashSet>.Contains<EqA, A>(A value, K<HashSet, A> ta) =>\n        ta.As().Contains(value);\n\n    static int Foldable<HashSet>.Count<A>(K<HashSet, A> ta) =>\n        ta.As().Count;\n\n    static bool Foldable<HashSet>.IsEmpty<A>(K<HashSet, A> ta) =>\n        ta.As().IsEmpty;\n\n    static K<F, K<HashSet, B>> Traversable<HashSet>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<HashSet, A> ta) \n    {\n        return F.Map<HashSet<B>, K<HashSet, B>>(\n            ks => ks,\n            Foldable.fold(acc, F.Pure(empty<B>()), ta));\n\n        K<F, HashSet<B>> acc(K<F, HashSet<B>> ys, A x) =>\n            Applicative.lift((bs, b) => bs.Add(b), ys, f(x));\n    }\n\n    static K<F, K<HashSet, B>> Traversable<HashSet>.TraverseM<F, A, B>(Func<A, K<F, B>> f, K<HashSet, A> ta) \n    {\n        return F.Map<HashSet<B>, K<HashSet, B>>(\n            ks => ks,\n            Foldable.fold(acc, F.Pure(empty<B>()), ta));\n\n        K<F, HashSet<B>> acc(K<F, HashSet<B>> fys, A x) =>\n            fys.Bind(ys => f(x).Map(ys.Add));\n    }\n    \n    static Fold<A, S> Foldable<HashSet>.FoldStep<A, S>(K<HashSet, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n\n    static Fold<A, S> Foldable<HashSet>.FoldStepBack<A, S>(K<HashSet, A> ta, S initialState) =>\n        // Order is undefined in a HashSet, so reversing the order makes no sense,\n        // so let's take the most efficient option:\n        ta.FoldStep(initialState);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.Add.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\nsealed class IterableAdd<A>(SeqStrict<A> Prefix, Iterable<A> Source, SeqStrict<A> Postfix) : Iterable<A>\n{\n    internal override bool IsAsync =>\n        Source.IsAsync;\n    \n    public override IO<int> CountIO() =>\n        Source.CountIO().Map(c => Prefix.Count + c + Postfix.Count);\n\n    public override Iterable<A> Add(A item) =>\n        new IterableAdd<A>(Prefix, Source, (SeqStrict<A>)Postfix.Add(item));\n\n    public override Iterable<A> Cons(A item) =>\n        new IterableAdd<A>((SeqStrict<A>)Prefix.Cons(item), Source, Postfix);\n\n    public override IO<IEnumerable<A>> AsEnumerableIO()\n    {\n        return IO.lift(go);\n        IEnumerable<A> go(EnvIO env)\n        {\n            foreach (var x in Prefix)\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n\n            foreach (var x in Source.AsEnumerable(env.Token))\n            {\n                if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n\n            foreach (var x in Postfix)\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n        }\n    }\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO()\n    {\n        return IO.lift(go);\n        async IAsyncEnumerable<A> go(EnvIO env)\n        {\n            foreach (var x in Prefix)\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n\n            await foreach (var x in Source.AsAsyncEnumerable(env.Token))\n            {\n                yield return x;\n            }\n\n            foreach (var x in Postfix)\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n        }\n    }\n\n    public override Iterable<A> Reverse() =>\n        new IterableAdd<A>(Postfix.Rev(), Source.Rev(), Prefix.Rev());\n\n    public override Iterable<B> Map<B>(Func<A, B> f) =>\n        new IterableAdd<B>(Prefix.Map(f), Source.Map(f), Postfix.Map(f));\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        new IterableAdd<A>(Prefix.Filter(f), Source.Filter(f), Postfix.Filter(f));\n\n    public override IO<S> FoldWhileIO<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        Source.IsAsync\n            ? IO.liftVAsync(async env =>\n                            {\n                                var s = initialState;\n\n                                foreach (var x in Prefix)\n                                {\n                                    if (!predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n\n                                    s = f(x)(s);\n                                }\n\n                                await foreach (var x in Source.AsAsyncEnumerable(env.Token))\n                                {\n                                    if (!predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n\n                                    s = f(x)(s);\n                                }\n\n                                foreach (var x in Postfix)\n                                {\n                                    if (!predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n\n                                    s = f(x)(s);\n                                }\n\n                                return s;\n                            })\n            : IO.lift(env =>\n                      {\n                          var s = initialState;\n\n                          foreach (var x in Prefix)\n                          {\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n\n                              s = f(x)(s);\n                          }\n\n                          foreach (var x in Source.AsEnumerable(env.Token))\n                          {\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n\n                              s = f(x)(s);\n                          }\n\n                          foreach (var x in Postfix)\n                          {\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n\n                              s = f(x)(s);\n                          }\n\n                          return s;\n                      });\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        Source.IsAsync\n            ? IO.liftVAsync(async env =>\n                            {\n                                var s = initialState;\n\n                                foreach (var x in Prefix)\n                                {\n                                    if (!predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n\n                                    s = f(s, x);\n                                }\n\n                                await foreach (var x in Source.AsAsyncEnumerable(env.Token))\n                                {\n                                    if (!predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n\n                                    s = f(s, x);\n                                }\n\n                                foreach (var x in Postfix)\n                                {\n                                    if (!predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n\n                                    s = f(s, x);\n                                }\n\n                                return s;\n                            })\n            : IO.lift(env =>\n                      {\n                          var s = initialState;\n\n                          foreach (var x in Prefix)\n                          {\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n\n                              s = f(s, x);\n                          }\n\n                          foreach (var x in Source.AsEnumerable(env.Token))\n                          {\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n\n                              s = f(s, x);\n                          }\n\n                          foreach (var x in Postfix)\n                          {\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n\n                              s = f(s, x);\n                          }\n\n                          return s;\n                      });\n\n    public override IO<S> FoldUntilIO<S>(\n        Func<A, Func<S, S>> f, \n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        Source.IsAsync\n            ? IO.liftVAsync(async env =>\n                            {\n                                var s = initialState;\n\n                                foreach (var x in Prefix)\n                                {\n                                    s = f(x)(s);\n                                    if (predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n                                }\n\n                                await foreach (var x in Source.AsAsyncEnumerable(env.Token))\n                                {\n                                    s = f(x)(s);\n                                    if (predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n                                }\n\n                                foreach (var x in Postfix)\n                                {\n                                    s = f(x)(s);\n                                    if (predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n                                }\n                                return s;\n                            })\n            : IO.lift(env =>\n                      {\n                          var s = initialState;\n\n                          foreach (var x in Prefix)\n                          {\n                              s = f(x)(s);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n\n                          foreach (var x in Source.AsEnumerable(env.Token))\n                          {\n                              s = f(x)(s);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n\n                          foreach (var x in Postfix)\n                          {\n                              s = f(x)(s);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n\n                          return s;\n                      });\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        Source.IsAsync\n            ? IO.liftVAsync(async env =>\n                            {\n                                var s = initialState;\n\n                                foreach (var x in Prefix)\n                                {\n                                    s = f(s, x);\n                                    if (predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n                                }\n\n                                await foreach (var x in Source.AsAsyncEnumerable(env.Token))\n                                {\n                                    s = f(s, x);\n                                    if (predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n                                }\n\n                                foreach (var x in Postfix)\n                                {\n                                    s = f(s, x);\n                                    if (predicate((s, x)))\n                                    {\n                                        return s;\n                                    }\n                                }\n                                return s;\n                            })\n            : IO.lift(env =>\n                      {\n                          var s = initialState;\n\n                          foreach (var x in Prefix)\n                          {\n                              s = f(s, x);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n\n                          foreach (var x in Source.AsEnumerable(env.Token))\n                          {\n                              s = f(s, x);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n\n                          foreach (var x in Postfix)\n                          {\n                              s = f(s, x);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n\n                          return s;\n                      });\n\n    public override Iterable<A> Choose(Iterable<A> rhs)\n    {\n        if (!Prefix.IsEmpty) return this;\n        return new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n    }\n\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) \n    {\n        if (!Prefix.IsEmpty) return this;\n        return new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.Value.As().AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n    }\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.AsyncEnumerable.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nsealed class IterableAsyncEnumerable<A>(IO<IAsyncEnumerable<A>> runEnumerable) : Iterable<A>\n{\n    internal override bool IsAsync =>\n        true;\n\n    public override IO<int> CountIO() =>\n        IO.liftVAsync(async env => await (await runEnumerable.RunAsync(env)).CountAsync(env.Token));\n\n    public override IO<IEnumerable<A>> AsEnumerableIO()\n    {\n        return IO.lift(env => go(env, runEnumerable));\n\n        static IEnumerable<A> go(EnvIO env, IO<IAsyncEnumerable<A>> run)\n        {\n            var xs = run.Run(env);\n            foreach (var x in xs.ToBlockingEnumerable(env.Token))\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n        }\n    }\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO() \n    {\n        return IO.lift(env => go(env, runEnumerable));\n\n        static async IAsyncEnumerable<A> go(EnvIO env, IO<IAsyncEnumerable<A>> run)\n        {\n            var xs = await run.RunAsync(env);\n            await foreach (var x in xs.WithCancellation(env.Token))\n            {\n                yield return x;\n            }\n        }\n    }\n\n    public override Iterable<A> Reverse() =>\n        new IterableAsyncEnumerable<A>(AsAsyncEnumerableIO().Map(xs => xs.Reverse()));\n\n    public override Iterable<B> Map<B>(Func<A, B> f) =>\n        new IterableAsyncEnumerable<B>(AsAsyncEnumerableIO().Map(xs => xs.Select(f)));\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        new IterableAsyncEnumerable<A>(AsAsyncEnumerableIO().Map(xs => xs.Where(f)));\n\n    public override IO<S> FoldWhileIO<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        IO.liftVAsync(async env =>\n                      {\n                          var s = initialState;\n                          var xs = await runEnumerable.RunAsync(env);\n                          await foreach (var x in xs.WithCancellation(env.Token))\n                          {\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                              s = f(x)(s);\n                          }\n                          return s;\n                      });\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          var xs = await runEnumerable.RunAsync(env);\n                          await foreach (var x in xs.WithCancellation(env.Token))\n                          {\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n\n                              s = f(s, x);\n                          }\n\n                          return s;\n                      });\n\n    public override IO<S> FoldUntilIO<S>(\n        Func<A, Func<S, S>> f, \n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          var xs = await runEnumerable.RunAsync(env);\n                          await foreach (var x in xs.WithCancellation(env.Token))\n                          {\n                              s = f(x)(s);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n\n                          return s;\n                      });\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          var xs = await runEnumerable.RunAsync(env);\n                          await foreach (var x in xs.WithCancellation(env.Token))\n                          {\n                              s = f(s, x);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n                          return s;\n                      });\n\n\n    public override Iterable<A> Choose(Iterable<A> rhs) =>\n        new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n\n    /// <summary>\n    /// If this sequence is empty, return the other sequence, otherwise return this sequence.\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side of the operator</param>\n    /// <returns>A choice between two sequences based</returns>\n    [Pure]\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) =>\n        new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.Value.As().AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.Cast.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace LanguageExt;\n\nsealed class IterableCast<X, A>(Iterable<X> Items) : Iterable<A>\n{\n    internal override bool IsAsync =>\n        Items.IsAsync;\n    \n    public override IO<int> CountIO() =>\n        Items.CountIO();\n\n    public override IO<IEnumerable<A>> AsEnumerableIO()\n    {\n        return Items.AsEnumerableIO()\n                    .Map(xs => xs as IEnumerable<A> ?? go(xs));\n        \n        IEnumerable<A> go(IEnumerable<X> xs)\n        {\n            foreach (object? x in xs)\n            {\n                if (x is A y) yield return y;\n            }\n        }\n    }\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO()\n    {\n        return Items.AsAsyncEnumerableIO()\n                    .Map(xs => xs as IAsyncEnumerable<A> ?? go(xs));\n        \n        async IAsyncEnumerable<A> go(IAsyncEnumerable<X> xs)\n        {\n            await foreach (object? x in xs)\n            {\n                if (x is A y) yield return y;\n            }\n        }\n    }\n\n    public override Iterable<A> Reverse() =>\n        new IterableCast<X, A>(Items.Reverse());\n\n    public override Iterable<B> Map<B>(Func<A, B> f) =>\n        Make().Map(f);\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        Make().Filter(f);\n\n    public override IO<S> FoldWhileIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        Make().FoldWhileIO(f, predicate, initialState);\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        Make().FoldWhileIO(f, predicate, initialState);\n\n    public override IO<S> FoldUntilIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        Make().FoldUntilIO(f, predicate, initialState);\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        Make().FoldUntilIO(f, predicate, initialState);\n\n    public override Iterable<A> Choose(Iterable<A> rhs) =>\n        new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) => \n        new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.Value.As().AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n\n    Iterable<A> Make() =>\n        IsAsync\n            ? new IterableEnumerable<A>(AsEnumerableIO())\n            : new IterableAsyncEnumerable<A>(AsAsyncEnumerableIO());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.Concat.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nsealed class IterableConcat<A>(Seq<Iterable<A>> Items) : Iterable<A>\n{\n    public Seq<Iterable<A>> Items { get; } = Items;\n\n    internal override bool IsAsync =>\n        Items.Exists(x => x.IsAsync);\n    \n    public override IO<int> CountIO() =>\n        +Items.FoldM(0, (s, iter) => iter.CountIO().Map(c => c + s));\n\n    public override IO<IEnumerable<A>> AsEnumerableIO()\n    {\n        return +go(Items);\n        K<IO, IEnumerable<A>> go(Seq<Iterable<A>> items) =>\n            items switch\n            {\n                []         => IO.pure(Enumerable.Empty<A>()),\n                var (h, t) => +h.AsEnumerableIO() >> (xs => xs.Concat * go(t))\n            };\n    }\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO() \n    {\n        return go(Items);\n        IO<IAsyncEnumerable<A>> go(Seq<Iterable<A>> items) =>\n            items switch\n            {\n                []         => IO.pure(AsyncEnumerable.Empty<A>()),\n                var (h, t) => from xs in h.AsAsyncEnumerableIO()\n                              from ys in go(t)\n                              select xs.Concat<A>(ys)\n            };\n    }\n\n    public override Iterable<A> Reverse() =>\n        new IterableConcat<A>(Items.Map(xs => xs.Reverse()).Rev());\n\n    public override Iterable<B> Map<B>(Func<A, B> f) =>\n        new IterableConcat<B>(Items.Map(xs => xs.Map(f)));\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        new IterableConcat<A>(Items.Map(xs => xs.Filter(f)));\n\n    public override IO<S> FoldWhileIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          foreach (var xxs in Items)\n                          {\n                              if (xxs.IsAsync)\n                              {\n                                  await foreach (var x in xxs.AsAsyncEnumerable(env.Token))\n                                  {\n                                      if (!predicate((s, x)))\n                                      {\n                                          return s;\n                                      }\n\n                                      s = f(x)(s);\n                                  }\n                              }\n                              else\n                              {\n                                  foreach (var x in xxs.AsEnumerable(env.Token))\n                                  {\n                                      if (!predicate((s, x)))\n                                      {\n                                          return s;\n                                      }\n                                      s = f(x)(s);\n                                  }\n                              }\n                          }\n                          return s;\n                      });\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          foreach (var xxs in Items)\n                          {\n                              if (xxs.IsAsync)\n                              {\n                                  await foreach (var x in xxs.AsAsyncEnumerable(env.Token))\n                                  {\n                                      if (!predicate((s, x)))\n                                      {\n                                          return s;\n                                      }\n                                      s = f(s, x);\n                                  }\n                              }\n                              else\n                              {\n                                  foreach (var x in xxs.AsEnumerable(env.Token))\n                                  {\n                                      if (!predicate((s, x)))\n                                      {\n                                          return s;\n                                      }\n                                      s = f(s, x);\n                                  }\n                              }\n                          }\n                          return s;\n                      });\n        \n\n    public override IO<S> FoldUntilIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          foreach (var xxs in Items)\n                          {\n                              if (xxs.IsAsync)\n                              {\n                                  await foreach (var x in xxs.AsAsyncEnumerable(env.Token))\n                                  {\n                                      s = f(x)(s);\n                                      if (predicate((s, x)))\n                                      {\n                                          return s;\n                                      }\n                                  }\n                              }\n                              else\n                              {\n                                  foreach (var x in xxs.AsEnumerable(env.Token))\n                                  {\n                                      s = f(x)(s);\n                                      if (predicate((s, x)))\n                                      {\n                                          return s;\n                                      }\n                                  }\n                              }\n                          }\n                          return s;\n                      });\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          foreach (var xxs in Items)\n                          {\n                              if (xxs.IsAsync)\n                              {\n                                  await foreach (var x in xxs.AsAsyncEnumerable(env.Token))\n                                  {\n                                      s = f(s, x);\n                                      if (predicate((s, x)))\n                                      {\n                                          return s;\n                                      }\n                                  }\n                              }\n                              else\n                              {\n                                  foreach (var x in xxs.AsEnumerable(env.Token))\n                                  {\n                                      s = f(s, x);\n                                      if (predicate((s, x)))\n                                      {\n                                          return s;\n                                      }\n                                  }\n                              }\n                          }\n                          return s;\n                      });\n\n    public override Iterable<A> Choose(Iterable<A> rhs) => \n        new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) => \n        new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.Value.As().AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.Enumerable.cs",
    "content": "﻿#pragma warning disable CS1998\nusing System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\nsealed class IterableEnumerable<A>(IO<IEnumerable<A>> runEnumerable) : Iterable<A>\n{\n    internal override bool IsAsync =>\n        false;\n    \n    public override IO<int> CountIO() =>\n        AsEnumerableIO().Map(xs => xs.Count());\n\n    public override IO<IEnumerable<A>> AsEnumerableIO()\n    {\n        // This makes a regular IEnumerable cancellable.\n        return IO.lift(env => go(env, runEnumerable));\n        static IEnumerable<A> go(EnvIO env, IO<IEnumerable<A>> run)\n        {\n            var xs = run.Run(env);\n            foreach (var x in xs)\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n        }\n    }\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO() =>\n        AsEnumerableIO().Map(xs => xs.ToAsyncEnumerable());\n\n    public override Iterable<A> Reverse() =>\n        new IterableEnumerable<A>(AsEnumerableIO().Map(xs => xs.Reverse()));\n\n    public override Iterable<B> Map<B>(Func<A, B> f) =>\n        new IterableEnumerable<B>(AsEnumerableIO().Map(xs => xs.Select(f)));\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        new IterableEnumerable<A>(AsEnumerableIO().Map(xs => xs.Where(f)));\n\n    public override IO<S> FoldWhileIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          var xs = await runEnumerable.RunAsync(env);\n                          foreach (var x in xs)\n                          {\n                              if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                              s = f(x)(s);\n                          }\n                          return s;\n                      });\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          var xs = await runEnumerable.RunAsync(env);\n                          foreach (var x in xs)\n                          {\n                              if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                              s = f(s, x);\n                          }\n                          return s;\n                      });\n\n\n    public override IO<S> FoldUntilIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          var xs = await runEnumerable.RunAsync(env);\n                          foreach (var x in xs)\n                          {\n                              if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                              s = f(x)(s);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n                          return s;\n                      });\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          var xs = await runEnumerable.RunAsync(env);\n                          foreach (var x in xs)\n                          {\n                              if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                              s = f(s, x);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n                          return s;\n                      });\n\n    public override Iterable<A> Choose(Iterable<A> rhs) =>\n        rhs.IsAsync\n            ? new IterableAsyncEnumerable<A>(\n                IO.liftVAsync(async env =>\n                              {\n                                  var ls   = AsAsyncEnumerable(env.Token);\n                                  var iter = ls.GetIteratorAsync();\n                                  if (await iter.IsEmpty)\n                                  {\n                                      return rhs.AsAsyncEnumerable(env.Token);\n                                  }\n                                  else\n                                  {\n                                      // This has already been evaluated by `IsEmpty`\n                                      var head = await iter.Head;\n                                      var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                      return tail.Prepend(head);\n                                  }\n                              }))\n            : new IterableEnumerable<A>(\n                IO.lift(env =>\n                        {\n                            var ls   = AsEnumerable(env.Token);\n                            var iter = ls.GetIterator();\n                            if (iter.IsEmpty)\n                            {\n                                return rhs.AsEnumerable(env.Token);\n                            }\n                            else\n                            {\n                                // This has already been evaluated by `IsEmpty`\n                                var head = iter.Head;\n                                var tail = iter.Tail.Split().AsEnumerable();\n                                return tail.Prepend(head);\n                            }\n                        }));\n\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) =>\n        new IterableAsyncEnumerable<A>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.Value.As().AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.Nil.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace LanguageExt;\n\nsealed class IterableNil<A> : Iterable<A>\n{\n    public static readonly Iterable<A> Default = new IterableNil<A>();\n\n    internal override bool IsAsync =>\n        false;\n\n    public override IO<int> CountIO() =>\n        IO.pure(0);\n\n    public override IO<IEnumerable<A>> AsEnumerableIO() =>\n        IO.pure(Enumerable.Empty<A>());\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO() => \n        IO.pure(AsyncEnumerable.Empty<A>());\n\n    public override Iterable<A> Reverse() =>\n        this;\n\n    public override Iterable<B> Map<B>(Func<A, B> f) => \n        IterableNil<B>.Default;\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        this;\n\n    public override IO<S> FoldWhileIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.pure(initialState);\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.pure(initialState);\n\n    public override IO<S> FoldUntilIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.pure(initialState);\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.pure(initialState);\n\n    public override Iterable<A> Choose(Iterable<A> rhs) =>\n        rhs;\n\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) => \n        rhs.Value.As();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.Singleton.cs",
    "content": "#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously\nusing System;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\nsealed class IterableSingleton<A>(A Value) : Iterable<A>\n{\n    internal override bool IsAsync =>\n        false;\n\n    public override IO<int> CountIO() =>\n        IO.pure(1);\n\n    public override IO<IEnumerable<A>> AsEnumerableIO() =>\n        IO.pure<IEnumerable<A>>([Value]);\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO() =>\n        IO.pure(One(Value));\n\n    static async IAsyncEnumerable<A> One(A value)\n    {\n        yield return value;\n    }\n\n    public override Iterable<A> Reverse() =>\n        this;\n\n    public override Iterable<B> Map<B>(Func<A, B> f) =>\n        new IterableSingleton<B>(f(Value));\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        f(Value) ? this : Empty;\n\n    public override IO<S> FoldWhileIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate,\n                                         S initialState) =>\n        IO.lift(_ => predicate((initialState, Value)) ? f(Value)(initialState) : initialState);\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        IO.lift(_ => predicate((initialState, Value)) ? f(initialState, Value) : initialState);\n\n    public override IO<S> FoldUntilIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate,\n                                         S initialState) =>\n        IO.lift(_ => f(Value)(initialState));\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        IO.lift(_ => f(initialState, Value));\n\n    public override Iterable<A> Choose(Iterable<A> rhs) =>\n        this;\n\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) =>\n        this;\n}\n     \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.SingletonIO.cs",
    "content": "#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace LanguageExt;\n\nsealed class IterableSingletonIO<A>(IO<A> Value) : Iterable<A>\n{\n    internal override bool IsAsync =>\n        false;\n\n    public override IO<int> CountIO() =>\n        IO.pure(1);\n\n    public override IO<IEnumerable<A>> AsEnumerableIO() =>\n        Value.Map(One);\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO() =>\n        Value.Map(OneAsync);\n\n    static IEnumerable<A> One(A value)\n    {\n        yield return value;\n    }\n\n    static async IAsyncEnumerable<A> OneAsync(A value)\n    {\n        yield return value;\n    }\n\n    public override Iterable<A> Reverse() =>\n        this;\n\n    public override Iterable<B> Map<B>(Func<A, B> f) =>\n        new IterableSingletonIO<B>(Value.Map(f));\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        new IterableEnumerable<A>(AsEnumerableIO().Map(xs => xs.Where(f)));\n\n    public override IO<S> FoldWhileIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        Value.Map(x => predicate((initialState, x)) ? f(x)(initialState) : initialState);\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        Value.Map(x => predicate((initialState, x)) ? f(initialState, x) : initialState);\n\n    public override IO<S> FoldUntilIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        Value.Map(x => f(x)(initialState));\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) =>\n        Value.Map(x => f(initialState, x));\n\n    public override Iterable<A> Choose(Iterable<A> rhs) =>\n        this;\n\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) =>\n        this;\n}\n     \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.Strict.cs",
    "content": "#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\nsealed class IterableStrict<A>(SeqStrict<A> Items) : Iterable<A>\n{\n    internal override bool IsAsync =>\n        false;\n    \n    public override IO<int> CountIO() =>\n        IO.pure(Items.Count);\n\n    public override Iterable<A> Add(A item) =>\n        new IterableStrict<A>((SeqStrict<A>)Items.Add(item));\n\n    public override Iterable<A> Cons(A item) =>\n        new IterableStrict<A>((SeqStrict<A>)Items.Cons(item));\n\n    public override IO<IEnumerable<A>> AsEnumerableIO()\n    {\n        return IO.lift(go);\n        IEnumerable<A> go(EnvIO env)\n        {\n            foreach (var x in Items)\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n        }\n    }\n\n    public override IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO()\n    {\n        return IO.lift(go);\n        async IAsyncEnumerable<A> go(EnvIO env)\n        {\n            foreach (var x in Items)\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                yield return x;\n            }\n        }\n    }\n\n    public override Iterable<A> Reverse() =>\n        new IterableStrict<A>(Items.Rev());\n\n    public override Iterable<B> Map<B>(Func<A, B> f) =>\n        new IterableStrict<B>(Items.Map(f));\n\n    public override Iterable<A> Filter(Func<A, bool> f) =>\n        new IterableStrict<A>(Items.Filter(f));\n\n    public override IO<S> FoldWhileIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          foreach (var x in Items)\n                          {\n                              if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                              s = f(x)(s);\n                          }\n                          return s;\n                      });\n\n    public override IO<S> FoldWhileIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          foreach (var x in Items)\n                          {\n                              if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                              if (!predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                              s = f(s, x);\n                          }\n                          return s;\n                      });\n\n\n    public override IO<S> FoldUntilIO<S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          foreach (var x in Items)\n                          {\n                              if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                              s = f(x)(s);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n                          return s;\n                      });\n\n    public override IO<S> FoldUntilIO<S>(Func<S, A, S> f, Func<(S State, A Value), bool> predicate, S initialState) => \n        IO.liftVAsync(async env =>\n                      {\n                          var s  = initialState;\n                          foreach (var x in Items)\n                          {\n                              if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                              s = f(s, x);\n                              if (predicate((s, x)))\n                              {\n                                  return s;\n                              }\n                          }\n                          return s;\n                      });\n\n    public override Iterable<A> Choose(Iterable<A> rhs) => \n        Items.IsEmpty\n            ? rhs\n            : this;\n\n    public override Iterable<A> Choose(Memo<Iterable, A> rhs) => \n        Items.IsEmpty\n            ? rhs.Value.As()\n            : this;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/DSL/Iterable.Zip.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace LanguageExt;\n\nsealed class IterableZip<A, B>(Iterable<A> First, Iterable<B> Second) : Iterable<(A First, B Second)>\n{\n    internal override bool IsAsync =>\n        First.IsAsync || Second.IsAsync;\n\n    public override IO<int> CountIO() =>\n        IsAsync\n            ? IO.liftVAsync(async env => await (await AsAsyncEnumerableIO().RunAsync(env)).CountAsync(env.Token))\n            : IO.lift(env => AsEnumerableIO().Run(env).Count());\n\n    public override IO<IEnumerable<(A First, B Second)>> AsEnumerableIO()\n    {\n        return IO.lift(e => go(e, First, Second));\n\n        static IEnumerable<(A, B)> go(EnvIO env, Iterable<A> fst, Iterable<B> snd)\n        {\n            using var iterA = fst.AsEnumerable(env.Token).GetEnumerator();\n            using var iterB = snd.AsEnumerable(env.Token).GetEnumerator();\n\n            while (iterA.MoveNext() && iterB.MoveNext())\n            {\n                yield return (iterA.Current, iterB.Current);\n            }\n        }\n    }\n\n    public override IO<IAsyncEnumerable<(A First, B Second)>> AsAsyncEnumerableIO()\n    {\n        return (First.IsAsync, Second.IsAsync) switch\n               {\n                   (true, true)   => IO.lift(e => AsyncAsync(e, First, Second)),\n                   (true, false)  => IO.lift(e => AsyncSync(e, First, Second)),\n                   (false, true)  => IO.lift(e => SyncAsync(e, First, Second)),\n                   (false, false) => IO.lift(e => SyncSync(e, First, Second).ToAsyncEnumerable()),\n               };\n\n        static async IAsyncEnumerable<(A, B)> AsyncAsync(EnvIO env, Iterable<A> fst, Iterable<B> snd)\n        {\n            var iterA = fst.AsAsyncEnumerable(env.Token).GetAsyncEnumerator(env.Token);\n            var iterB = snd.AsAsyncEnumerable(env.Token).GetAsyncEnumerator(env.Token);\n\n            while (await iterA.MoveNextAsync() && await iterB.MoveNextAsync())\n            {\n                yield return (iterA.Current, iterB.Current);\n            }\n        }\n\n        static async IAsyncEnumerable<(A, B)> AsyncSync(EnvIO env, Iterable<A> fst, Iterable<B> snd)\n        {\n            var       iterA = fst.AsAsyncEnumerable(env.Token).GetAsyncEnumerator(env.Token);\n            using var iterB = snd.AsEnumerable(env.Token).GetEnumerator();\n\n            while (await iterA.MoveNextAsync() && iterB.MoveNext())\n            {\n                yield return (iterA.Current, iterB.Current);\n            }\n        }        \n\n        static async IAsyncEnumerable<(A, B)> SyncAsync(EnvIO env, Iterable<A> fst, Iterable<B> snd)\n        {\n            using var iterA = fst.AsEnumerable(env.Token).GetEnumerator();\n            var       iterB = snd.AsAsyncEnumerable(env.Token).GetAsyncEnumerator(env.Token);\n\n            while (iterA.MoveNext() && await iterB.MoveNextAsync())\n            {\n                yield return (iterA.Current, iterB.Current);\n            }\n        }\n\n        static IEnumerable<(A, B)> SyncSync(EnvIO env, Iterable<A> fst, Iterable<B> snd)\n        {\n            using var iterA = fst.AsEnumerable(env.Token).GetEnumerator();\n            using var iterB = snd.AsEnumerable(env.Token).GetEnumerator();\n\n            while (iterA.MoveNext() && iterB.MoveNext())\n            {\n                yield return (iterA.Current, iterB.Current);\n            }\n        }\n    }\n\n    public override Iterable<(A First, B Second)> Reverse() =>\n        Make().Reverse();\n\n    public override Iterable<C> Map<C>(Func<(A First, B Second), C> f) => \n        Make().Map(f);\n\n    public override Iterable<(A First, B Second)> Filter(Func<(A First, B Second), bool> f) => \n        Make().Filter(f);\n\n    public override IO<S> FoldWhileIO<S>(Func<(A First, B Second), Func<S, S>> f, Func<(S State, (A First, B Second) Value), bool> predicate, S initialState) => \n        Make().FoldWhileIO(f, predicate, initialState);\n\n    public override IO<S> FoldWhileIO<S>(Func<S, (A First, B Second), S> f, Func<(S State, (A First, B Second) Value), bool> predicate, S initialState) => \n        Make().FoldWhileIO(f, predicate, initialState);\n\n    public override IO<S> FoldUntilIO<S>(Func<(A First, B Second), Func<S, S>> f, Func<(S State, (A First, B Second) Value), bool> predicate, S initialState) => \n        Make().FoldUntilIO(f, predicate, initialState);\n\n    public override IO<S> FoldUntilIO<S>(Func<S, (A First, B Second), S> f, Func<(S State, (A First, B Second) Value), bool> predicate, S initialState) => \n        Make().FoldUntilIO(f, predicate, initialState);\n    \n    public override Iterable<(A First, B Second)> Choose(Iterable<(A First, B Second)> rhs) =>\n        new IterableAsyncEnumerable<(A First, B Second)>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n\n    public override Iterable<(A First, B Second)> Choose(Memo<Iterable, (A First, B Second)> rhs) => \n        new IterableAsyncEnumerable<(A First, B Second)>(\n            IO.liftVAsync(async env =>\n                          {\n                              var ls   = AsAsyncEnumerable(env.Token);\n                              var iter = ls.GetIteratorAsync();\n                              if (await iter.IsEmpty)\n                              {\n                                  return rhs.Value.As().AsAsyncEnumerable(env.Token);\n                              }\n                              else\n                              {\n                                  // This has already been evaluated by `IsEmpty`\n                                  var head = await iter.Head;\n                                  var tail = (await iter.Tail).Split().AsEnumerable(env.Token);\n                                  return tail.Prepend(head);\n                              }\n                          }));\n\n    Iterable<(A First, B Second)> Make() =>\n        IsAsync\n            ? new IterableAsyncEnumerable<(A First, B Second)>(AsAsyncEnumerableIO())\n            : new IterableEnumerable<(A First, B Second)>(AsEnumerableIO());\n    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/Extensions/Iterable.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IterableExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Iterable<B> Map<A, B>(this Func<A, B> f, K<Iterable, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Iterable<B> Map<A, B>(this Func<A, B> f, Iterable<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Iterable<B> Action<A, B>(this K<Iterable, A> ma, K<Iterable, B> mb) =>\n        Applicative.action(ma, mb).As();    \n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Iterable<B> Action<A, B>(this Iterable<A> ma, K<Iterable, B> mb) =>\n        Applicative.action(ma, mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Iterable<B> Apply<A, B>(this Iterable<Func<A, B>> mf, K<Iterable, A> ma) =>\n        Applicative.apply(mf, ma).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Iterable<B> Apply<A, B>(this K<Iterable, Func<A, B>> mf, K<Iterable, A> ma) =>\n        Applicative.apply(mf, ma).As();    \n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/Extensions/Iterable.Extensions.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing System;\nusing System.Collections.Generic;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class IterableExtensions\n{\n    public static Iterable<A> As<A>(this K<Iterable, A> xs) =>\n        (Iterable<A>)xs;\n    \n    public static Iterable<A> AsIterable<A>(this IEnumerable<A> xs) =>\n        new IterableEnumerable<A>(IO.pure(xs));\n    \n    public static Iterable<A> AsIterable<A>(this IAsyncEnumerable<A> xs) =>\n        new IterableAsyncEnumerable<A>(IO.pure(xs));\n\n    public static Iterable<A> Flatten<A>(this Iterable<Iterable<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <param name=\"list\">sequence</param>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    extension<A>(Iterable<A> list)\n    {\n        /// <summary>\n        /// Applies the given function 'selector' to each element of the sequence. Returns the sequence \n        /// comprised of the results for each element where the function returns Some(f(x)).\n        /// </summary>\n        /// <param name=\"selector\">Selector function</param>\n        /// <returns>Mapped and filtered sequence</returns>\n        [Pure]\n        public Iterable<B> Choose<B>(Func<A, Option<B>> selector) =>\n            Iterable.choose(list, selector);\n\n        [Pure]\n        public Iterable<A> Rev() =>\n            Iterable.rev(list);\n    }\n\n    /// <param name=\"list\">sequence</param>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    extension<A>(Iterable<A> list)\n        where A : Monoid<A>\n    {\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        public A Fold() =>\n            list.FoldIO().Run();\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        public IO<A> FoldIO() =>\n            list.FoldMapIO(identity); \n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        public A FoldWhile(Func<(A State, A Value), bool> predicate) =>\n            list.FoldWhileIO(predicate).Run();\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        public IO<A> FoldWhileIO(Func<(A State, A Value), bool> predicate) =>\n            list.FoldMapWhileIO(identity, predicate);\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        public A FoldUntil(Func<(A State, A Value), bool> predicate) =>\n            list.FoldUntilIO(predicate).Run();\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use 'foldMap'' instead, with 'id' as the map.\n        /// </summary>\n        public IO<A> FoldUntilIO(Func<(A State, A Value), bool> predicate) =>\n            list.FoldMapUntilIO(identity, predicate);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/Iterable.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Cons sequence module\n/// Represents a sequence of values in a similar way to IEnumerable, but without the\n/// issues of multiple evaluation for key LINQ operators like Skip, Count, etc.\n/// </summary>\n/// <typeparam name=\"A\">Type of the values in the sequence</typeparam>\npublic partial class Iterable\n{\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> flatten<A>(Iterable<Iterable<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Create an empty sequence\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> empty<A>() =>\n        Iterable<A>.Empty;\n\n    /// <summary>\n    /// Create an empty sequence\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> singleton<A>(A value) =>\n        new IterableSingleton<A>(value);\n\n    /// <summary>\n    /// Create a new empty sequence\n    /// </summary>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> create<A>() =>\n        Iterable<A>.Empty;\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> create<A>(params A[] items)\n    {\n        if (items.Length == 0) return Iterable<A>.Empty;\n        var nitems = new A[items.Length];\n        System.Array.Copy(items, nitems, items.Length);\n        return Iterable<A>.FromSpan(items);\n    }\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> createRange<A>(ReadOnlySpan<A> items) =>\n        items.Length == 0 ? Iterable<A>.Empty : Iterable<A>.FromSpan(items);\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> createRange<A>(IEnumerable<A> items) =>\n        new IterableEnumerable<A>(IO.pure(items));\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> createRange<A>(IAsyncEnumerable<A> items) =>\n        new IterableAsyncEnumerable<A>(IO.pure(items));\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> createRange<A>(IO<IAsyncEnumerable<A>> items) =>\n        new IterableAsyncEnumerable<A>(items);\n\n    /// <summary>\n    /// Generates a sequence of A using the provided delegate to initialise\n    /// each item.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> generate<A>(int count, Func<int, A> generator) =>\n        IterableExtensions.AsIterable(Range(0, count)).Map(generator);\n\n    /// <summary>\n    /// Generates a sequence that contains one repeated value.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> repeat<A>(A item, int count) =>\n        IterableExtensions.AsIterable(Range(0, count)).Map(_ => item);\n\n    /// <summary>\n    /// Get the item at the head (first) of the sequence or None if the sequence is empty\n    /// </summary>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>Optional head item</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> head<A>(Iterable<A> list) =>\n        list.Head;\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the sequence. Returns the sequence \n    /// of results for each element where the function returns Some(f(x)).\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<B> choose<A, B>(Iterable<A> list, Func<A, Option<B>> selector) =>\n        list.Map(selector).Filter(t => t.IsSome).Map(t => t.Value!);\n\n    /// <summary>\n    /// Reverses the sequence (Reverse in LINQ)\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence to reverse</param>\n    /// <returns>Reversed sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> rev<A>(Iterable<A> list) =>\n        list.Reverse();\n\n    /// <summary>\n    /// Joins two sequences together either into a single sequence using the join \n    /// function provided\n    /// </summary>\n    /// <param name=\"list\">First sequence to join</param>\n    /// <param name=\"other\">Second sequence to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<C> zip<A, B, C>(Iterable<A> list, Iterable<B> other, Func<A, B, C> zipper) =>\n        list.Zip(other, zipper);\n\n    /// <summary>\n    /// Joins two sequences together either into an sequence of tuples\n    /// </summary>\n    /// <param name=\"list\">First sequence to join</param>\n    /// <param name=\"other\">Second sequence to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined sequence of tuples</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<(A First, B Second)> zip<A, B>(Iterable<A> list, Iterable<B> other) =>\n        list.Zip(other, (t, u) => (t, u));\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> distinct<A>(Iterable<A> list) =>\n        list.Distinct();\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> distinct<EqA, A>(Iterable<A> list) where EqA : Eq<A> =>\n        list.Distinct<EqA>();\n\n    /// <summary>\n    /// Returns a new sequence with the first 'count' items from the sequence provided\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first 'count' items from the sequence provided</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> take<A>(Iterable<A> list, int count) =>\n        list.Take(count);\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first items that match the predicate</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> takeWhile<A>(Iterable<A> list, Func<A, bool> pred) =>\n        list.TakeWhile(pred);\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't.  An index value is also provided to the predicate function.\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first items that match the predicate</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> takeWhile<A>(Iterable<A> list, Func<A, int, bool> pred) =>\n        list.TakeWhile(pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/Iterable.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Lazy sequence\n/// </summary>\n/// <remarks>\n/// This is a lightweight wrapper around `IEnumerable` that also implements traits\n/// that make it play nice with other types in this library: Monad, Traversable, etc. \n/// </remarks>\n/// <typeparam name=\"A\">Type of the values in the sequence</typeparam>\n[CollectionBuilder(typeof(Iterable), nameof(Iterable.createRange))]\npublic abstract class Iterable<A> :\n    IEnumerable<A>,\n    IAsyncEnumerable<A>,\n    Monoid<Iterable<A>>,\n    IComparable<Iterable<A>>,\n    IAdditiveIdentity<Iterable<A>, Iterable<A>>,\n    IComparisonOperators<Iterable<A>, Iterable<A>, bool>,\n    IAdditionOperators<Iterable<A>, Iterable<A>, Iterable<A>>,\n    K<Iterable, A>\n{\n    int? hashCode;\n\n    /// <summary>\n    /// True if this iterable or any component part of the structure has asynchonicity.  \n    /// </summary>\n    internal abstract bool IsAsync { get; }\n\n    /// <summary>\n    /// Create an iterable from a span\n    /// </summary>\n    public static Iterable<A> FromSpan(ReadOnlySpan<A> ma) =>\n        new IterableEnumerable<A>(IO.pure<IEnumerable<A>>(ma.ToArray()));\n\n    /// <summary>\n    /// Number of items in the sequence.\n    /// </summary>\n    /// <remarks>\n    /// NOTE: This will force evaluation of the sequence\n    /// </remarks>\n    [Pure]\n    public int Count() =>\n        CountIO().Run();\n\n    /// <summary>\n    /// Number of items in the sequence.\n    /// </summary>\n    [Pure]\n    public abstract IO<int> CountIO();\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public IEnumerable<A> AsEnumerable(CancellationToken token = default)\n    {\n        using var env = EnvIO.New(token: token);\n        var       xs  = AsEnumerableIO().Run();\n        foreach (var x in xs)\n        {\n            if(env.Token.IsCancellationRequested) throw new OperationCanceledException();\n            yield return x;\n        }\n    }\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public abstract IO<IEnumerable<A>> AsEnumerableIO();\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public async IAsyncEnumerable<A> AsAsyncEnumerable([EnumeratorCancellation] CancellationToken token = default)\n    {\n        using var env = EnvIO.New(token: token);\n        var xs = await AsAsyncEnumerableIO().RunAsync(env);\n        await foreach (var x in xs.WithCancellation(token))\n        {\n            yield return x;\n        }\n    }\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public abstract IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO();\n\n    /// <summary>\n    /// Reverse the sequence\n    /// </summary>\n    [Pure]\n    public abstract Iterable<A> Reverse();\n\n    /// <summary>\n    /// Add an item to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// This does not force evaluation of the whole lazy sequence, nor does it cause\n    /// exponential iteration issues when repeated adds occur.\n    /// </remarks>\n    [Pure]\n    public virtual Iterable<A> Add(A item) =>\n        new IterableAdd<A>(\n            new SeqStrict<A>(new A[8], 8, 0, 0, 0),\n            this,\n            new SeqStrict<A>([item, default!, default!, default!, default!, default!, default!, default!], 0, 1, 0, 0)); \n\n    /// <summary>\n    /// Add an item to the beginning of the sequence\n    /// </summary>\n    /// <remarks>\n    /// This does not force evaluation of the whole lazy sequence, nor does it cause\n    /// exponential iteration issues when repeated cons occur.\n    /// </remarks>\n    [Pure]\n    public virtual Iterable<A> Cons(A item) =>\n        new IterableAdd<A>(\n            new SeqStrict<A>([default!, default!, default!, default!, default!, default!, default!, item], 7, 1, 0, 0),\n            this,\n            new SeqStrict<A>(new A[8], 0, 0, 0, 0));\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Unit Iter(Action<A> f) =>\n        IterIO(f).Run();\n\n    /// <summary>\n    /// Pure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [Pure]\n    public IO<Unit> IterIO(Action<A> f) =>\n        IsAsync\n            ? IO.liftVAsync(async env =>\n                            {\n                                await foreach (var x in AsAsyncEnumerable(env.Token))\n                                {\n                                    f(x);\n                                }\n                                return unit;\n                            })\n            : IO.lift(env =>\n                      {\n                          foreach (var x in AsEnumerable(env.Token))\n                          {\n                              f(x);\n                          }\n                          return unit;\n                      });\n\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Unit Iter(Action<A, int> f) =>\n        IterIO(f).Run();\n\n    /// <summary>\n    /// Pure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [Pure]\n    public IO<Unit> IterIO(Action<A, int> f, int offset = 0) =>\n        IsAsync\n            ? IO.liftVAsync(async env =>\n                            {\n                                var ix = offset;\n                                await foreach (var x in AsAsyncEnumerable(env.Token))\n                                {\n                                    f(x, ix++);\n                                }\n\n                                return unit;\n                            })\n            : IO.lift(env =>\n                      {\n                          var ix = offset;\n                          foreach (var x in AsEnumerable(env.Token))\n                          {\n                              f(x, ix++);\n                          }\n\n                          return unit;\n                      });\n    \n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public abstract Iterable<B> Map<B>(Func<A, B> f);\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public Iterable<B> Map<B>(Func<A, int, B> f, int offset = 0) =>\n        Zip(Iterable.createRange(Enumerable.InfiniteSequence(offset, 1)))\n           .Map(p => f(p.First, p.Second));\n\n    /// <summary>\n    /// Filter the items in the sequence\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply to the items</param>\n    /// <returns>Filtered sequence</returns>\n    [Pure]\n    public abstract Iterable<A> Filter(Func<A, bool> f);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public IO<bool> EqualsIO<EqA>(Iterable<A>? other) \n        where EqA : Eq<A> =>\n        other is null\n            ? IO.pure(false)\n            : ReferenceEquals(this, other)\n                  ? IO.pure(true)\n                  : (IsAsync, IsAsync) switch\n                    {\n                        (true, true)   => IO.liftVAsync(async env => await AsAsyncEnumerable(env.Token).SequenceEqualAsync(other.AsAsyncEnumerable(env.Token), Eq.Comparer<EqA, A>())),\n                        (true, false)  => IO.liftVAsync(async env => await AsAsyncEnumerable(env.Token).SequenceEqualAsync(other.AsAsyncEnumerable(env.Token), Eq.Comparer<EqA, A>())),\n                        (false, true)  => IO.liftVAsync(async env => await AsAsyncEnumerable(env.Token).SequenceEqualAsync(other.AsAsyncEnumerable(env.Token), Eq.Comparer<EqA, A>())),\n                        (false, false) => IO.lift(env => AsEnumerable(env.Token).SequenceEqual(other.AsEnumerable(env.Token), Eq.Comparer<EqA, A>()))\n                    };\n    \n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public IO<bool> EqualsIO(Iterable<A>? other) =>\n        EqualsIO<EqDefault<A>>(other);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public bool Equals<EqA>(Iterable<A>? other)\n        where EqA : Eq<A> =>\n        EqualsIO<EqA>(other).Run();\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public bool Equals(Iterable<A>? other) =>\n        EqualsIO<EqDefault<A>>(other).Run();\n\n    [Pure]\n    public IAsyncEnumerator<A> GetAsyncEnumerator(CancellationToken cancellationToken = default) => \n        AsAsyncEnumerable(cancellationToken).GetAsyncEnumerator(cancellationToken);\n\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is Iterable<A> rhs && Equals(rhs);\n\n    [Pure]\n    public static bool operator ==(Iterable<A>? lhs, Iterable<A>? rhs) =>\n        (lhs, rhs) switch\n        {\n            (null, null) => true,\n            (null, _)    => false,\n            (_, null)    => false,\n            _            => lhs.Equals(rhs)\n        };\n\n    [Pure]\n    public static bool operator !=(Iterable<A>? lhs, Iterable<A>? rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Semigroup combine two iterables (concatenate)\n    /// </summary>\n    [Pure]\n    public Iterable<A> Combine(Iterable<A> y) =>\n        Concat(y);\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    [Pure]\n    public Iterable<A> Concat(IEnumerable<A> items) =>\n        Concat(new IterableEnumerable<A>(IO.pure(items)));\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    [Pure]\n    public Iterable<A> Concat(IAsyncEnumerable<A> items) =>\n        Concat(new IterableAsyncEnumerable<A>(IO.pure(items)));\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    [Pure]\n    public Iterable<A> Concat(Iterable<A> items) =>\n        (this, items) switch\n        {\n            (IterableConcat<A> l, IterableConcat<A> r) => new IterableConcat<A>(l.Items + r.Items),\n            (IterableConcat<A> l, var r)               => new IterableConcat<A>(l.Items.Add(r)),\n            (var l, IterableConcat<A> r)               => new IterableConcat<A>(l.Cons(r.Items)),\n            var (l, r)                                 => new IterableConcat<A>(Seq(l, r))\n        };\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    public Iterable<A> Distinct<EqA>()\n        where EqA : Eq<A> =>\n        IsAsync\n            ? new IterableAsyncEnumerable<A>(AsAsyncEnumerableIO().Map(xs => xs.Distinct(Eq.Comparer<EqA, A>())))\n            : new IterableEnumerable<A>(AsEnumerableIO().Map(xs => xs.Distinct(Eq.Comparer<EqA, A>())));\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    public Iterable<A> Distinct() =>\n        Distinct<EqDefault<A>>();\n\n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <remarks>\n    /// NOTE: This method will eagerly evaluate the iterable. If you're working with\n    /// an asynchronous sequence, then it is advised to use `TraverseIO`.\n    /// </remarks>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Iterable<B>> Traverse<F, B>(Func<A, K<F, B>> f)\n        where F : Applicative<F>\n    {\n        return FoldIO(add, F.Pure(Iterable<B>.Empty)).Run();\n        Func<K<F, Iterable<B>>, K<F, Iterable<B>>> add(A value) =>\n            state =>\n                Applicative.lift((bs, b) => bs.Add(b), state, f(value));                                            \n        \n    }\n\n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <remarks>\n    /// NOTE: This method will eagerly evaluate the iterable. If you're working with\n    /// an asynchronous sequence, then it is advised to use `TraverseIO`.\n    /// </remarks>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, Iterable<B>> TraverseM<M, B>(Func<A, K<M, B>> f)\n        where M : Monad<M>\n    {\n        return FoldIO(add, M.Pure(Iterable<B>.Empty)).Run();\n\n        Func<K<M, Iterable<B>>, K<M, Iterable<B>>> add(A value) =>\n            state => state.Bind(bs => f(value).Map(bs.Add)); \n    }    \n\n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Iterable<B>> TraverseIO<F, B>(Func<A, K<F, B>> f, K<Iterable, A> kta) \n        where F : MonadIO<F>\n    {\n        var ta = +kta;\n        return F.LiftIO(ta.FoldIO(add, F.Pure(Iterable<B>.Empty))).Flatten();\n\n        Func<K<F, Iterable<B>>, K<F, Iterable<B>>> add(A value) =>\n            state =>\n                state.Bind(\n                    bs => f(value).Bind(\n                        b => F.Pure(bs.Add(b)))); \n    }\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Iterable<B> Bind<B>(Func<A, K<Iterable, B>> f)\n    {\n        return IsAsync\n                   ? new IterableAsyncEnumerable<B>(IO.lift(async))\n                   : new IterableAsyncEnumerable<B>(IO.lift(sync));\n\n        async IAsyncEnumerable<B> async(EnvIO env)\n        {\n            await foreach (var a in AsAsyncEnumerable(env.Token))\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                var mb = +f(a);\n                if (mb.IsAsync)\n                {\n                    await foreach (var b in mb.AsAsyncEnumerable(env.Token))\n                    {\n                        if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                        yield return b;\n                    }\n                }\n                else\n                {\n                    foreach (var b in mb.AsEnumerable(env.Token))\n                    {\n                        if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                        yield return b;\n                    }\n                }\n            }\n        }\n        async IAsyncEnumerable<B> sync(EnvIO env)\n        {\n            foreach (var a in AsEnumerable(env.Token))\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                var mb = +f(a);\n                if (mb.IsAsync)\n                {\n                    await foreach (var b in mb.AsAsyncEnumerable(env.Token))\n                    {\n                        if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                        yield return b;\n                    }\n                }\n                else\n                {\n                    foreach (var b in mb.AsEnumerable(env.Token))\n                    {\n                        if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                        yield return b;\n                    }\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Iterable<B> Bind<B>(Func<A, Iterable<B>> f)\n    {\n        return IsAsync\n                   ? new IterableAsyncEnumerable<B>(IO.lift(async))\n                   : new IterableAsyncEnumerable<B>(IO.lift(sync));\n\n        async IAsyncEnumerable<B> async(EnvIO env)\n        {\n            await foreach (var a in AsAsyncEnumerable(env.Token))\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                var mb = f(a);\n                if (mb.IsAsync)\n                {\n                    await foreach (var b in mb.AsAsyncEnumerable(env.Token))\n                    {\n                        if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                        yield return b;\n                    }\n                }\n                else\n                {\n                    foreach (var b in mb.AsEnumerable(env.Token))\n                    {\n                        if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                        yield return b;\n                    }\n                }\n            }\n        }\n\n        async IAsyncEnumerable<B> sync(EnvIO env)\n        {\n            foreach (var a in AsEnumerable(env.Token))\n            {\n                if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                var mb = f(a);\n                if (mb.IsAsync)\n                {\n                    await foreach (var b in mb.AsAsyncEnumerable(env.Token))\n                    {\n                        if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                        yield return b;\n                    }\n                }\n                else\n                {\n                    foreach (var b in mb.AsEnumerable(env.Token))\n                    {\n                        if (env.Token.IsCancellationRequested) throw new OperationCanceledException();\n                        yield return b;\n                    }\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public S FoldWhile<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        FoldWhileIO(f, predicate, initialState).Run();\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public S FoldWhile<S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        FoldWhileIO(f, predicate, initialState).Run();\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public abstract IO<S> FoldWhileIO<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState);\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public abstract IO<S> FoldWhileIO<S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState);\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public S FoldUntil<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        FoldUntilIO(f, predicate, initialState).Run();\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public S FoldUntil<S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        FoldUntilIO(f, predicate, initialState).Run();\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public abstract IO<S> FoldUntilIO<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState);\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public abstract IO<S> FoldUntilIO<S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState);\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public S FoldMaybe<S>(\n        Func<S, Func<A, Option<S>>> f,\n        S initialState) =>\n        FoldMaybeIO(f, initialState).Run();\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public S FoldMaybe<S>(\n        Func<S, A, Option<S>> f,\n        S initialState) =>\n        FoldMaybeIO(f, initialState).Run();\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public IO<S> FoldMaybeIO<S>(\n        Func<S, Func<A, Option<S>>> f,\n        S initialState) =>\n        FoldWhileIO<(bool IsSome, S Value)>(\n                a => s => f(s.Value)(a) switch\n                          {\n                              { IsSome: true, Case: S value } => (true, value),\n                              _                               => (false, s.Value)\n                          },\n                s => s.State.IsSome,\n                (true, initialState))\n           .Map(s => s.Value);\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public IO<S> FoldMaybeIO<S>(\n        Func<S, A, Option<S>> f,\n        S initialState) =>\n        FoldWhileIO<(bool IsSome, S Value)>(\n                (s, a) => f(s.Value, a) switch\n                          {\n                              { IsSome: true, Case: S value } => (true, value),\n                              _                               => (false, s.Value)\n                          },\n                s => s.State.IsSome,\n                (true, initialState))\n           .Map(s => s.Value);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public K<M, S> FoldWhileM<M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<A, bool> predicate, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldWhileIO(acc, s => predicate(s.Value), Monad.pure<M, S>)\n                  .Bind(f1 => f1(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(value)(state), bind);\n    }\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public K<M, S> FoldWhileM<M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<A, bool> predicate, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldWhileIO(acc, s => predicate(s.Value), Monad.pure<M, S>)\n           .Bind(f1 => f1(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(state, value), bind);\n    }\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public K<M, S> FoldUntilM<M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<A, bool> predicate, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldUntilIO(acc, s => predicate(s.Value), Monad.pure<M, S>).Bind(f1 => f1(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(value)(state), bind);\n    }\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public K<M, S> FoldUntilM<M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<A, bool> predicate, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldUntilIO(acc, s => predicate(s.Value), Monad.pure<M, S>).Bind(f1 => f1(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(state, value), bind);\n    }\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public S Fold<S>(Func<A, Func<S, S>> f, S initialState) =>\n        FoldIO(f, initialState).Run();\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public S Fold<S>(Func<S, A, S> f, S initialState) =>\n        FoldIO(f, initialState).Run();\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public IO<S> FoldIO<S>(Func<A, Func<S, S>> f, S initialState) =>\n        FoldWhileIO(f, _ => true, initialState);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public IO<S> FoldIO<S>(Func<S, A, S> f, S initialState) =>\n        FoldWhileIO(f, _ => true, initialState);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public K<M, S> FoldM<M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldIO(acc, Monad.pure<M, S>).Bind(f => f(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(value)(state), bind);\n    }\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public K<M, S> FoldM<M, S>(\n        Func<S, A, K<M, S>> f, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldIO(acc, Monad.pure<M, S>).Bind(f => f(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(state, value), bind);\n    }\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public B FoldMap<B>(Func<A, B> f)\n        where B : Monoid<B> =>\n        FoldMapIO(f).Run();\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public IO<B> FoldMapIO<B>(Func<A, B> f)\n        where B : Monoid<B> =>\n        FoldIO(x => a => f(x).Combine(a), B.Empty);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public B FoldMapWhile<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where B : Monoid<B> =>\n        FoldMapWhileIO(f, predicate).Run();\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public IO<B> FoldMapWhileIO<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where B : Monoid<B> =>\n        FoldWhileIO(x => a => f(x).Combine(a), predicate, B.Empty);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public B FoldMapUntil<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where B : Monoid<B> =>\n        FoldMapUntilIO(f, predicate).Run();\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public IO<B> FoldMapUntilIO<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where B : Monoid<B> =>\n        FoldUntilIO(x => a => f(x).Combine(a), predicate, B.Empty);\n    \n    /// <summary>\n    /// Returns true if the sequence has items in it\n    /// </summary>\n    /// <returns>True if the sequence has items in it</returns>\n    [Pure]\n    public bool Any() =>\n        this.Exists(_ => true);\n\n    /// <summary>\n    /// Inject a value in between each item in the sequence \n    /// </summary>\n    /// <param name=\"ma\">Sequence to inject values into</param>\n    /// <param name=\"value\">Item to inject</param>\n    /// <typeparam name=\"A\">Bound type</typeparam>\n    /// <returns>A sequence with the values injected</returns>\n    [Pure]\n    public Iterable<A> Intersperse(A value)\n    {\n        return IsAsync\n                   ? new IterableAsyncEnumerable<A>(IO.lift(goAsync))\n                   : new IterableEnumerable<A>(IO.lift(goSync));\n        \n        IEnumerable<A> goSync(EnvIO env)\n        {\n            var isFirst = true;\n            foreach(var item in AsEnumerable(env.Token))\n            {\n                if (!isFirst)\n                {\n                    yield return value;\n                }\n\n                yield return item;\n                isFirst = false;\n            }\n        }\n        \n        async IAsyncEnumerable<A> goAsync(EnvIO env)\n        {\n            {\n                var isFirst = true;\n                await foreach(var item in AsAsyncEnumerable(env.Token))\n                {\n                    if (!isFirst)\n                    {\n                        yield return value;\n                    }\n\n                    yield return item;\n                    isFirst = false;\n                }\n            }\n        }\n    }\n\n    [Pure]\n    public IO<int> CompareToIO(object? obj) =>\n        obj is Iterable<A> rhs\n            ? CompareToIO(rhs)\n            : IO.pure(1);\n\n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj is Iterable<A> rhs\n            ? CompareTo(rhs)\n            : 1;\n\n    [Pure]\n    public IO<int> CompareToIO(Iterable<A>? other) =>\n        CompareToIO<OrdDefault<A>>(other);\n\n    [Pure]\n    public int CompareTo(Iterable<A>? other) =>\n        CompareTo<OrdDefault<A>>(other);\n\n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public IO<int> CompareToIO<OrdA>(Iterable<A>? rhs) \n        where OrdA : Ord<A>\n    {\n        if (rhs is null) return IO.pure(1);\n\n        return IsAsync || rhs.IsAsync\n                   ? IO.liftVAsync(async env =>\n                                   {\n                                       var iterA = GetAsyncEnumerator(env.Token);\n                                       var iterB = rhs.GetAsyncEnumerator(env.Token);\n                                       while (await iterA.MoveNextAsync())\n                                       {\n                                           if (await iterB.MoveNextAsync())\n                                           {\n                                               var cmp = OrdA.Compare(iterA.Current, iterB.Current);\n                                               if (cmp != 0) return cmp;\n                                           }\n                                           else\n                                           {\n                                               return 1;\n                                           }\n                                       }\n\n                                       if (await iterB.MoveNextAsync())\n                                       {\n                                           return -1;\n                                       }\n\n                                       return 0;\n                                   })\n                   : IO.lift(env =>\n                             {\n                                 using var iterA = AsEnumerable(env.Token).GetEnumerator();\n                                 using var iterB = rhs.AsEnumerable(env.Token).GetEnumerator();\n                                 while (iterA.MoveNext())\n                                 {\n                                     if (iterB.MoveNext())\n                                     {\n                                         var cmp = OrdA.Compare(iterA.Current, iterB.Current);\n                                         if (cmp != 0) return cmp;\n                                     }\n                                     else\n                                     {\n                                         return 1;\n                                     }\n                                 }\n\n                                 if (iterB.MoveNext())\n                                 {\n                                     return -1;\n                                 }\n\n                                 return 0;\n                             });\n    }\n\n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public int CompareTo<OrdA>(Iterable<A>? rhs) \n        where OrdA : Ord<A> =>\n        CompareToIO<OrdA>(rhs).Run();\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        ToStringIO().Run();\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public virtual IO<string> ToStringIO() =>\n        // TODO: Replace with FoldIO\n        AsEnumerableIO().Map(xs => CollectionFormat.ToShortArrayString(xs));\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        ToFullStringIO(separator).Run();\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public virtual IO<string> ToFullStringIO(string separator = \", \") =>\n        // TODO: Replace with FoldIO\n        AsEnumerableIO().Map(xs => CollectionFormat.ToFullString(xs, separator));\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        ToFullArrayStringIO(separator).Run();\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public virtual IO<string> ToFullArrayStringIO(string separator = \", \") =>\n        // TODO: Replace with FoldIO\n        AsEnumerableIO().Map(xs => CollectionFormat.ToFullArrayString(AsEnumerable(), separator));\n\n    /// <summary>\n    /// Tail of the iterable\n    /// </summary>\n    public Iterable<A> Tail =>\n        Skip(1);\n\n    /// <summary>\n    /// Skip count items\n    /// </summary>\n    [Pure]\n    public Iterable<A> Skip(int amount) =>\n        amount < 1\n            ? this\n            : IsAsync\n                ? new IterableEnumerable<A>(AsEnumerableIO().Map(xs => xs.Skip(amount)))\n                : new IterableAsyncEnumerable<A>(AsAsyncEnumerableIO().Map(xs => xs.Skip(amount)));\n\n    /// <summary>\n    /// Take count items\n    /// </summary>\n    [Pure]\n    public Iterable<A> Take(int amount) =>\n        amount < 1\n            ? Empty\n            : IsAsync\n                ? new IterableEnumerable<A>(AsEnumerableIO().Map(xs => xs.Take(amount)))\n                : new IterableAsyncEnumerable<A>(AsAsyncEnumerableIO().Map(xs => xs.Take(amount)));\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate \n    /// provided, and stopping as soon as one doesn't\n    /// </summary>\n    /// <returns>A new sequence with the first items that match the \n    /// predicate</returns>\n    [Pure]\n    public Iterable<A> TakeWhile(Func<A, bool> pred)\n    {\n        return IsAsync\n                   ? new IterableAsyncEnumerable<A>(IO.lift(async))\n                   : new IterableEnumerable<A>(IO.lift(sync));\n            \n        IEnumerable<A> sync(EnvIO env)\n        {\n            foreach (var x in AsEnumerable(env.Token))\n            {\n                if (!pred(x)) break;\n                yield return x;\n            }\n        }\n            \n        async IAsyncEnumerable<A> async(EnvIO env)\n        {\n            await foreach (var x in AsAsyncEnumerable(env.Token))\n            {\n                if (!pred(x)) break;\n                yield return x;\n            }\n        }        \n    }\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate \n    /// provided; and stopping as soon as one doesn't.  An index value is \n    /// also provided to the predicate function.\n    /// </summary>\n    /// <returns>A new sequence with the first items that match the \n    /// predicate</returns>\n    [Pure]\n    public Iterable<A> TakeWhile(Func<A, int, bool> pred)\n    {\n        return IsAsync\n                   ? new IterableAsyncEnumerable<A>(IO.lift(async))\n                   : new IterableEnumerable<A>(IO.lift(sync));\n            \n        IEnumerable<A> sync(EnvIO env)\n        {\n            var ix = 0;\n            foreach (var x in AsEnumerable(env.Token))\n            {\n                if (!pred(x, ix++)) break;\n                yield return x;\n            }\n        }\n            \n        async IAsyncEnumerable<A> async(EnvIO env)\n        {\n            var ix = 0;\n            await foreach (var x in AsAsyncEnumerable(env.Token))\n            {\n                if (!pred(x, ix++)) break;\n                yield return x;\n            }\n        }        \n    }\n\n    /// <summary>\n    /// Partition a list into two based on  a predicate\n    /// </summary>\n    /// <param name=\"predicate\">True if the item goes in the first list, false for the second list</param>\n    /// <returns>Pair of lists</returns>\n    [Pure]\n    public IO<(Iterable<A> First, Iterable<A> Second)> PartitionIO(Func<A, bool> predicate)\n    {\n        return IsAsync\n                   ? IO.liftVAsync(async)\n                   : IO.lift(sync);\n        \n        async ValueTask<(Iterable<A> First, Iterable<A> Second)> async(EnvIO env)\n        {\n            Iterable<A> f = new IterableStrict<A>(SeqStrict<A>.Empty);\n            Iterable<A> s = new IterableStrict<A>(SeqStrict<A>.Empty);\n\n            await foreach (var item in AsAsyncEnumerable(env.Token))\n            {\n                if (predicate(item))\n                {\n                    f = f.Add(item);\n                }\n                else\n                {\n                    s = s.Add(item);\n                }\n            }\n            return (f, s);\n        }\n \n        (Iterable<A> First, Iterable<A> Second) sync(EnvIO env)\n        {\n            Iterable<A> f = new IterableStrict<A>(SeqStrict<A>.Empty);\n            Iterable<A> s = new IterableStrict<A>(SeqStrict<A>.Empty);\n\n            foreach (var item in AsEnumerable(env.Token))\n            {\n                if (predicate(item))\n                {\n                    f = f.Add(item);\n                }\n                else\n                {\n                    s = s.Add(item);\n                }\n            }\n\n            return (f, s);\n        }\n    }\n\n    /// <summary>\n    /// Partition a list into two based on  a predicate\n    /// </summary>\n    /// <param name=\"predicate\">True if the item goes in the first list, false for the second list</param>\n    /// <returns>Pair of lists</returns>\n    [Pure]\n    public (Iterable<A> First, Iterable<A> Second) Partition(Func<A, bool> predicate) =>\n        PartitionIO(predicate).Run();\n    \n    /// <summary>\n    /// Cast items to another type\n    /// </summary>\n    /// <remarks>\n    /// Any item in the sequence that can't be cast to a `B` will be dropped from the result \n    /// </remarks>\n    [Pure]\n    public Iterable<B> Cast<B>() =>\n        new IterableCast<A, B>(this);\n\n    /// <summary>\n    /// Zip two iterables into pairs\n    /// </summary>\n    [Pure]\n    public Iterable<(A First, B Second)> Zip<B>(Iterable<B> rhs) =>\n        new IterableZip<A, B>(this, rhs);\n\n    /// <summary>\n    /// Zip two iterables into pairs\n    /// </summary>\n    [Pure]\n    public Iterable<C> Zip<B, C>(Iterable<B> rhs, Func<A, B, C> zipper) =>\n        Zip(rhs).Map(pair => zipper(pair.First, pair.Second));\n\n\n    /// <summary>\n    /// Empty sequence\n    /// </summary>\n    [Pure]\n    public static Iterable<A> Empty => \n        IterableNil<A>.Default;\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    public static Iterable<A> operator +(Iterable<A> x, Iterable<A> y) =>\n        x.Concat(y);\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    public static Iterable<A> operator +(A x, Iterable<A> y) =>\n        x.Cons(y);\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    public static Iterable<A> operator +(Iterable<A> x, A y) =>\n        x.Add(y);\n\n    /// <summary>\n    /// If this sequence is empty, return the other sequence, otherwise return this sequence.\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side of the operator</param>\n    /// <returns>A choice between two sequences based</returns>\n    [Pure]\n    public abstract Iterable<A> Choose(Iterable<A> rhs);\n\n    /// <summary>\n    /// If this sequence is empty, return the other sequence, otherwise return this sequence.\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side of the operator</param>\n    /// <returns>A choice between two sequences based</returns>\n    [Pure]\n    public abstract Iterable<A> Choose(Memo<Iterable, A> rhs);\n    \n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> operator |(Iterable<A> x, K<Iterable, A> y) =>\n        x.Choose(+y);\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> operator |(K<Iterable, A> x, Iterable<A> y) =>\n        x.As().Choose(y);\n    \n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> operator |(Iterable<A> x, Memo<Iterable, A> y) =>\n        x.Choose(y);\n\n    /// <summary>\n    /// Ordering operator\n    /// </summary>\n    [Pure]\n    public static bool operator >(Iterable<A> x, Iterable<A> y) =>\n        x.CompareTo(y) > 0;\n\n    /// <summary>\n    /// Ordering operator\n    /// </summary>\n    [Pure]\n    public static bool operator >=(Iterable<A> x, Iterable<A> y) =>\n        x.CompareTo(y) >= 0;\n\n    /// <summary>\n    /// Ordering  operator\n    /// </summary>\n    [Pure]\n    public static bool operator <(Iterable<A> x, Iterable<A> y) =>\n        x.CompareTo(y) < 0;\n\n    /// <summary>\n    /// Ordering  operator\n    /// </summary>\n    [Pure]\n    public static bool operator <=(Iterable<A> x, Iterable<A> y) =>\n        x.CompareTo(y) <= 0;\n                \n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    public static implicit operator Iterable<A>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public Iterable<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public Iterable<B> Select<B>(Func<A, int, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Filter the items in the sequence\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply to the items</param>\n    /// <returns>Filtered sequence</returns>\n    [Pure]\n    public Iterable<A> Where(Func<A, bool> f) =>\n        Filter(f);\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"bind\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Iterable<B> SelectMany<B>(Func<A, Iterable<B>> bind) =>\n        Bind(bind);\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"bind\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Iterable<C> SelectMany<B, C>(Func<A, Iterable<B>> bind, Func<A, B, C> project) =>\n        Bind(x  => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"bind\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Iterable<B> SelectMany<B>(Func<A, IEnumerable<B>> bind) =>\n        Bind(x => bind(x).AsIterable());\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"bind\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Iterable<C> SelectMany<B, C>(Func<A, IEnumerable<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).AsIterable().Map(y => project(x, y)));\n\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsEnumerable().GetEnumerator();\n\n    /// <summary>\n    /// Get the hash code for all the items in the sequence, or 0 if empty\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public override int GetHashCode() =>\n        hashCode is null\n            ? (hashCode = hash(AsEnumerable())).Value\n            : hashCode.Value;\n\n    /// <summary>\n    /// Get the additive-identity, i.e. the monoid-zero.  Which is the empty sequence/\n    /// </summary>\n    public static Iterable<A> AdditiveIdentity => \n        Empty;\n    \n    IEnumerator IEnumerable.GetEnumerator() => \n        GetEnumerator();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/Operators/Iterable.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IterableExtensions\n{\n    extension<A>(K<Iterable, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Iterable<A> operator +(K<Iterable, A> ma) =>\n            (Iterable<A>)ma;\n        \n        public static Iterable<A> operator >> (K<Iterable, A> ma, Lower lower) =>\n            (Iterable<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/Prelude/Iterable.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Iterable<B> map<A, B>(Func<A, B> f, K<Iterable, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Iterable<B> action<A, B>(K<Iterable, A> ma, K<Iterable, B> mb) =>\n        Applicative.action(ma, mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Iterable<B> apply<A, B>(K<Iterable, Func<A, B>> mf, K<Iterable, A> ma) =>\n        Applicative.apply(mf, ma).As();    \n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterable/Trait/Iterable.TraitImpl.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class Iterable : \n    Monad<Iterable>, \n    MonoidK<Iterable>,\n    Alternative<Iterable>, \n    Traversable<Iterable>,\n    NaturalEpi<Iterable, Iterable>,\n    NaturalMono<Iterable, Arr>,\n    NaturalMono<Iterable, Seq>,\n    NaturalMono<Iterable, Lst>,\n    NaturalMono<Iterable, Set>,\n    NaturalMono<Iterable, HashSet>\n{\n    static K<Iterable, B> Monad<Iterable>.Recur<A, B>(A value, Func<A, K<Iterable, Next<A, B>>> f) =>\n        Monad.iterableRecur(value, f);\n    \n    static K<Iterable, B> Monad<Iterable>.Bind<A, B>(K<Iterable, A> ma, Func<A, K<Iterable, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<Iterable, B> Functor<Iterable>.Map<A, B>(Func<A, B> f, K<Iterable, A> ma) => \n        ma.As().Map(f);\n\n    static K<Iterable, A> Applicative<Iterable>.Pure<A>(A value) =>\n        singleton(value);\n\n    static K<Iterable, B> Applicative<Iterable>.Apply<A, B>(K<Iterable, Func<A, B>> mf, K<Iterable, A> ma) =>\n        mf >> ma.Map;\n\n    static K<Iterable, B> Applicative<Iterable>.Apply<A, B>(K<Iterable, Func<A, B>> mf, Memo<Iterable, A> ma) =>\n        mf >> ma.Map;\n\n    static K<Iterable, A> MonoidK<Iterable>.Empty<A>() =>\n        Iterable<A>.Empty;\n\n    static K<Iterable, A> Alternative<Iterable>.Empty<A>() => \n        Iterable<A>.Empty;\n    \n    static K<Iterable, A> SemigroupK<Iterable>.Combine<A>(K<Iterable, A> ma, K<Iterable, A> mb) =>\n        ma.As().Concat(+mb);\n\n    static K<Iterable, A> Choice<Iterable>.Choose<A>(K<Iterable, A> ma, K<Iterable, A> mb) =>\n        ma.As().Choose(+mb);\n    \n    static K<Iterable, A> Choice<Iterable>.Choose<A>(K<Iterable, A> ma, Memo<Iterable, A> mb) => \n        ma.As().Choose(mb);\n\n    static K<F, K<Iterable, B>> Traversable<Iterable>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Iterable, A> ta) =>\n        ta.As().Traverse(f).Map(mb => mb.Kind());\n\n    static K<F, K<Iterable, B>> Traversable<Iterable>.TraverseM<F, A, B>(Func<A, K<F, B>> f, K<Iterable, A> ta) => \n        ta.As().TraverseM(f).Map(mb => mb.Kind());\n\n    static S Foldable<Iterable>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Iterable, A> ta) =>\n        ta.As().FoldWhile(f, predicate, state);\n    \n    static S Foldable<Iterable>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S state, \n        K<Iterable, A> ta) =>\n        ta.As().Reverse().FoldWhile((a, s) => f(a)(s), predicate, state);\n    \n    static Arr<A> Foldable<Iterable>.ToArr<A>(K<Iterable, A> ta) =>\n        new(ta.As());\n\n    static Lst<A> Foldable<Iterable>.ToLst<A>(K<Iterable, A> ta) =>\n        new(ta.As());\n\n    static Iterable<A> Foldable<Iterable>.ToIterable<A>(K<Iterable, A> ta) =>\n        ta.As();\n    \n    static Seq<A> Foldable<Iterable>.ToSeq<A>(K<Iterable, A> ta) =>\n        new(ta.As());\n\n    static K<Seq, A> Natural<Iterable, Seq>.Transform<A>(K<Iterable, A> fa) => \n        toSeq(fa.As());\n\n    static K<Arr, A> Natural<Iterable, Arr>.Transform<A>(K<Iterable, A> fa) => \n        toArray(fa.As());\n\n    static K<Lst, A> Natural<Iterable, Lst>.Transform<A>(K<Iterable, A> fa) => \n        toList(fa.As());\n\n    static K<Set, A> Natural<Iterable, Set>.Transform<A>(K<Iterable, A> fa) => \n        toSet(fa.As());\n\n    static K<HashSet, A> Natural<Iterable, HashSet>.Transform<A>(K<Iterable, A> fa) => \n        toHashSet(fa.As());\n\n    static K<Iterable, A> Natural<Iterable, Iterable>.Transform<A>(K<Iterable, A> fa) =>\n        fa;\n\n    static K<Iterable, A> CoNatural<Iterable, Iterable>.CoTransform<A>(K<Iterable, A> fa) => \n        fa;\n        \n    static Fold<A, S> Foldable<Iterable>.FoldStep<A, S>(K<Iterable, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n        \n    static Fold<A, S> Foldable<Iterable>.FoldStepBack<A, S>(K<Iterable, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().Reverse().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IterableNE/Extensions/IterableNE.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IterableNEExtensions\n{\n    /// <param name=\"f\">Mapping function</param>\n    extension<A, B>(Func<A, B> f)\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public IterableNE<B> Map(K<IterableNE, A> ma) =>\n            Functor.map(f, ma).As();\n\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public IterableNE<B> Map(IterableNE<A> ma) =>\n            Functor.map(f, ma).As();\n    }\n\n    extension<A>(K<IterableNE, A> ma)\n    {\n        /// <summary>\n        /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n        /// </summary>\n        public IterableNE<B> Action<B>(K<IterableNE, B> mb) =>\n            Applicative.action(ma, mb).As();\n    }    \n    \n    extension<A>(IterableNE<A> ma)\n    {\n        /// <summary>\n        /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n        /// </summary>\n        public IterableNE<B> Action<B>(K<IterableNE, B> mb) =>\n            Applicative.action(ma, mb).As();\n    }\n\n    /// <param name=\"mf\">Mapping function(s)</param>\n    extension<A, B>(IterableNE<Func<A, B>> mf)\n    {\n        /// <summary>\n        /// Applicative functor apply operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n        /// then takes the resulting value and wraps it back up into a new applicative-functor.\n        /// </remarks>\n        /// <param name=\"ma\">Value(s) applicative functor</param>\n        /// <returns>Mapped applicative functor</returns>\n        public IterableNE<B> Apply(K<IterableNE, A> ma) =>\n            Applicative.apply(mf, ma).As();\n    }\n\n    /// <param name=\"mf\">Mapping function(s)</param>\n    extension<A, B>(K<IterableNE, Func<A, B>> mf)\n    {\n        /// <summary>\n        /// Applicative functor apply operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n        /// then takes the resulting value and wraps it back up into a new applicative-functor.\n        /// </remarks>\n        /// <param name=\"ma\">Value(s) applicative functor</param>\n        /// <returns>Mapped applicative functor</returns>\n        public IterableNE<B> Apply(K<IterableNE, A> ma) =>\n            Applicative.apply(mf, ma).As();\n    }    \n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IterableNE/Extensions/IterableNE.Extensions.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing System;\nusing LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class IterableNEExtensions\n{\n    [Pure]\n    public static IterableNE<A> As<A>(this K<IterableNE, A> xs) =>\n        (IterableNE<A>)xs;\n\n    [Pure]\n    public static Option<IterableNE<A>> AsIterableNE<A>(this IEnumerable<A> xs) =>\n        IterableNE.createRange(xs);\n\n    [Pure]\n    public static IO<IterableNE<A>> AsIterableNE<A>(this IAsyncEnumerable<A> xs) =>\n        IterableNE.createRange(xs);\n\n    [Pure]\n    public static Option<IterableNE<A>> AsIterableNE<A>(this Seq<A> xs) =>\n        xs.Head.Map(h => new IterableNE<A>(h, xs.Tail.AsIterable()));\n\n    [Pure]\n    public static Option<IterableNE<A>> AsIterableNE<A>(this Arr<A> xs) =>\n        xs.IsEmpty\n            ? None\n            : new IterableNE<A>(xs[0], xs.Splice(1).AsIterable());\n\n    [Pure]\n    public static Option<IterableNE<A>> AsIterableNE<A>(this Lst<A> xs) =>\n        xs.IsEmpty\n            ? None\n            : new IterableNE<A>(xs[0], xs.Skip(1));\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Option<IterableNE<A>> Flatten<A>(this IterableNE<IterableNE<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <param name=\"list\">sequence</param>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    extension<A>(IterableNE<A> list)\n    {\n        /// <summary>\n        /// Applies the given function 'selector' to each element of the sequence. Returns the sequence \n        /// comprised of the results for each element where the function returns Some(f(x)).\n        /// </summary>\n        /// <param name=\"selector\">Selector function</param>\n        /// <returns>Mapped and filtered sequence</returns>\n        [Pure]\n        public Iterable<B> Choose<B>(Func<A, Option<B>> selector) =>\n            IterableNE.choose(list, selector);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IterableNE/IterableNE.Module.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Cons sequence module\n/// Represents a sequence of values in a similar way to IEnumerable, but without the\n/// issues of multiple evaluation for key LINQ operators like Skip, Count, etc.\n/// </summary>\n/// <typeparam name=\"A\">Type of the values in the sequence</typeparam>\npublic partial class IterableNE\n{\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<IterableNE<A>> flatten<A>(IterableNE<IterableNE<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Create an empty sequence\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IterableNE<A> singleton<A>(A value) =>\n        IterableNE<A>.FromSpan([value]);\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    public static IterableNE<A> create<A>(A head, params ReadOnlySpan<A> tail) =>\n        new (head, Iterable<A>.FromSpan(tail));\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    public static IterableNE<A> create<A>(A head, IEnumerable<A> tail) =>\n        new (head, Iterable.createRange(tail));\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    public static IterableNE<A> create<A>(A head, IAsyncEnumerable<A> tail) =>\n        new (head, Iterable.createRange(tail));\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    public static IterableNE<A> create<A>(A head, Iterable<A> tail) =>\n        new (head, tail);\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    public static IterableNE<A> create<A>(A head, IterableNE<A> tail) =>\n        new (head, tail.AsIterable());\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<IterableNE<A>> createRange<A>(ReadOnlySpan<A> items) =>\n        items.Length == 0 \n            ? None\n            : IterableNE<A>.FromSpan(items);\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<IterableNE<A>> createRange<A>(IEnumerable<A> items)\n    {\n        var iter = Iterator.from(items);\n        if (iter.IsEmpty) return None;\n        var head = iter.Head;\n        var tail = iter.Tail.AsIterable();\n        return new IterableNE<A>(head, tail);\n    }\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<IterableNE<A>> createRange<A>(IAsyncEnumerable<A> items) =>\n        IO.liftVAsync(async _ =>\n                      {\n                          var iter = IteratorAsync.from(items);\n                          if (await iter.IsEmpty) throw new ArgumentException(\"Can't create an IterableNE from an empty sequence\");\n                          var head = await iter.Head;\n                          var tail = (await iter.Tail).AsIterable();\n                          return new IterableNE<A>(head, tail);\n                      });\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<IterableNE<A>> createRange<A>(Iterable<A> items)\n    {\n        return IO.liftVAsync(_ => items.IsAsync\n                                      ? async()\n                                      : sync());\n    \n        async ValueTask<IterableNE<A>> async()\n        {\n            var iter = IteratorAsync.from(items);\n            if (await iter.IsEmpty) throw new ArgumentException(\"Can't create an IterableNE from an empty sequence\");\n            var head = await iter.Head;\n            var tail = (await iter.Tail).AsIterable();\n            return new IterableNE<A>(head, tail);\n        }\n\n        ValueTask<IterableNE<A>> sync()\n        {\n            var iter = Iterator.from(items);\n            if (iter.IsEmpty) throw new ArgumentException(\"Can't create an IterableNE from an empty sequence\");\n            var head = iter.Head;\n            var tail = iter.Tail.AsIterable();\n            return ValueTask.FromResult(new IterableNE<A>(head, tail));\n        }\n    }\n\n    /// <summary>\n    /// Generates a sequence of A using the provided delegate to initialise\n    /// each item.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<IterableNE<A>> generate<A>(int count, Func<int, A> generator) =>\n        count < 1\n            ? None\n            : createRange(Range(0, count).Select(generator));\n\n    /// <summary>\n    /// Generates a sequence that contains one repeated value.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<IterableNE<A>> repeat<A>(A item, int count) =>\n        count < 1\n            ? None\n            : createRange(Range(0, count).Select(_ => item));\n\n    /// <summary>\n    /// Get the item at the head (first) of the sequence\n    /// </summary>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>Head item</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static A head<A>(IterableNE<A> list) =>\n        list.Head;\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the sequence. Returns the sequence \n    /// of results for each element where the function returns Some(f(x)).\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<B> choose<A, B>(IterableNE<A> list, Func<A, Option<B>> selector) =>\n        list.Map(selector)\n            .Filter(t => t.IsSome)\n            .Map(t => t.Value!);\n\n    /// <summary>\n    /// Joins two sequences together either into a single sequence using the join \n    /// function provided\n    /// </summary>\n    /// <param name=\"list\">First sequence to join</param>\n    /// <param name=\"other\">Second sequence to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IterableNE<C> zip<A, B, C>(IterableNE<A> list, IterableNE<B> other, Func<A, B, C> zipper) =>\n        list.Zip(other, zipper);\n\n    /// <summary>\n    /// Joins two sequences together either into an sequence of tuples\n    /// </summary>\n    /// <param name=\"list\">First sequence to join</param>\n    /// <param name=\"other\">Second sequence to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined sequence of tuples</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IterableNE<(A First, B Second)> zip<A, B>(IterableNE<A> list, IterableNE<B> other) =>\n        list.Zip(other, (t, u) => (t, u));\n\n    /// <summary>\n    /// Returns a new sequence with the first 'count' items from the sequence provided\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first 'count' items from the sequence provided</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> take<A>(IterableNE<A> list, int count) =>\n        list.Take(count);\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first items that match the predicate</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> takeWhile<A>(IterableNE<A> list, Func<A, bool> pred) =>\n        list.TakeWhile(pred);\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't.  An index value is also provided to the predicate function.\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first items that match the predicate</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> takeWhile<A>(IterableNE<A> list, Func<A, int, bool> pred) =>\n        list.TakeWhile(pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IterableNE/IterableNE.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Numerics;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n// ReSharper disable NonReadonlyMemberInGetHashCode\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Non-empty lazy-sequence\n/// </summary>\n/// <remarks>\n/// This always has a Head value and a Tail of length 0 to `n`.   \n/// </remarks>\n/// <typeparam name=\"A\">Type of the values in the sequence</typeparam>\npublic record IterableNE<A>(A Head, Iterable<A> Tail) :\n    IEnumerable<A>,\n    Semigroup<IterableNE<A>>,\n    IComparable<IterableNE<A>>,\n    IComparisonOperators<IterableNE<A>, IterableNE<A>, bool>,\n    IAdditionOperators<IterableNE<A>, IterableNE<A>, IterableNE<A>>,\n    K<IterableNE, A>\n{\n    int? hashCode;\n\n    public static IterableNE<A> FromSpan(ReadOnlySpan<A> ma)\n    {\n        if (ma.IsEmpty) throw new ArgumentException(\"Cannot create an IterableNE from an empty span\");\n        return new IterableNE<A>(ma[0], Iterable<A>.FromSpan(ma.Slice(1)));\n    }\n    \n    [Pure]\n    internal bool IsAsync =>\n        Tail.IsAsync;\n    \n    /// <summary>\n    /// Number of items in the sequence.\n    /// </summary>\n    /// <remarks>\n    /// NOTE: This will force evaluation of the sequence\n    /// </remarks>\n    [Pure]\n    public int Count() =>\n        CountIO().Run();\n\n    /// <summary>\n    /// Number of items in the sequence.\n    /// </summary>\n    /// <remarks>\n    /// NOTE: This will force evaluation of the sequence\n    /// </remarks>\n    [Pure]\n    public IO<int> CountIO() =>\n        Tail.CountIO().Map(c => c + 1);\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public IO<IEnumerable<A>> AsEnumerableIO() =>\n        Tail.AsEnumerableIO().Map(xs => xs.Prepend(Head));\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public IEnumerable<A> AsEnumerable(CancellationToken token = default)\n    {\n        using var env = EnvIO.New(token: token);\n        return AsEnumerableIO().Run(env);\n    }\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public IO<IAsyncEnumerable<A>> AsAsyncEnumerableIO() =>\n        Tail.AsAsyncEnumerableIO().Map(xs => xs.Prepend(Head));\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public IAsyncEnumerable<A> AsAsyncEnumerable(CancellationToken token = default)\n    {\n        using var env = EnvIO.New(token: token);\n        return AsAsyncEnumerableIO().Run(env);\n    }\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        Head.Cons(Tail);\n\n    /// <summary>\n    /// Add an item to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// This does not force evaluation of the whole lazy sequence, nor does it cause\n    /// exponential iteration issues when repeated adds occur.\n    /// </remarks>\n    [Pure]\n    public IterableNE<A> Add(A item) =>\n        new(Head, Tail.Add(item));\n\n    /// <summary>\n    /// Add an item to the beginning of the sequence\n    /// </summary>\n    /// <remarks>\n    /// This does not force evaluation of the whole lazy sequence, nor does it cause\n    /// exponential iteration issues when repeated cons occur.\n    /// </remarks>\n    [Pure]\n    public IterableNE<A> Cons(A item) =>\n        new(item, Head.Cons(Tail));\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public IO<Unit> IterIO(Action<A> f) =>\n        IO.lift(() => f(Head)) >> Tail.IterIO(f);\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Unit Iter(Action<A> f) =>\n        IterIO(f).Run();\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public IO<Unit> IterIO(Action<A, int> f) =>\n        IO.lift(() => f(Head, 0)) >> Tail.IterIO(f, 1);\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Unit Iter(Action<A, int> f) =>\n        IterIO(f).Run();\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public IterableNE<B> Map<B>(Func<A, B> f) =>\n        new(f(Head), Tail.Map(f));\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public IterableNE<B> Map<B>(Func<A, int, B> f) =>\n        new(f(Head, 0), Tail.Map(f, 1));\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public IterableNE<B> Bind<B>(Func<A, IterableNE<B>> f)\n    {\n        var head = f(Head);\n        var tail = Tail.Bind(a => f(a).AsIterable());\n        return head + tail;\n    }\n\n    /// <summary>\n    /// Filter the items in the sequence\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply to the items</param>\n    /// <returns>Filtered sequence</returns>\n    [Pure]\n    public Iterable<A> Filter(Func<A, bool> f) =>\n        f(Head)\n            ? Head.Cons(Tail.Filter(f))\n            : Tail.Filter(f);\n\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public S FoldWhile<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        FoldWhileIO(f, predicate, initialState).Run();\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public S FoldWhile<S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        FoldWhileIO(f, predicate, initialState).Run();\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public IO<S> FoldWhileIO<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        IO.liftVAsync<S>(async env => predicate((initialState, Head))\n                                          ? initialState\n                                          : await Tail.FoldUntilIO(f, predicate, f(Head)(initialState)).RunAsync(env));\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public IO<S> FoldWhileIO<S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        IO.liftVAsync<S>(async env => predicate((initialState, Head))\n                                          ? initialState\n                                          : await Tail.FoldUntilIO(f, predicate, f(initialState, Head)).RunAsync(env));\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public S FoldUntil<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        FoldUntilIO(f, predicate, initialState).Run();\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public S FoldUntil<S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        FoldUntilIO(f, predicate, initialState).Run();\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public IO<S> FoldUntilIO<S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        IO.liftVAsync<S>(async env =>\n                         {\n                             var s = f(Head)(initialState);\n                             if (predicate((s, Head))) return s;\n                             return await Tail.FoldUntilIO(f, predicate, s).RunAsync(env);\n                         });\n\n    /// <summary>\n    /// Fold over the sequence from the left, accumulating state in `f`\n    /// </summary>\n    /// <param name=\"f\">Fold function to apply to each item in the sequence</param>\n    /// <param name=\"predicate\">Continue while the predicate returns true for any pair of value and state.\n    /// This is tested before the value is processed and the state is updated. So, use `FoldWhile*` for pre-assertions.\n    /// </param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"S\">State value type</typeparam>\n    /// <returns>Resulting state</returns>\n    public IO<S> FoldUntilIO<S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState) =>\n        IO.liftVAsync<S>(async env =>\n                         {\n                             var s = f(initialState, Head);\n                             if (predicate((s, Head))) return s;\n                             return await Tail.FoldUntilIO(f, predicate, s).RunAsync(env);\n                         });\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public S FoldMaybe<S>(\n        Func<S, Func<A, Option<S>>> f,\n        S initialState) =>\n        FoldMaybeIO(f, initialState).Run();\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public S FoldMaybe<S>(\n        Func<S, A, Option<S>> f,\n        S initialState) =>\n        FoldMaybeIO(f, initialState).Run();\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public IO<S> FoldMaybeIO<S>(\n        Func<S, Func<A, Option<S>>> f,\n        S initialState) =>\n        FoldWhileIO<(bool IsSome, S Value)>(\n                a => s => f(s.Value)(a) switch\n                          {\n                              { IsSome: true, Case: S value } => (true, value),\n                              _                               => (false, s.Value)\n                          },\n                s => s.State.IsSome,\n                (true, initialState))\n           .Map(s => s.Value);\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public IO<S> FoldMaybeIO<S>(\n        Func<S, A, Option<S>> f,\n        S initialState) =>\n        FoldWhileIO<(bool IsSome, S Value)>(\n                (s, a) => f(s.Value, a) switch\n                          {\n                              { IsSome: true, Case: S value } => (true, value),\n                              _                               => (false, s.Value)\n                          },\n                s => s.State.IsSome,\n                (true, initialState))\n           .Map(s => s.Value);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public K<M, S> FoldWhileM<M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<A, bool> predicate, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldWhileIO(acc, s => predicate(s.Value), Monad.pure<M, S>)\n                  .Bind(f1 => f1(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(value)(state), bind);\n    }\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public K<M, S> FoldWhileM<M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<A, bool> predicate, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldWhileIO(acc, s => predicate(s.Value), Monad.pure<M, S>)\n           .Bind(f1 => f1(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(state, value), bind);\n    }\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public K<M, S> FoldUntilM<M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<A, bool> predicate, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldUntilIO(acc, s => predicate(s.Value), Monad.pure<M, S>).Bind(f1 => f1(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(value)(state), bind);\n    }\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public K<M, S> FoldUntilM<M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<A, bool> predicate, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldUntilIO(acc, s => predicate(s.Value), Monad.pure<M, S>).Bind(f1 => f1(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(state, value), bind);\n    }\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public S Fold<S>(Func<A, Func<S, S>> f, S initialState) =>\n        FoldIO(f, initialState).Run();\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public S Fold<S>(Func<S, A, S> f, S initialState) =>\n        FoldIO(f, initialState).Run();\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public IO<S> FoldIO<S>(Func<A, Func<S, S>> f, S initialState) =>\n        FoldWhileIO(f, _ => true, initialState);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public IO<S> FoldIO<S>(Func<S, A, S> f, S initialState) =>\n        FoldWhileIO(f, _ => true, initialState);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public K<M, S> FoldM<M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldIO(acc, Monad.pure<M, S>).Bind(f => f(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(value)(state), bind);\n    }\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public K<M, S> FoldM<M, S>(\n        Func<S, A, K<M, S>> f, \n        S initialState) \n        where M : MonadIO<M>\n    {\n        return FoldIO(acc, Monad.pure<M, S>).Bind(f => f(initialState));\n\n        Func<Func<S, K<M, S>>, Func<S, K<M, S>>> acc(A value) =>\n            bind => state => Monad.bind(f(state, value), bind);\n    }\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public B FoldMap<B>(Func<A, B> f)\n        where B : Monoid<B> =>\n        FoldMapIO(f).Run();\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public IO<B> FoldMapIO<B>(Func<A, B> f)\n        where B : Monoid<B> =>\n        FoldIO(x => a => f(x).Combine(a), B.Empty);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public B FoldMapWhile<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where B : Monoid<B> =>\n        FoldMapWhileIO(f, predicate).Run();\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public IO<B> FoldMapWhileIO<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where B : Monoid<B> =>\n        FoldWhileIO(x => a => f(x).Combine(a), predicate, B.Empty);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public B FoldMapUntil<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where B : Monoid<B> =>\n        FoldMapUntilIO(f, predicate).Run();\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public IO<B> FoldMapUntilIO<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where B : Monoid<B> =>\n        FoldUntilIO(x => a => f(x).Combine(a), predicate, B.Empty);\n\n    /// <summary>\n    /// Semigroup combine two iterables (concatenate)\n    /// </summary>\n    [Pure]\n    public IterableNE<A> Combine(IterableNE<A> y) =>\n        new(Head, Tail + y.Head.Cons(y.Tail));\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    [Pure]\n    public IterableNE<A> Concat(IEnumerable<A> items) =>\n        new(Head, Tail.Concat(items));\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    [Pure]\n    public IterableNE<A> Concat(Iterable<A> items) =>\n        new(Head, Tail + items);\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    [Pure]\n    public IterableNE<A> Concat(IterableNE<A> items) =>\n        new(Head, Tail + items.Head.Cons(items.Tail));\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public IterableNE<B> Bind<B>(Func<A, K<IterableNE, B>> f) =>\n        Bind(a => f(a).As());\n\n    /// <summary>\n    /// Returns true if the sequence has items in it\n    /// </summary>\n    /// <returns>True if the sequence has items in it</returns>\n    [Pure]\n    public bool Any() =>\n        true;\n\n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj is IterableNE<A> rhs\n            ? CompareTo(rhs)\n            : 1;\n\n    [Pure]\n    public int CompareTo(IterableNE<A>? other) =>\n        CompareTo<OrdDefault<A>>(other);\n\n    [Pure]\n    public IO<int> CompareToIO(IterableNE<A>? other) =>\n        CompareToIO<OrdDefault<A>>(other);\n\n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public int CompareTo<OrdA>(IterableNE<A>? rhs)\n        where OrdA : Ord<A> =>\n        CompareToIO<OrdA>(rhs).Run();\n    \n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public IO<int> CompareToIO<OrdA>(IterableNE<A>? rhs)\n        where OrdA : Ord<A> =>\n        IO.liftVAsync(async e =>\n                      {\n                          if (rhs is null) return 1;\n                          var cmp = OrdA.Compare(Head, rhs.Head);\n                          if (cmp != 0) return cmp;\n                          return await Tail.CompareToIO(rhs.Tail).RunAsync(e);\n                      });\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsEnumerable());\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public IO<string> ToStringIO() =>\n        AsEnumerableIO().Map(xs => CollectionFormat.ToShortArrayString(xs));\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsEnumerable(), separator);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public IO<string> ToFullStringIO(string separator = \", \") =>\n        AsEnumerableIO().Map(xs => CollectionFormat.ToFullString(xs, separator));\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsEnumerable(), separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public IO<string> ToFullArrayStringIO(string separator = \", \") =>\n        AsEnumerableIO().Map(xs => CollectionFormat.ToFullArrayString(xs, separator));\n\n    /// <summary>\n    /// Skip count items\n    /// </summary>\n    [Pure]\n    public Iterable<A> Skip(int amount) =>\n        amount switch\n        {\n            0 => AsIterable(),\n            1 => Tail,\n            _ => Tail.Skip(amount - 1)\n        };\n\n    /// <summary>\n    /// Take count items\n    /// </summary>\n    [Pure]\n    public Iterable<A> Take(int amount) =>\n        amount switch\n        {\n            0 => [],\n            1 => [Head],\n            _ => Tail.Take(amount - 1)\n        };\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate \n    /// provided, and stopping as soon as one doesn't\n    /// </summary>\n    /// <returns>A new sequence with the first items that match the \n    /// predicate</returns>\n    [Pure]\n    public Iterable<A> TakeWhile(Func<A, bool> pred) =>\n        AsIterable().TakeWhile(pred);\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate \n    /// provided, and stopping as soon as one doesn't.  An index value is \n    /// also provided to the predicate function.\n    /// </summary>\n    /// <returns>A new sequence with the first items that match the \n    /// predicate</returns>\n    [Pure]\n    public Iterable<A> TakeWhile(Func<A, int, bool> pred) =>\n        AsIterable().TakeWhile(pred);\n\n    [Pure]\n    /// <summary>\n    /// Partition a list into two based on  a predicate\n    /// </summary>\n    /// <param name=\"predicate\">True if the item goes in the first list, false for the second list</param>\n    /// <returns>Pair of lists</returns>\n    public (Iterable<A> First, Iterable<A> Second) Partition(Func<A, bool> predicate)\n    {\n        var (f, s) = Tail.Partition(predicate);\n        return predicate(Head)\n                ? (Head.Cons(f), s)\n                : (f, Head.Cons(s));\n    }\n\n    /// <summary>\n    /// Zip two iterables into pairs\n    /// </summary>\n    [Pure]\n    public IterableNE<(A First, B Second)> Zip<B>(IterableNE<B> rhs) =>\n        new ((Head, rhs.Head), Tail.Zip(rhs.Tail));\n\n    /// <summary>\n    /// Zip two iterables into pairs\n    /// </summary>\n    [Pure]\n    public IterableNE<C> Zip<B, C>(IterableNE<B> rhs, Func<A, B, C> zipper) =>\n        new (zipper(Head, rhs.Head), Tail.Zip(rhs.Tail, zipper));\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    public static IterableNE<A> operator +(IterableNE<A> x, IterableNE<A> y) =>\n        x.Concat(y);\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    public static IterableNE<A> operator +(IterableNE<A> x, Iterable<A> y) =>\n        x.Concat(y);\n\n    /// <summary>\n    /// Ordering operator\n    /// </summary>\n    [Pure]\n    public static bool operator >(IterableNE<A> x, IterableNE<A> y) =>\n        x.CompareTo(y) > 0;\n\n    /// <summary>\n    /// Ordering operator\n    /// </summary>\n    [Pure]\n    public static bool operator >=(IterableNE<A> x, IterableNE<A> y) =>\n        x.CompareTo(y) >= 0;\n\n    /// <summary>\n    /// Ordering  operator\n    /// </summary>\n    [Pure]\n    public static bool operator <(IterableNE<A> x, IterableNE<A> y) =>\n        x.CompareTo(y) < 0;\n\n    /// <summary>\n    /// Ordering  operator\n    /// </summary>\n    [Pure]\n    public static bool operator <=(IterableNE<A> x, IterableNE<A> y) =>\n        x.CompareTo(y) <= 0;\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public IterableNE<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public IterableNE<B> Select<B>(Func<A, int, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"bind\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public IterableNE<B> SelectMany<B>(Func<A, IterableNE<B>> bind) =>\n        Bind(bind);\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"bind\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public IterableNE<C> SelectMany<B, C>(Func<A, IterableNE<B>> bind, Func<A, B, C> project) =>\n        Bind(x  => bind(x).Map(y => project(x, y)));\n\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsEnumerable().GetEnumerator();\n\n    /// <summary>\n    /// Get the hash code for all the items in the sequence, or 0 if empty\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public override int GetHashCode() =>\n        hashCode.HasValue\n            ? hashCode.Value\n            : (hashCode = hash(AsEnumerable())).Value;\n    \n    IEnumerator IEnumerable.GetEnumerator() => \n        GetEnumerator();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IterableNE/Operators/IterableNE.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IterableNEExtensions\n{\n    extension<A>(K<IterableNE, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static IterableNE<A> operator +(K<IterableNE, A> ma) =>\n            (IterableNE<A>)ma;\n        \n        public static IterableNE<A> operator >> (K<IterableNE, A> ma, Lower lower) =>\n            (IterableNE<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IterableNE/Trait/IterableNE.TraitImpl.cs",
    "content": "using System;\nusing System.Linq;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class IterableNE : \n    Monad<IterableNE>, \n    SemigroupK<IterableNE>,\n    Foldable<IterableNE>,\n    NaturalMono<IterableNE, Arr>,\n    NaturalMono<IterableNE, Seq>,\n    NaturalMono<IterableNE, Lst>,\n    NaturalMono<IterableNE, Set>,\n    NaturalMono<IterableNE, Iterable>,\n    NaturalMono<IterableNE, HashSet>\n{\n    static K<IterableNE, B> Monad<IterableNE>.Recur<A, B>(A value, Func<A, K<IterableNE, Next<A, B>>> f) =>\n        // TODO: We need a way of lifting an IO<IAsyncEnumerable> into IterableNE (knowing it's non-empty)\n        // Create a sub-type DSL for IterableNE, like Iterable\n        Monad.unsafeRecur(value, f);\n    \n    static K<IterableNE, B> Monad<IterableNE>.Bind<A, B>(K<IterableNE, A> ma, Func<A, K<IterableNE, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<IterableNE, B> Functor<IterableNE>.Map<A, B>(Func<A, B> f, K<IterableNE, A> ma) => \n        ma.As().Map(f);\n\n    static K<IterableNE, A> Applicative<IterableNE>.Pure<A>(A value) =>\n        singleton(value);\n\n    static K<IterableNE, B> Applicative<IterableNE>.Apply<A, B>(K<IterableNE, Func<A, B>> mf, K<IterableNE, A> ma) =>\n        mf >> ma.Map;\n\n    static K<IterableNE, B> Applicative<IterableNE>.Apply<A, B>(K<IterableNE, Func<A, B>> mf, Memo<IterableNE, A> ma) =>\n        mf >> ma.Map;\n\n    static K<IterableNE, A> SemigroupK<IterableNE>.Combine<A>(K<IterableNE, A> ma, K<IterableNE, A> mb) =>\n        ma.As().Concat(mb.As());\n    \n    static S Foldable<IterableNE>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<IterableNE, A> ta) =>\n        ta.As().FoldWhile(f, predicate, state);\n    \n    static S Foldable<IterableNE>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S state, \n        K<IterableNE, A> ta) =>\n        throw new NotSupportedException(\"FoldBack* is currently not supported for IterableNE\");\n    \n    static Arr<A> Foldable<IterableNE>.ToArr<A>(K<IterableNE, A> ta) =>\n        new(ta.As());\n\n    static Lst<A> Foldable<IterableNE>.ToLst<A>(K<IterableNE, A> ta) =>\n        new(ta.As());\n\n    static Iterable<A> Foldable<IterableNE>.ToIterable<A>(K<IterableNE, A> ta) =>\n        ta.As().AsIterable();\n    \n    static Seq<A> Foldable<IterableNE>.ToSeq<A>(K<IterableNE, A> ta) =>\n        new(ta.As());\n\n    static K<Seq, A> Natural<IterableNE, Seq>.Transform<A>(K<IterableNE, A> fa) => \n        toSeq(fa.As());\n\n    static K<Arr, A> Natural<IterableNE, Arr>.Transform<A>(K<IterableNE, A> fa) => \n        toArray(fa.As());\n\n    static K<Lst, A> Natural<IterableNE, Lst>.Transform<A>(K<IterableNE, A> fa) => \n        toList(fa.As());\n\n    static K<Set, A> Natural<IterableNE, Set>.Transform<A>(K<IterableNE, A> fa) => \n        toSet(fa.As());\n\n    static K<Iterable, A> Natural<IterableNE, Iterable>.Transform<A>(K<IterableNE, A> fa) => \n        fa.As().AsIterable();\n\n    static K<HashSet, A> Natural<IterableNE, HashSet>.Transform<A>(K<IterableNE, A> fa) => \n        toHashSet(fa.As());\n    \n    static Fold<A, S> Foldable<IterableNE>.FoldStep<A, S>(K<IterableNE, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }   \n        \n    static Fold<A, S> Foldable<IterableNE>.FoldStepBack<A, S>(K<IterableNE, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().Reverse().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/DSL/Iterator.Cons.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic abstract partial class Iterator<A> \n{\n    /// <summary>\n    /// Cons iterator case.\n    ///\n    /// Contains a head value and a tail that represents the rest of the sequence.\n    /// </summary>\n    public abstract class Cons : Iterator<A>\n    {\n        public new void Deconstruct(out A head, out Iterator<A> tail)\n        {\n            head = Head;\n            tail = Tail;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/DSL/Iterator.ConsFirst.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic abstract partial class Iterator<A> \n{\n    internal sealed class ConsFirst : Cons\n    {\n        IEnumerable<A> enumerable;\n        int firstAcquired;\n        Iterator<A>? firstValue;\n\n        public override string ToString() => \n            \"Iterator\";\n\n        internal ConsFirst(IEnumerable<A> enumerable) =>\n            this.enumerable = enumerable;\n\n        public override A Head =>\n            First.Head;\n\n        public override Iterator<A> Tail =>\n            First.Tail;\n\n        public new void Deconstruct(out A head, out Iterator<A> tail)\n        {\n            head = Head;\n            tail = Tail;\n        }\n\n        Iterator<A> First\n        {\n            get\n            {\n                if (firstAcquired == 2) return firstValue!;\n                \n                SpinWait sw = default;\n                while (firstAcquired < 2)\n                {\n                    if (Interlocked.CompareExchange(ref firstAcquired, 1, 0) == 0)\n                    {\n                        try\n                        {\n                            var enumerator = enumerable.GetEnumerator();\n                            if (enumerator.MoveNext())\n                            {\n                                firstValue = new ConsValueEnum(enumerator.Current, enumerator);\n                            }\n                            else\n                            {\n                                enumerator.Dispose();\n                                firstValue = Nil.Default;\n                            }\n\n                            firstAcquired = 2;\n                        }\n                        catch (Exception)\n                        {\n                            firstAcquired = 0;\n                            throw;\n                        }\n                    }\n                    else\n                    {\n                        sw.SpinOnce();\n                    }\n                }\n                return firstValue!;\n            }\n        }\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override bool IsEmpty =>\n            First.IsEmpty;\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override Iterator<A> Clone() =>\n            new ConsFirst(enumerable);\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override Iterator<A> Split() =>\n            Clone();\n\n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override long Count =>\n            First.Count;\n\n        public override void Dispose()\n        {\n            if (Interlocked.CompareExchange(ref firstAcquired, 1, 2) == 2)\n            {\n                firstValue?.Dispose();\n                firstValue = null;\n                firstAcquired = 0;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/DSL/Iterator.ConsValue.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic abstract partial class Iterator<A> \n{\n    internal sealed class ConsValue : Cons\n    {\n        A head;\n        Iterator<A> tail;\n\n        public override string ToString() => \n            \"Iterator\";\n\n        public ConsValue(A head, Iterator<A> tail)\n        {\n            this.head = head;\n            this.tail = tail;\n            Count = -1;\n        }\n        \n        public new void Deconstruct(out A head, out Iterator<A> tail)\n        {\n            head = Head;\n            tail = Tail;\n        }\n\n        /// <summary>\n        /// Head element\n        /// </summary>\n        public override A Head => head;\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        public override Iterator<A> Tail => tail;\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override bool IsEmpty =>\n            false;\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override Iterator<A> Clone() =>\n            new ConsValue(Head, Tail.Clone());\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override Iterator<A> Split() =>\n            this;\n\n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override long Count\n        {\n            get\n            {\n                if (field == -1)\n                {\n                    field = 1 + Tail.Count;\n                }\n                return field;\n            }\n        }\n        \n        public override void Dispose() =>\n            Tail.Dispose();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/DSL/Iterator.ConsValueEnum.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic abstract partial class Iterator<A> \n{\n    internal sealed class ConsValueEnum : Cons\n    {\n        Exception? exception;\n        IEnumerator<A>? enumerator;\n        int tailAcquired;\n        Iterator<A>? tailValue;\n        long count = -1;\n\n        public override string ToString() => \n            \"Iterator\";\n\n        internal ConsValueEnum(A head, IEnumerator<A> enumerator)\n        {\n            Head = head;\n            this.enumerator = enumerator;\n        }\n\n        public new void Deconstruct(out A head, out Iterator<A> tail)\n        {\n            head = Head;\n            tail = Tail;\n        }\n\n        /// <summary>\n        /// Head element\n        /// </summary>\n        public override A Head { get; }\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        public override Iterator<A> Tail\n        {\n            get\n            {\n                if(tailAcquired == 2) return tailValue!;\n                if(tailAcquired == 3) exception!.Rethrow();\n\n                SpinWait sw = default;\n                while (tailAcquired < 2)\n                {\n                    if (Interlocked.CompareExchange(ref tailAcquired, 1, 0) == 0)\n                    {\n                        try\n                        {\n                            if (enumerator!.MoveNext())\n                            {\n                                tailValue = new ConsValueEnum(enumerator.Current, enumerator);\n                            }\n                            else\n                            {\n                                enumerator?.Dispose();\n                                enumerator = null;\n                                tailValue = Nil.Default;\n                            }\n\n                            tailAcquired = 2;\n                        }\n                        catch (Exception e)\n                        {\n                            exception = e;\n                            tailAcquired = 3;\n                            throw;\n                        }\n                    }\n                    else\n                    {\n                        sw.SpinOnce();\n                    }\n                }\n\n                if(tailAcquired == 3) exception!.Rethrow();\n                return tailValue!;\n            }\n        }\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override bool IsEmpty =>\n            false;\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override Iterator<A> Clone() =>\n            this;\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override Iterator<A> Split()\n        {\n            if (Interlocked.CompareExchange(ref tailAcquired, 1, 0) == 0)\n            {\n                tailValue = Nil.Default;\n                tailAcquired = 2;\n                return new ConsValueEnum(Head, enumerator!);\n            }\n            else\n            {\n                return this;\n            }\n        }\n        \n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override long Count\n        {\n            get\n            {\n                if (count == -1)\n                {\n                    count = 1 + Tail.Count;\n                }\n                return count;\n            }\n        }\n\n        public override void Dispose()\n        {\n            enumerator?.Dispose();\n            enumerator = null;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/DSL/Iterator.ConsValueLazy.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic abstract partial class Iterator<A> \n{\n    internal sealed class ConsValueLazy : Cons\n    {\n        long count;\n        A head;\n        Exception? error;\n        Iterator<A>? tail;\n        Func<Iterator<A>>? tailF;\n        int tailAcquired;\n\n        public override string ToString() => \n            \"Iterator\";\n\n        public ConsValueLazy(A head, Func<Iterator<A>> tailF)\n        {\n            this.head = head;\n            this.tailF = tailF;\n            tail = null;\n            count = -1;\n        }\n        \n        public new void Deconstruct(out A h, out Iterator<A> t)\n        {\n            h = Head;\n            t = Tail;\n        }\n\n        /// <summary>\n        /// Head element\n        /// </summary>\n        public override A Head => head;\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        public override Iterator<A> Tail => TailLazy();\n\n        Iterator<A> TailLazy()\n        {\n            if (tailAcquired == 2) return tail!;\n            if (tailAcquired == 3) error!.Rethrow();\n\n            SpinWait sw = default;\n            while (tailAcquired < 2)\n            {\n                if (Interlocked.CompareExchange(ref tailAcquired, 1, 0) == 0)\n                {\n                    try\n                    {\n                        tail = tailF!();\n                        tailF = null;\n                        tailAcquired = 2;\n                    }\n                    catch(Exception e)\n                    {\n                        error = e;\n                        tailF = null;\n                        tailAcquired = 3;\n                        throw;\n                    }\n                }\n                else\n                {\n                    sw.SpinOnce();\n                }\n            }\n\n            return tail!;\n        }\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override bool IsEmpty =>\n            false;\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override Iterator<A> Clone() =>\n            this;\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override Iterator<A> Split()\n        {\n            var h = head;\n            var t = tailF;\n            return tailAcquired == 0\n                       ? new ConsValueLazy(h, t!)\n                       : this;\n        }\n\n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override long Count\n        {\n            get\n            {\n                if (count == -1)\n                {\n                    count = 1 + Tail.Count;\n                }\n                return count;\n            }\n        }\n\n        public override void Dispose()\n        {\n            if (tailAcquired == 2)\n            {\n                Tail.Dispose();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/DSL/Iterator.Nil.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic abstract partial class Iterator<A> : \n    IEnumerable<A>,\n    IEquatable<Iterator<A>>,\n    IDisposable,\n    K<Iterator, A>\n{\n    /// <summary>\n    /// Nil iterator case\n    ///\n    /// The end of the sequence.\n    /// </summary>\n    public sealed class Nil : Iterator<A>\n    {\n        public static readonly Iterator<A> Default = new Nil();\n\n        public override string ToString() => \n            \"Nil\";\n\n        /// <summary>\n        /// Head element\n        /// </summary>\n        public override A Head =>\n            throw new InvalidOperationException(\"Nil iterator has no head\");\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        public override Iterator<A> Tail =>\n            this;\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override bool IsEmpty =>\n            true;\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override Iterator<A> Clone() =>\n            this;\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override Iterator<A> Split() =>\n            this;\n\n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override long Count =>\n            0;\n\n        public override void Dispose()\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/Extensions/Iterator.Extensions.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IteratorExtensions\n{\n    /// <summary>\n    /// Downcast operator\n    /// </summary>\n    public static Iterator<A> As<A>(this K<Iterator, A> ma) =>\n        (Iterator<A>)ma;\n    \n    /// <summary>\n    /// Get an iterator for any `IEnumerable` \n    /// </summary>\n    public static Iterator<A> GetIterator<A>(this IEnumerable<A> enumerable) =>\n        Iterator.from(enumerable);\n\n}\n\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/Iterator.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\npublic partial class Iterator\n{\n    /// <summary>\n    /// Create an iterator from an `IEnumerable`\n    /// </summary>\n    /// <param name=\"enumerable\"></param>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    public static Iterator<A> from<A>(IEnumerable<A> enumerable) =>\n        new Iterator<A>.ConsFirst(enumerable);\n\n    /// <summary>\n    /// Construct a singleton sequence \n    /// </summary>\n    /// <param name=\"head\">Head item</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Iterator</returns>\n    public static Iterator<A> singleton<A>(A head) =>\n        new Iterator<A>.ConsValue(head, Iterator<A>.Nil.Default);\n\n    /// <summary>\n    /// Construct a sequence from a head item and a tail sequence\n    /// </summary>\n    /// <param name=\"head\">Head item</param>\n    /// <param name=\"tail\">Tail sequences</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Iterator</returns>\n    public static Iterator<A> Cons<A>(A head, Iterator<A> tail) =>\n        new Iterator<A>.ConsValue(head, tail);\n\n    /// <summary>\n    /// Construct a sequence from a head item and a tail sequence\n    /// </summary>\n    /// <param name=\"head\">Head item</param>\n    /// <param name=\"tail\">Tail sequences</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Iterator</returns>\n    public static Iterator<A> Cons<A>(A head, Func<Iterator<A>> tail) =>\n        new Iterator<A>.ConsValueLazy(head, tail);\n\n    /// <summary>\n    /// Empty sequence\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Iterator</returns>\n    public static Iterator<A> Nil<A>() =>\n        Iterator<A>.Nil.Default;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/Iterator.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Wrapper for `IEnumerator` that makes it work like an immutable sequence.\n/// \n/// It is thread-safe and impossible for any item in the sequence to be enumerated more than once.\n/// </summary>\n/// <remarks>\n/// `IEnumerator` from the .NET BCL has several problems: \n///\n///    * It's very imperative\n///    * It's not thread-safe, two enumerators can't be shared\n/// \n/// The lack of support for sharing of enumerators means that it's problematic using it internally\n/// in types like `StreamT`, or anything that needs to keep an `IEnumerator` alive for any period\n/// of time.\n///\n/// NOTE: There is a per-item allocation to hold the state of the iterator.  These are discarded as\n/// you enumerate the sequence.  However, technically it is possible to hold the initial `Iterator`\n/// value and subsequently gain a cached sequence of every item encountered in the enumerator.\n///\n/// That may well be valuable for circumstances where re-evaluation would be expensive.  However,\n/// for infinite-streams this would be extremely problematic.  So, make sure you discard any\n/// previous `Iterator` values as you walk the sequence. \n/// </remarks>\n/// <typeparam name=\"A\">Item value type</typeparam>\npublic abstract partial class Iterator<A> : \n    IEnumerable<A>,\n    IEquatable<Iterator<A>>,\n    IDisposable,\n    K<Iterator, A>\n{\n    /// <summary>\n    /// Empty iterator\n    /// </summary>\n    public static readonly Iterator<A> Empty = new Nil();\n    \n    /// <summary>\n    /// Head element\n    /// </summary>\n    [Pure]\n    public abstract A Head { get; }\n\n    /// <summary>\n    /// Tail of the sequence\n    /// </summary>\n    [Pure]\n    public abstract Iterator<A> Tail { get; }\n    \n    /// <summary>\n    /// Return true if there are no elements in the sequence.\n    /// </summary>\n    [Pure]\n    public abstract bool IsEmpty  { get; }\n    \n    /// <summary>\n    /// Return the number of items in the sequence.\n    /// </summary>\n    /// <remarks>\n    /// Requires all items to be evaluated, this will happen only once however.\n    /// </remarks>\n    [Pure]\n    public abstract long Count  { get; }\n\n    /// <summary>\n    /// Clone the iterator so that we can consume it without having the head item referenced.\n    /// This will stop any GC pressure when processing large or infinite sequences.\n    /// </summary>\n    [Pure]\n    public abstract Iterator<A> Clone();\n\n    /// <summary>\n    /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n    /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n    /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n    /// can't be garbage collected. \n    /// </summary>\n    /// <remarks>\n    /// Any other iterator references that came before this one will terminate at this point.  Splitting the\n    /// previous and subsequent iterators here. \n    /// </remarks>\n    /// <returns>New iterator that starts from the current iterator position.</returns>\n    public abstract Iterator<A> Split();\n\n    /// <summary>\n    /// Create an `IEnumerable` from an `Iterator`\n    /// </summary>\n    [Pure]\n    public IEnumerable<A> AsEnumerable()\n    {\n        for (var ma = Clone(); !ma.IsEmpty; ma = ma.Tail)\n        {\n            yield return  ma.Head;\n        }\n    }\n\n    /// <summary>\n    /// Create an `Iterable` from an `Iterator`\n    /// </summary>\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        Iterable.createRange(AsEnumerable());\n\n    /// <summary>\n    /// Deconstructor\n    /// </summary>\n    public void Deconstruct(out A head, out Iterator<A> tail)\n    {\n        head = Head;\n        tail = Tail;\n    }\n    \n    /// <summary>\n    /// Functor map\n    /// </summary>\n    [Pure]\n    public Iterator<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    [Pure]\n    public Iterator<B> Map<B>(Func<A, B> f)\n    {\n        return Go(this, f).GetIterator();\n        static IEnumerable<B> Go(Iterator<A> ma, Func<A, B> f)\n        {\n            for (var a = ma.Clone(); !a.IsEmpty; a = a.Tail)\n            {\n                yield return f(a.Head);\n            }\n        }\n    }\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public Iterator<B> Bind<B>(Func<A, Iterator<B>> f)\n    {\n        return Go(this, f).GetIterator();\n        static IEnumerable<B> Go(Iterator<A> ma, Func<A, Iterator<B>> f)\n        {\n            for (var a = ma.Clone(); !a.IsEmpty; a = a.Tail)\n            {\n                for (var b = f(a.Head); !b.IsEmpty; b = b.Tail)\n                {\n                    yield return b.Head;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public Iterator<C> SelectMany<B, C>(Func<A, Iterator<B>> bind, Func<A, B, C> project)\n    {\n        return Go(this, bind, project).GetIterator();\n        static IEnumerable<C> Go(Iterator<A> ma, Func<A, Iterator<B>> bind, Func<A, B, C> project)\n        {\n            for (var a = ma.Clone(); !a.IsEmpty; a = a.Tail)\n            {\n                for (var b = bind(a.Head); !b.IsEmpty; b = b.Tail)\n                {\n                    yield return project(a.Head, b.Head);\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Applicative apply\n    /// </summary>\n    [Pure]\n    public Iterator<B> Apply<B>(Iterator<Func<A, B>> ff, Iterator<A> fa)\n    {\n        return Go(ff, fa).GetIterator();\n        static IEnumerable<B> Go(Iterator<Func<A, B>> ff, Iterator<A> fa)\n        {\n            for (var f = ff.Clone(); !f.IsEmpty; f = f.Tail)\n            {\n                for (var a = fa.Clone(); !a.IsEmpty; a = a.Tail)\n                {\n                    yield return f.Head(a.Head);\n                }\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Concatenate two iterators\n    /// </summary>\n    [Pure]\n    public Iterator<A> Concat(Iterator<A> other)\n    {\n        return Go(this, other).GetIterator();\n        static IEnumerable<A> Go(Iterator<A> ma, Iterator<A> mb)\n        {\n            for (var a = ma.Clone(); !a.IsEmpty; a = a.Tail)\n            {\n                yield return ma.Head;\n            }\n            for (var b = mb.Clone(); !b.IsEmpty; b = b.Tail)\n            {\n                yield return mb.Head;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Fold the sequence while there are more items remaining\n    /// </summary>\n    [Pure]\n    public S Fold<S>(\n        S state,\n        Func<A, Func<S, S>> f)\n    {\n        for(var xs = Clone(); !xs.IsEmpty; xs = xs.Tail)\n        {\n            state = f(xs.Head)(state);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence while there are more items remaining\n    /// </summary>\n    [Pure]\n    public S Fold<S>(        \n        S state,\n        Func<S, A, S> f)\n    {\n        for(var xs = Clone(); !xs.IsEmpty; xs = xs.Tail)\n        {\n            state = f(state, xs.Head);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence in reverse while there are more items remaining\n    /// </summary>\n    [Pure]\n    public S FoldBack<S>(\n        S state,\n        Func<A, Func<S, S>> f)\n    {\n        foreach(var x in Clone().AsEnumerable().Reverse())\n        {\n            state = f(x)(state);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence in reverse while there are more items remaining\n    /// </summary>\n    [Pure]\n    public S FoldBack<S>(        \n        S state,\n        Func<S, A, S> f)\n    {\n        foreach(var x in Clone().AsEnumerable().Reverse())\n        {\n            state = f(state, x);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence while the predicate returns `true` and there are more items remaining\n    /// </summary>\n    [Pure]\n    public S FoldWhile<S>(\n        S state,\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate)\n    {\n        for(var xs = Clone(); !xs.IsEmpty; xs = xs.Tail)\n        {\n            if (!predicate((state, xs.Head))) return state;\n            state = f(xs.Head)(state);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence while the predicate returns `true` and there are more items remaining\n    /// </summary>\n    [Pure]\n    public S FoldWhile<S>(\n        S state,\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate)\n    {\n        for(var xs = Clone(); !xs.IsEmpty; xs = xs.Tail)\n        {\n            if (!predicate((state, xs.Head))) return state;\n            state = f(state, xs.Head);\n        }\n        return state;\n    }\n    \n    /// <summary>\n    /// Fold the sequence in reverse while the predicate returns `true` and there are more items remaining\n    /// </summary>\n    [Pure]\n    public S FoldBackWhile<S>(\n        S state,\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate) \n    {\n        foreach(var x in Clone().AsEnumerable().Reverse())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(state)(x);\n        }\n        return state;\n    }\n    \n    /// <summary>\n    /// Fold the sequence in reverse while the predicate returns `true` and there are more items remaining\n    /// </summary>\n    [Pure]\n    public S FoldBackWhile<S>(\n        S state,\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate)\n    {\n        foreach(var x in Clone().AsEnumerable().Reverse())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(state, x);\n        }\n        return state;\n    }\n    \n    /// <summary>\n    /// Fold the sequence until the predicate returns `true` or the sequence ends\n    /// </summary>\n    [Pure]\n    public S FoldUntil<S>(\n        S state,\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate)\n    {\n        for(var xs = Clone(); !xs.IsEmpty; xs = xs.Tail)\n        {\n            state = f(xs.Head)(state);\n            if (predicate((state, xs.Head))) return state;\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence until the predicate returns `true` or the sequence ends\n    /// </summary>\n    [Pure]\n    public S FoldUntil<S>(\n        S state,\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate)\n    {\n        for(var xs = Clone(); !xs.IsEmpty; xs = xs.Tail)\n        {\n            state = f(state, xs.Head);\n            if (predicate((state, xs.Head))) return state;\n        }\n        return state;\n    }\n    \n    /// <summary>\n    /// Fold the sequence in reverse until the predicate returns `true` or the sequence ends\n    /// </summary>\n    [Pure]\n    public S FoldBackUntil<S>(\n        S state,\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate) \n    {\n        foreach(var x in Clone().AsEnumerable().Reverse())\n        {\n            state = f(state)(x);\n            if (predicate((state, x))) return state;\n        }\n        return state;\n    }\n    \n    /// <summary>\n    /// Fold the sequence in reverse until the predicate returns `true` or the sequence ends\n    /// </summary>\n    [Pure]\n    public S FoldBackUntil<S>(\n        S state,\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate)\n    {\n        foreach(var x in Clone().AsEnumerable().Reverse())\n        {\n            state = f(state, x);\n            if (predicate((state, x))) return state;\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Interleave two iterator sequences together\n    /// </summary>\n    /// <remarks>\n    /// Whilst there are items in both sequences, each is yielded after the other.  Once one sequence\n    /// runs out of items, the remaining items of the other sequence is yielded alone.\n    /// </remarks>\n    [Pure]\n    public Iterator<A> Merge(Iterator<A> other)\n    {\n        return Go(this, other).GetIterator();        \n        static IEnumerable<A> Go(Iterator<A> ma, Iterator<A> mb)\n        {\n            var a = ma.Clone();\n            var b = mb.Clone();\n\n            while (!a.IsEmpty && !b.IsEmpty)\n            {\n                yield return a.Head;\n                yield return b.Head;\n                a = a.Tail;\n                b = b.Tail;\n            }\n\n            if (a.IsEmpty)\n            {\n                while (!b.IsEmpty)\n                {\n                    yield return b.Head;\n                    b = b.Tail;\n                }\n            }\n            else\n            {\n                while (!a.IsEmpty)\n                {\n                    yield return a.Head;\n                    a = a.Tail;\n                }\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Zips the items of two sequences together\n    /// </summary>\n    /// <remarks>\n    /// The output sequence will be as long as the shortest input sequence.\n    /// </remarks>\n    [Pure]\n    public Iterator<(A First , A Second)> Zip(Iterator<A> other)\n    {\n        return Go(this, other).GetIterator();        \n        static IEnumerable<(A First , A Second)> Go(Iterator<A> ma, Iterator<A> mb)\n        {\n            var a = ma.Clone();\n            var b = mb.Clone();\n\n            while (!a.IsEmpty && !b.IsEmpty)\n            {\n                yield return (a.Head, b.Head);\n                a = a.Tail;\n                b = b.Tail;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Combine two sequences\n    /// </summary>\n    public static Iterator<A> operator +(Iterator<A> ma, Iterator<A> mb) =>\n        ma.Concat(mb);\n\n    /// <summary>\n    /// Dispose\n    /// </summary>\n    public abstract void Dispose();\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"obj\">Other iterator to compare against</param>\n    /// <returns>True if equal</returns>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is Iterator<A> other && Equals(other);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"other\">Other iterator to compare against</param>\n    /// <returns>True if equal</returns>\n    [Pure]\n    public bool Equals(Iterator<A>? rhs)\n    {\n        if (rhs is null) return false;\n        var iterA = Clone();\n        var iterB = rhs.Clone();\n        while (true)\n        {\n            if(iterA.IsEmpty && iterB.IsEmpty) return true; \n            if(iterA.IsEmpty || iterB.IsEmpty) return false;\n            if(!EqDefault<A>.Equals(iterA.Head, iterB.Head)) return false;\n            iterA = iterA.Tail;\n            iterB = iterB.Tail;\n        }\n    }\n\n    [Pure]\n    public override int GetHashCode()\n    {\n        if(IsEmpty) return 0;\n        var iter = Clone();\n        var hash = OffsetBasis;\n        while(!iter.IsEmpty)\n        {\n            var itemHash = iter.Head?.GetHashCode() ?? 0;\n            unchecked\n            {\n                hash = (hash ^ itemHash) * Prime;\n            }\n            iter = iter.Tail;\n        }\n        return hash;\n    }\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public IEnumerator<A> GetEnumerator() => \n        AsEnumerable().GetEnumerator();\n\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() => \n        GetEnumerator();\n\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsEnumerable());\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsEnumerable(), separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(this.AsEnumerable(), separator);\n\n    const int OffsetBasis = -2128831035;\n    const int Prime = 16777619;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/Operators/Iterator.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IteratorExtensions\n{\n    extension<A>(K<Iterator, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Iterator<A> operator +(K<Iterator, A> ma) =>\n            (Iterator<A>)ma;\n        \n        public static Iterator<A> operator >> (K<Iterator, A> ma, Lower lower) =>\n            (Iterator<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/README.md",
    "content": "`Iterator<A>` is a functional-wrapper for `IEnumerator<A>`.  The abstraction leaks a little, so it's worth \nunderstanding how it works by reading the details below.  On the whole, it behaves like an immutable stream \nthat caches values as it goes, but there are some footguns that you should be aware of so that they can be \navoided.\n\n## Problem: `IEnumerator<A>`\n\n* It is mutable which means using it in immutable data-structures is problematic. \n* If you pass an `IEnumerator` reference to two threads, each thread can \ncall `MoveNext`and it will move the enumeration position for other thread, or even worse, move past the end\nof the sequence due to race conditions.\n* Enumerators start before the first item and use a complicated mechanism for accessing and testing the validity of\nthe element value.\n\n_Nobody in their right mind would invent an interface like `IEnumerator<A>` today._\n\n## Solution: `Iterator<A>`\n\n`Iterator<A>` still uses `IEnumerator<A>` internally, but it makes it thread-safe and functional.  From the outside\nthe type acts and works exactly like any other immutable sequence, but internally it does some quite complex\nprocessing to achieve this with an `IEnumerator<A>` reference.\n\n> You may say \"Why not just drop `IEnumerator<A>`?\" - which is a completely valid position to hold. Unfortunately, \n> `IEnumerable` and `IEnumerator` are baked into the CPS state-machine that is used for `yield return` and \n> `yield break`.  So, we don't get to ignore those types, and instead we need to make them play nice.\n\n`IEnumerable<A>` has a method called `GetEnumerator()` which is used to access an `IEnumerator<A>`.  A new extension\nmethod is available called `GetIterator()`, this will yield an `Iterator<A>`.\n\nYou can pattern-match an `Iterator<A>` like a functional 'cons' linked-list type:\n\n```c#\nstatic A Sum<A>(Iterator<A> iter) where A : INumber =>\n    iter switch\n    {\n        Iterator<A>.Nil                 => A.Zero,\n        Iterator<A>.Cons(var x, var xs) => x + Sum(xs),\n    }\n```\nOr, use `IsEmpty` and `Head`:\n```c#\nstatic A Sum<A>(Iterator<A> iter) where A : INumber =>\n    iter.IsEmpty\n        ? A.Zero\n        : iter.Head + Sum(iter.Tail);\n```\nOr, use built-in operators:\n```c#\nstatic A Sum<A>(Iterator<A> iter) where A : INumber =>\n    iter.Fold(A.Zero, (s, x) => s + x);\n```\nOr, take an imperative approach:\n```c#\nstatic A Sum<A>(Iterator<A> iter) where A : INumber\n{\n    var total = A.Zero;\n    while(!iter.IsEmpty)\n    {\n        total += iter.Head;\n        iter = iter.Tail;\n    }\n    return total;\n}\n```\nAnd,\n```c#\nstatic A Sum<A>(Iterator<A> iter) where A : INumber\n{\n    for(var total = A.Zero; !iter.IsEmpty; iter = iter.Tail)\n    {\n        total += iter.Head;\n    }\n    return total;\n}\n```\n\n`Iterator<A>` is `abstract` and the first type returned from `GetIterator()` will be a `Iterator<A>.ConsFirst`, this type implements \n`Iterator<A>`.  The internal fields that `ConsFirst` contains are these:\n```c#\nIEnumerable<A> enumerable;\nint firstAcquired;\nIterator<A>? firstValue;\n```\nSo, you can see that it doesn't actually have an `IEnumerator<A>` as this point.\n\nThe two key properties of `Iterator<A>` are `Head` (for accessing the current item) and `Tail` (for accessing\nthe remaining items), so let's look at those for `ConsFirst`:\n```c#\npublic override A Head =>\n    First.Head;\n\npublic override Iterator<A> Tail =>\n    First.Tail;\n```\nThey both access `First`, which is:\n\n```c#\nIterator<A> First\n{\n    get\n    {\n        if (firstAcquired == 2) return firstValue!;\n        \n        SpinWait sw = default;\n        while (firstAcquired < 2)\n        {\n            if (Interlocked.CompareExchange(ref firstAcquired, 1, 0) == 0)\n            {\n                try\n                {\n                    var enumerator = enumerable.GetEnumerator();\n                    if (enumerator.MoveNext())\n                    {\n                        firstValue = new ConsValueEnum(enumerator.Current, enumerator);\n                    }\n                    else\n                    {\n                        enumerator.Dispose();\n                        firstValue = Nil.Default;\n                    }\n\n                    firstAcquired = 2;\n                }\n                catch (Exception)\n                {\n                    firstAcquired = 0;\n                    throw;\n                }\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n\n        return firstValue!;\n    }\n}\n```\nThis all looks quite complex, but you should be able to see that the `Interlocked.CompareExchange`\nthen-block is where the `IEnumerator` is created.  We then either set `firstValue` to a new `ConsValueEnum` with \nthe head-item and the `enumerator` as arguments; or we set it to `Nil`.  \n\nUpon success, we set `firstAcquired` to `2`.  So, subsequent calls to `First` will just return `firstValue`.  This\nlocking technique without using locks is a way to efficiently protect the enumerator from race-conditions.\n\nSo, upon first access to either `Head` or `Tail` we launch the `IEnumerator` and cache the first item in the sequence. \nAll subsequent access goes to `Head` or `Tail` on either `Nil` or `ConsValueEnum`.  We never touch the `IEnumerator`\nagain in `ConsFirst`.\n\nThe `Nil` implementation isn't so surprising:\n```c#\npublic override A Head =>\n    throw new InvalidOperationException(\"Nil iterator has no head\");\n\npublic override Iterator<A> Tail =>\n    this;\n```\n`ConsValueEnum` is where it gets interesting.  It has the following internal fields:\n```c#\nException? exception;\nIEnumerator<A>? enumerator;\nint tailAcquired;\nIterator<A>? tailValue;\n```\nIt also has a `Head` property that is set in the constructor:\n```c#\npublic override A Head { get; }\n```\nSo, we can access the `Head` value at any time, but the `Tail` value isn't yet set:\n```c#\npublic override Iterator<A> Tail\n{\n    get\n    {\n        if(tailAcquired == 2) return tailValue!;\n        if(tailAcquired == 3) exception!.Rethrow();\n\n        SpinWait sw = default;\n        while (tailAcquired < 2)\n        {\n            if (Interlocked.CompareExchange(ref tailAcquired, 1, 0) == 0)\n            {   \n                try\n                {\n                    if (enumerator!.MoveNext())\n                    {\n                        tailValue = new ConsValueEnum(enumerator.Current, enumerator);\n                    }\n                    else\n                    {\n                        enumerator?.Dispose();\n                        enumerator = null;\n                        tailValue = Nil.Default;\n                    }\n\n                    tailAcquired = 2;\n                }\n                catch (Exception e)\n                {\n                    exception = e;\n                    tailAcquired = 3;\n                    throw;\n                }\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n\n        if(tailAcquired == 3) exception!.Rethrow();\n        return tailValue!;\n    }\n}\n```\nThis does a similar thing to `ConsFirst` of protecting a section with `Interlocked.CompareExchange`.  So, we can\nonly ever access the 'then' part [of that `if` statement] once.  In that block we `MoveNext` the `IEnumerator` \nwhich will either return `true` or `false`.  \n\nIf `true` then we create another `ConsValueEnum`, if `false` then we use `Nil`.  Whichever is created gets assigned\nto `tailValue` and `tailAcquired` gets set to `2`.  That means subsequent calls to `Tail` will just return\n`tailValue`.\n\nThat process continues for each item of the sequence until the `IEnumerator` runs out of items to yield.  The end\nresult is a linked-list of `ConsValueEnum` objects that have a `ConsFirst` object at the head of the linked-list.\n\nSo, `Iterator<A>` effectively caches the sequence as you go.  If you hold on to the head of the sequence, then the\nwhole list may end up in memory at once.  This could be problematic when working with large lazy sequences or even\ninfinite sequences.\n\nThis, for example, is fine:\n```c#\nfor(var iter = Naturals.GetIterator(); !iter.IsEmpty; iter = iter.Tail)\n{\n    Console.WriteLine(iter.Head);\n}\n```\nBecause the `iter` reference keeps getting updated, in-place, meaning that nothing is holding on to the head-item in\nthe sequence, and so the garbage-collector can collect those unreferenced items.\n\nWhereas this (below) will cause memory-usage to grow and grow:\n```c#\nvar start = Naturals.GetIterator();\nfor(var iter = start; !iter.IsEmpty; iter = iter.Tail)\n{\n    Console.WriteLine(iter.Head);\n}\n```\nBecause `start` is holding a reference to the first item, so it must hold a reference (indirectly) to every \nsubsequent item.  Meaning the garbage-collector can't collect.\n\nTo get around this you can use `Clone`:\n```c#\nvar start = Naturals.GetIterator();\nfor(var iter = start.Clone(); !iter.IsEmpty; iter = iter.Tail)\n{\n    Console.WriteLine(iter.Head);\n}\n```\nThis creates a new 'head' for the sequence and so `iter` is the only reference, meaning updates to `iter`\nmake the head elements free for garbage collection.\n\nSo, `Iterator<A>` is much, much more powerful than `IEnumerator<A>`.  It is mostly useful for immutable data-types \nthat need to carry an `IEnumerator<A>`, but can't due to its mutable-limitations.  `Iterator<A>` has some limitations of \nits own, but they are relatively easy to work around, whereas that isn't the case with `IEnumerator<A>` (without writing\na type like `Iterator<A>`!)."
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Iterator/Trait/Iterator.TraitImpl.cs",
    "content": "using System;\nusing System.Linq;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing G = System.Collections.Generic;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class Iterator : \n    Monad<Iterator>,\n    MonoidK<Iterator>,\n    Alternative<Iterator>, \n    Traversable<Iterator>,\n    Natural<Iterator, Arr>,\n    Natural<Iterator, Seq>,\n    Natural<Iterator, Lst>,\n    Natural<Iterator, Set>,\n    Natural<Iterator, Iterable>,\n    Natural<Iterator, HashSet>\n{\n    static K<Iterator, B> Monad<Iterator>.Recur<A, B>(A value, Func<A, K<Iterator, Next<A, B>>> f) =>\n        Monad.unsafeRecur(value, f);\n    \n    static K<Iterator, B> Monad<Iterator>.Bind<A, B>(K<Iterator, A> ma, Func<A, K<Iterator, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<Iterator, B> Functor<Iterator>.Map<A, B>(Func<A, B> f, K<Iterator, A> ma) => \n        ma.As().Map(f);\n\n    static K<Iterator, A> Applicative<Iterator>.Pure<A>(A value) =>\n        Cons(value, Nil<A>());\n\n    static K<Iterator, B> Applicative<Iterator>.Apply<A, B>(K<Iterator, Func<A, B>> mf, K<Iterator, A> ma)\n    {\n        return go().GetIterator();\n        G.IEnumerable<B> go()\n        {\n            for (var f = mf.As().Clone(); !f.IsEmpty; f = f.Tail)\n            {\n                for (var a = ma.As().Clone(); !a.IsEmpty; a = a.Tail)\n                {\n                    yield return f.Head(a.Head);\n                }\n            }\n        }\n    }\n\n    static K<Iterator, B> Applicative<Iterator>.Apply<A, B>(K<Iterator, Func<A, B>> mf, Memo<Iterator, A> ma)\n    {\n        return go().GetIterator();\n        G.IEnumerable<B> go()\n        {\n            for (var f = mf.As().Clone(); !f.IsEmpty; f = f.Tail)\n            {\n                for (var a = ma.Value.As().Clone(); !a.IsEmpty; a = a.Tail)\n                {\n                    yield return f.Head(a.Head);\n                }\n            }\n        }\n    }\n\n    static K<Iterator, A> MonoidK<Iterator>.Empty<A>() =>\n        Iterator<A>.Empty;\n\n    static K<Iterator, A> Alternative<Iterator>.Empty<A>() =>\n        Iterator<A>.Empty;\n\n    static K<Iterator, A> SemigroupK<Iterator>.Combine<A>(K<Iterator, A> ma, K<Iterator, A> mb) =>\n        ma.As().Concat(mb.As());\n\n    static K<Iterator, A> Choice<Iterator>.Choose<A>(K<Iterator, A> ma, K<Iterator, A> mb) => \n        ma.IsEmpty ? mb : ma;\n    \n    static K<Iterator, A> Choice<Iterator>.Choose<A>(K<Iterator, A> ma, Memo<Iterator, A> mb) => \n        ma.IsEmpty ? mb.Value : ma;\n    \n    static K<F, K<Iterator, B>> Traversable<Iterator>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Iterator, A> ta)\n    {\n        return Foldable.foldBack(add, F.Pure(Iterator<B>.Empty), ta)\n                       .Map(bs => bs.Kind());\n\n        Func<A, K<F, Iterator<B>>> add(K<F, Iterator<B>> state) =>\n            value =>\n              Applicative.lift((bs, b) => b.Cons(bs), state, f(value));                                            \n    }\n\n    static K<F, K<Iterator, B>> Traversable<Iterator>.TraverseM<F, A, B>(Func<A, K<F, B>> f, K<Iterator, A> ta) \n    {\n        return Foldable.foldBack(add, F.Pure(Iterator<B>.Empty), ta)\n                       .Map(bs => bs.Kind());\n\n        Func<A, K<F, Iterator<B>>> add(K<F, Iterator<B>> state) =>\n            value =>\n                state.Bind(\n                    bs => f(value).Bind(\n                        b => F.Pure(b.Cons(bs)))); \n    }\n\n    static S Foldable<Iterator>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Iterator, A> ta) =>\n        ta.As().FoldWhile(state, f, predicate);\n    \n    static S Foldable<Iterator>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S state, \n        K<Iterator, A> ta) =>\n        ta.As().FoldBackWhile(state, f, predicate);\n    \n    static Arr<A> Foldable<Iterator>.ToArr<A>(K<Iterator, A> ta) =>\n        new(ta.As());\n\n    static Lst<A> Foldable<Iterator>.ToLst<A>(K<Iterator, A> ta) =>\n        new(ta.As());\n\n    static Iterable<A> Foldable<Iterator>.ToIterable<A>(K<Iterator, A> ta) =>\n        Iterable.createRange(ta.As());\n    \n    static Seq<A> Foldable<Iterator>.ToSeq<A>(K<Iterator, A> ta) =>\n        new(ta.As());\n\n    static K<Seq, A> Natural<Iterator, Seq>.Transform<A>(K<Iterator, A> fa) => \n        toSeq(fa.As());\n\n    static K<Arr, A> Natural<Iterator, Arr>.Transform<A>(K<Iterator, A> fa) => \n        toArray(fa.As());\n\n    static K<Lst, A> Natural<Iterator, Lst>.Transform<A>(K<Iterator, A> fa) => \n        toList(fa.As());\n\n    static K<Set, A> Natural<Iterator, Set>.Transform<A>(K<Iterator, A> fa) => \n        toSet(fa.As());\n\n    static K<HashSet, A> Natural<Iterator, HashSet>.Transform<A>(K<Iterator, A> fa) => \n        toHashSet(fa.As());\n    \n    static K<Iterable, A> Natural<Iterator, Iterable>.Transform<A>(K<Iterator, A> fa) => \n        Iterable.createRange(fa.As());\n    \n    static Fold<A, S> Foldable<Iterator>.FoldStep<A, S>(K<Iterator, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }   \n        \n    static Fold<A, S> Foldable<Iterator>.FoldStepBack<A, S>(K<Iterator, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().Reverse().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/DSL/IteratorAsync.Cons.cs",
    "content": "using System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic abstract partial class IteratorAsync<A> \n{\n    /// <summary>\n    /// Cons iterator case.\n    ///\n    /// Contains a head value and a tail that represents the rest of the sequence.\n    /// </summary>\n    public abstract class Cons : IteratorAsync<A>\n    {\n        public void Deconstruct(out ValueTask<A> head, out ValueTask<IteratorAsync<A>> tail)\n        {\n            head = Head;\n            tail = Tail;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/DSL/IteratorAsync.ConsFirst.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic abstract partial class IteratorAsync<A> \n{\n    internal sealed class ConsFirst : Cons\n    {\n        IAsyncEnumerable<A> enumerable;\n        int firstAcquired;\n        IteratorAsync<A>? firstValue;\n\n        internal ConsFirst(IAsyncEnumerable<A> enumerable) =>\n            this.enumerable = enumerable;\n\n        public override ValueTask<A> Head =>\n            First().Bind(f => f.Head);\n\n        public override ValueTask<IteratorAsync<A>> Tail =>\n            First().Bind(f => f.Tail);\n\n        public new void Deconstruct(out ValueTask<A> head, out ValueTask<IteratorAsync<A>> tail)\n        {\n            head = Head;\n            tail = Tail;\n        }\n\n        async ValueTask<IteratorAsync<A>> First()\n        {\n            if (firstAcquired == 2) return firstValue!;\n            \n            SpinWait sw = default;\n            while (firstAcquired < 2)\n            {\n                if (Interlocked.CompareExchange(ref firstAcquired, 1, 0) == 0)\n                {\n                    try\n                    {\n                        var enumerator = enumerable.GetAsyncEnumerator();\n                        if (await enumerator.MoveNextAsync())\n                        {\n                            firstValue = new ConsValueEnum(new(enumerator.Current), enumerator);\n                        }\n                        else\n                        {\n                            await enumerator.DisposeAsync();\n                            firstValue = Nil.Default;\n                        }\n\n                        firstAcquired = 2;\n                    }\n                    catch (Exception)\n                    {\n                        firstAcquired = 0;\n                        throw;\n                    }\n                }\n                else\n                {\n                    sw.SpinOnce();\n                }\n            }\n            return firstValue!;\n        }\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override ValueTask<bool> IsEmpty =>\n            First().Bind(f => f.IsEmpty);\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override IteratorAsync<A> Clone() =>\n            new ConsFirst(enumerable);\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override IteratorAsync<A> Split() =>\n            Clone();\n\n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override ValueTask<long> Count =>\n            First().Bind(f => f.Count);\n\n        public override async ValueTask DisposeAsync()\n        {\n            if (Interlocked.CompareExchange(ref firstAcquired, 1, 2) == 2)\n            {\n                var fv = firstValue;\n                if(fv != null) await fv.DisposeAsync();\n                firstValue = null;\n                firstAcquired = 0;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/DSL/IteratorAsync.ConsValue.cs",
    "content": "using System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic abstract partial class IteratorAsync<A> \n{\n    internal sealed class ConsValue : Cons\n    {\n        readonly A head;\n        readonly IteratorAsync<A> tail;\n\n        public ConsValue(A head, IteratorAsync<A> tail)\n        {\n            this.head = head;\n            this.tail = tail;\n        }\n        \n        public new void Deconstruct(out ValueTask<A> h, out ValueTask<IteratorAsync<A>> t)\n        {\n            h = Head;\n            t = Tail;\n        }\n\n        /// <summary>\n        /// Head element\n        /// </summary>\n        public override ValueTask<A> Head => new(head);\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        public override ValueTask<IteratorAsync<A>> Tail => new(tail);\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override ValueTask<bool> IsEmpty =>\n            new(false);\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override IteratorAsync<A> Clone() =>\n            new ConsValue(head, tail.Clone());\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override IteratorAsync<A> Split() =>\n            this;\n\n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override ValueTask<long> Count =>\n            Tail.Bind(t => t.Count.Map(c => c + 1));\n        \n        public override async ValueTask DisposeAsync() =>\n            await (await Tail).DisposeAsync();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/DSL/IteratorAsync.ConsValueEnum.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Wrapper for `IEnumerator` that makes it work like an immutable sequence.\n/// \n/// It is thread-safe and impossible for any item in the sequence to be enumerated more than once.\n/// </summary>\n/// <remarks>\n/// `IEnumerator` from the .NET BCL has several problems: \n///\n///    * It's very imperative\n///    * It's not thread-safe, two enumerators can't be shared\n/// \n/// The lack of support for sharing of enumerators means that it's problematic using it internally\n/// in types like `StreamT`, or anything that needs to keep an `IEnumerator` alive for any period\n/// of time.\n///\n/// NOTE: There is a per-item allocation to hold the state of the iterator.  These are discarded as\n/// you enumerate the sequence.  However, technically it is possible to hold the initial `Iterator`\n/// value and subsequently gain a cached sequence of every item encountered in the enumerator.\n///\n/// That may well be valuable for circumstances where re-evaluation would be expensive.  However,\n/// for infinite-streams this would be extremely problematic.  So, make sure you discard any\n/// previous `IteratorAsync` values as you walk the sequence. \n/// </remarks>\n/// <typeparam name=\"A\">Item value type</typeparam>\npublic abstract partial class IteratorAsync<A> \n{\n    internal sealed class ConsValueEnum : Cons\n    {\n        Exception? exception;\n        IAsyncEnumerator<A>? enumerator;\n        int tailAcquired;\n        IteratorAsync<A>? tailValue;\n\n        internal ConsValueEnum(ValueTask<A> head, IAsyncEnumerator<A> enumerator)\n        {\n            Head = head;\n            this.enumerator = enumerator;\n        }\n\n        public new void Deconstruct(out ValueTask<A> head, out ValueTask<IteratorAsync<A>> tail)\n        {\n            head = Head;\n            tail = Tail;\n        }\n\n        /// <summary>\n        /// Head element\n        /// </summary>\n        public override ValueTask<A> Head { get; }\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        public override ValueTask<IteratorAsync<A>> Tail\n        {\n            get\n            {\n                if(tailAcquired == 2) return new(tailValue!);\n                if(tailAcquired == 3) exception!.Rethrow();\n                return TailAsync();\n            }\n        }\n        \n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        async ValueTask<IteratorAsync<A>> TailAsync()\n        {\n            SpinWait sw = default;\n            while (tailAcquired < 2)\n            {\n                if (Interlocked.CompareExchange(ref tailAcquired, 1, 0) == 0)\n                {\n                    try\n                    {\n                        if (await enumerator!.MoveNextAsync())\n                        {\n                            tailValue = new ConsValueEnum(new(enumerator.Current), enumerator);\n                        }\n                        else\n                        {\n                            var e = enumerator;\n                            if(e != null) await e.DisposeAsync();\n                            enumerator = null;\n                            tailValue = Nil.Default;\n                        }\n\n                        tailAcquired = 2;\n                    }\n                    catch (Exception e)\n                    {\n                        exception = e;\n                        tailAcquired = 3;\n                        throw;\n                    }\n                }\n                else\n                {\n                    sw.SpinOnce();\n                }\n            }\n\n            if(tailAcquired == 3) exception!.Rethrow();\n            return tailValue!;\n        }\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override ValueTask<bool> IsEmpty =>\n            new(false);\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override IteratorAsync<A> Clone() =>\n            this;\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override IteratorAsync<A> Split()\n        {\n            if (Interlocked.CompareExchange(ref tailAcquired, 1, 0) == 0)\n            {\n                tailValue = Nil.Default;\n                tailAcquired = 2;\n                return new ConsValueEnum(Head, enumerator!);\n            }\n            else\n            {\n                return this;\n            }\n        }\n        \n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override ValueTask<long> Count =>\n            Tail.Bind(t => t.Count.Map(c => c + 1));\n        \n        public override async ValueTask DisposeAsync()\n        {\n            var e = enumerator;\n            if(e != null) await e.DisposeAsync();\n            enumerator = null;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/DSL/IteratorAsync.ConsValueLazy.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\npublic abstract partial class IteratorAsync<A> \n{\n    internal sealed class ConsValueLazy : Cons\n    {\n        ValueTask<A> head;\n        Exception? error;\n        IteratorAsync<A>? tail;\n        Func<IteratorAsync<A>>? tailF;\n        int tailAcquired;\n\n        public ConsValueLazy(ValueTask<A> head, Func<IteratorAsync<A>> tailF)\n        {\n            this.head = head;\n            this.tailF = tailF;\n            tail = null;\n        }\n        \n        public new void Deconstruct(out ValueTask<A> h, out ValueTask<IteratorAsync<A>> t)\n        {\n            h = Head;\n            t = Tail;\n        }\n\n        /// <summary>\n        /// Head element\n        /// </summary>\n        public override ValueTask<A> Head => head;\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        public override ValueTask<IteratorAsync<A>> Tail\n        {\n            get\n            {\n                if (tailAcquired == 2) return new(tail!);\n                if (tailAcquired == 3) error!.Rethrow();\n                return TailLazy();\n            }\n        }\n\n        ValueTask<IteratorAsync<A>> TailLazy()\n        {\n            SpinWait sw = default;\n            while (tailAcquired < 2)\n            {\n                if (Interlocked.CompareExchange(ref tailAcquired, 1, 0) == 0)\n                {\n                    try\n                    {\n                        tail = tailF!();\n                        tailF = null;\n                        tailAcquired = 2;\n                    }\n                    catch(Exception e)\n                    {\n                        error = e;\n                        tailF = null;\n                        tailAcquired = 3;\n                        throw;\n                    }\n                }\n                else\n                {\n                    sw.SpinOnce();\n                }\n            }\n\n            return new(tail!);\n        }\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override ValueTask<bool> IsEmpty =>\n            new(false);\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override IteratorAsync<A> Clone() =>\n            this;\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override IteratorAsync<A> Split()\n        {\n            var h = head;\n            var t = tailF;\n            return tailAcquired == 0\n                       ? new ConsValueLazy(h, t!)\n                       : this;\n        }\n\n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override ValueTask<long> Count =>\n            Tail.Bind(static t => t.Count.Map(static c => c + 1));\n\n        public override async ValueTask DisposeAsync()\n        {\n            if (tailAcquired == 2)\n            {\n                await (await Tail).DisposeAsync();\n            }\n        }\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/DSL/IteratorAsync.Nil.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic abstract partial class IteratorAsync<A>\n{\n    /// <summary>\n    /// Nil iterator case\n    ///\n    /// The end of the sequence.\n    /// </summary>\n    public sealed class Nil : IteratorAsync<A>\n    {\n        public static readonly IteratorAsync<A> Default = new Nil();\n\n        /// <summary>\n        /// Head element\n        /// </summary>\n        public override ValueTask<A> Head =>\n            throw new InvalidOperationException(\"Nil iterator has no head\");\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        public override ValueTask<IteratorAsync<A>> Tail =>\n            new(this);\n\n        /// <summary>\n        /// Return true if there are no elements in the sequence.\n        /// </summary>\n        public override ValueTask<bool> IsEmpty =>\n            new(true);\n\n        /// <summary>\n        /// Clone the iterator so that we can consume it without having the head item referenced.\n        /// This will stop any GC pressure.\n        /// </summary>\n        public override IteratorAsync<A> Clone() =>\n            this;\n\n        /// <summary>\n        /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n        /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n        /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n        /// can't be garbage collected. \n        /// </summary>\n        /// <returns>New iterator that starts from the current iterator position</returns>\n        public override IteratorAsync<A> Split() =>\n            this;\n\n        /// <summary>\n        /// Return the number of items in the sequence.\n        /// </summary>\n        /// <remarks>\n        /// Requires all items to be evaluated, this will happen only once however.\n        /// </remarks>\n        [Pure]\n        public override ValueTask<long> Count =>\n            new(0);\n\n        public override ValueTask DisposeAsync() =>\n            ValueTask.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/Extensions/IteratorAsync.Extensions.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IteratorAsyncExtensions\n{\n    /// <summary>\n    /// Downcast operator\n    /// </summary>\n    public static IteratorAsync<A> As<A>(this K<IteratorAsync, A> ma) =>\n        (IteratorAsync<A>)ma;\n    \n    /// <summary>\n    /// Get an iterator for any `IAsyncEnumerable` \n    /// </summary>\n    public static IteratorAsync<A> GetIteratorAsync<A>(this IAsyncEnumerable<A> enumerable) =>\n        IteratorAsync.from(enumerable);\n\n}\n\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/IteratorAsync.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\npublic partial class IteratorAsync\n{\n    /// <summary>\n    /// Create an iterator from an `IAsyncEnumerable`\n    /// </summary>\n    /// <param name=\"enumerable\"></param>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    public static IteratorAsync<A> from<A>(IAsyncEnumerable<A> enumerable) =>\n        new IteratorAsync<A>.ConsFirst(enumerable);\n\n    /// <summary>\n    /// Construct a singleton sequence \n    /// </summary>\n    /// <param name=\"head\">Head item</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IteratorAsync</returns>\n    public static IteratorAsync<A> singleton<A>(A head) =>\n        new IteratorAsync<A>.ConsValue(head, IteratorAsync<A>.Nil.Default);\n\n    /// <summary>\n    /// Construct a sequence from a head item and a tail sequence\n    /// </summary>\n    /// <param name=\"head\">Head item</param>\n    /// <param name=\"tail\">Tail sequences</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IteratorAsync</returns>\n    public static IteratorAsync<A> Cons<A>(A head, IteratorAsync<A> tail) =>\n        new IteratorAsync<A>.ConsValue(head, tail);\n\n    /// <summary>\n    /// Construct a sequence from a head item and a tail sequence\n    /// </summary>\n    /// <param name=\"head\">Head item</param>\n    /// <param name=\"tail\">Tail sequences</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IteratorAsync</returns>\n    public static IteratorAsync<A> Cons<A>(A head, Func<IteratorAsync<A>> tail) =>\n        new IteratorAsync<A>.ConsValueLazy(new(head), tail);\n\n    /// <summary>\n    /// Empty sequence\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>IteratorAsync</returns>\n    public static IteratorAsync<A> Nil<A>() =>\n        IteratorAsync<A>.Nil.Default;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/IteratorAsync.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Wrapper for `IEnumerator` that makes it work like an immutable sequence.\n/// \n/// It is thread-safe and impossible for any item in the sequence to be enumerated more than once.\n/// </summary>\n/// <remarks>\n/// `IEnumerator` from the .NET BCL has several problems: \n///\n///    * It's very imperative\n///    * It's not thread-safe, two enumerators can't be shared\n/// \n/// The lack of support for sharing of enumerators means that it's problematic using it internally\n/// in types like `StreamT`, or anything that needs to keep an `IEnumerator` alive for any period\n/// of time.\n///\n/// NOTE: There is a per-item allocation to hold the state of the iterator.  These are discarded as\n/// you enumerate the sequence.  However, technically it is possible to hold the initial `Iterator`\n/// value and subsequently gain a cached sequence of every item encountered in the enumerator.\n///\n/// That may well be valuable for circumstances where re-evaluation would be expensive.  However,\n/// for infinite-streams this would be extremely problematic.  So, make sure you discard any\n/// previous `IteratorAsync` values as you walk the sequence. \n/// </remarks>\npublic abstract partial class IteratorAsync<A> : \n    IAsyncEnumerable<A>,\n    IAsyncDisposable,\n    K<IteratorAsync, A>\n{\n    /// <summary>\n    /// Empty iterator\n    /// </summary>\n    public static readonly IteratorAsync<A> Empty = new Nil();\n    \n    /// <summary>\n    /// Head element\n    /// </summary>\n    [Pure]\n    public abstract ValueTask<A> Head { get; }\n\n    /// <summary>\n    /// Tail of the sequence\n    /// </summary>\n    [Pure]\n    public abstract ValueTask<IteratorAsync<A>> Tail { get; }\n    \n    /// <summary>\n    /// Return true if there are no elements in the sequence.\n    /// </summary>\n    [Pure]\n    public abstract ValueTask<bool> IsEmpty  { get; }\n    \n    /// <summary>\n    /// Return the number of items in the sequence.\n    /// </summary>\n    /// <remarks>\n    /// Requires all items to be evaluated, this will happen only once however.\n    /// </remarks>\n    [Pure]\n    public abstract ValueTask<long> Count  { get; }\n\n    /// <summary>\n    /// Clone the iterator so that we can consume it without having the head item referenced.\n    /// This will stop any GC pressure when processing large or infinite sequences.\n    /// </summary>\n    [Pure]\n    public abstract IteratorAsync<A> Clone();\n\n    /// <summary>\n    /// When iterating a sequence, it is possible (before evaluation of the `Tail`) to Terminate the current\n    /// iterator and to take a new iterator that continues on from the current location.  The reasons for doing\n    /// this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that\n    /// can't be garbage collected. \n    /// </summary>\n    /// <remarks>\n    /// Any other iterator references that came before this one will terminate at this point.  Splitting the\n    /// previous and subsequent iterators here. \n    /// </remarks>\n    /// <returns>New iterator that starts from the current iterator position.</returns>\n    public abstract IteratorAsync<A> Split();\n\n    /// <summary>\n    /// Create an `IEnumerable` from an `Iterator`\n    /// </summary>\n    [Pure]\n    public async IAsyncEnumerable<A> AsEnumerable([EnumeratorCancellation] CancellationToken token)\n    {\n        for (var ma = Clone(); !await ma.IsEmpty; ma = await ma.Tail)\n        {\n            if (token.IsCancellationRequested) throw new OperationCanceledException();\n            yield return await ma.Head;\n        }\n    }\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    [Pure]\n    public IteratorAsync<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    [Pure]\n    public IteratorAsync<B> Map<B>(Func<A, B> f)\n    {\n        return Go(this, f).GetIteratorAsync();\n        static async IAsyncEnumerable<B> Go(IteratorAsync<A> ma, Func<A, B> f)\n        {\n            for (var a = ma.Clone(); !await a.IsEmpty; a = await a.Tail)\n            {\n                yield return f(await a.Head);\n            }\n        }\n    }\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public IteratorAsync<B> Bind<B>(Func<A, IteratorAsync<B>> f)\n    {\n        return Go(this, f).GetIteratorAsync();\n        static async IAsyncEnumerable<B> Go(IteratorAsync<A> ma, Func<A, IteratorAsync<B>> f)\n        {\n            for (var a = ma.Clone(); !await a.IsEmpty; a = await a.Tail)\n            {\n                for (var b = f(await a.Head); !await b.IsEmpty; b = await b.Tail)\n                {\n                    yield return await b.Head;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public IteratorAsync<C> SelectMany<B, C>(Func<A, IteratorAsync<B>> bind, Func<A, B, C> project)\n    {\n        return Go(this, bind, project).GetIteratorAsync();\n        static async IAsyncEnumerable<C> Go(IteratorAsync<A> ma, Func<A, IteratorAsync<B>> bind, Func<A, B, C> project)\n        {\n            for (var a = ma.Clone(); !await a.IsEmpty; a = await a.Tail)\n            {\n                for (var b = bind(await a.Head); !await b.IsEmpty; b = await b.Tail)\n                {\n                    yield return project(await a.Head, await b.Head);\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Applicative apply\n    /// </summary>\n    [Pure]\n    public IteratorAsync<B> Apply<B>(IteratorAsync<Func<A, B>> ff, IteratorAsync<A> fa)\n    {\n        return Go(ff, fa).GetIteratorAsync();\n        static async IAsyncEnumerable<B> Go(IteratorAsync<Func<A, B>> ff, IteratorAsync<A> fa)\n        {\n            for (var f = ff.Clone(); !await f.IsEmpty; f = await f.Tail)\n            {\n                for (var a = fa.Clone(); !await a.IsEmpty; a = await a.Tail)\n                {\n                    yield return (await f.Head)(await a.Head);\n                }\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Concatenate two iterators\n    /// </summary>\n    [Pure]\n    public IteratorAsync<A> Concat(IteratorAsync<A> other)\n    {\n        return Go(this, other).GetIteratorAsync();\n        static async IAsyncEnumerable<A> Go(IteratorAsync<A> ma, IteratorAsync<A> mb)\n        {\n            for (var a = ma.Clone(); !await a.IsEmpty; a = await a.Tail)\n            {\n                yield return await ma.Head;\n            }\n            for (var b = mb.Clone(); !await b.IsEmpty; b = await b.Tail)\n            {\n                yield return await mb.Head;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Fold the sequence while there are more items remaining\n    /// </summary>\n    [Pure]\n    public async ValueTask<S> Fold<S>(\n        S state,\n        Func<A, Func<S, S>> f)\n    {\n        for(var xs = Clone(); !await xs.IsEmpty; xs = await xs.Tail)\n        {\n            state = f(await xs.Head)(state);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence while there are more items remaining\n    /// </summary>\n    [Pure]\n    public async ValueTask<S> Fold<S>(        \n        S state,\n        Func<S, A, S> f)\n    {\n        for(var xs = Clone(); !await xs.IsEmpty; xs = await xs.Tail)\n        {\n            state = f(state, await xs.Head);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence while the predicate returns `true` and there are more items remaining\n    /// </summary>\n    [Pure]\n    public async ValueTask<S> FoldWhile<S>(\n        S state,\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate)\n    {\n        for(var xs = Clone(); !await xs.IsEmpty; xs = await xs.Tail)\n        {\n            if (!predicate((state, await xs.Head))) return state;\n            state = f(await xs.Head)(state);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence while the predicate returns `true` and there are more items remaining\n    /// </summary>\n    [Pure]\n    public async ValueTask<S> FoldWhile<S>(\n        S state,\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate)\n    {\n        for(var xs = Clone(); !await xs.IsEmpty; xs = await xs.Tail)\n        {\n            if (!predicate((state, await xs.Head))) return state;\n            state = f(state, await xs.Head);\n        }\n        return state;\n    }\n    \n    /// <summary>\n    /// Fold the sequence until the predicate returns `true` or the sequence ends\n    /// </summary>\n    [Pure]\n    public async ValueTask<S> FoldUntil<S>(\n        S state,\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate)\n    {\n        for(var xs = Clone(); !await xs.IsEmpty; xs = await xs.Tail)\n        {\n            state = f(await xs.Head)(state);\n            if (predicate((state, await xs.Head))) return state;\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence until the predicate returns `true` or the sequence ends\n    /// </summary>\n    [Pure]\n    public async ValueTask<S> FoldUntil<S>(\n        S state,\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate)\n    {\n        for(var xs = Clone(); !await xs.IsEmpty; xs = await xs.Tail)\n        {\n            state = f(state, await xs.Head);\n            if (predicate((state, await xs.Head))) return state;\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Interleave two iterator sequences together\n    /// </summary>\n    /// <remarks>\n    /// Whilst there are items in both sequences, each is yielded after the other.  Once one sequence\n    /// runs out of items, the remaining items of the other sequence is yielded alone.\n    /// </remarks>\n    [Pure]\n    public IteratorAsync<A> Merge(IteratorAsync<A> other)\n    {\n        return Go(this, other).GetIteratorAsync();        \n        static async IAsyncEnumerable<A> Go(IteratorAsync<A> ma, IteratorAsync<A> mb)\n        {\n            var a = ma.Clone();\n            var b = mb.Clone();\n\n            // TODO: Replace this with a WaitAny tasks for each side, replacing the \n            //       task as each one yields.\n            \n            while (!await a.IsEmpty && !await b.IsEmpty)\n            {\n                yield return await a.Head;\n                yield return await b.Head;\n                a = await a.Tail;\n                b = await b.Tail;\n            }\n\n            if (await a.IsEmpty)\n            {\n                while (!await b.IsEmpty)\n                {\n                    yield return await b.Head;\n                    b = await b.Tail;\n                }\n            }\n            else\n            {\n                while (!await a.IsEmpty)\n                {\n                    yield return await a.Head;\n                    a = await a.Tail;\n                }\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Zips the items of two sequences together\n    /// </summary>\n    /// <remarks>\n    /// The output sequence will be as long as the shortest input sequence.\n    /// </remarks>\n    [Pure]\n    public IteratorAsync<(A First , A Second)> Zip(IteratorAsync<A> other)\n    {\n        return Go(this, other).GetIteratorAsync();        \n        static async IAsyncEnumerable<(A First , A Second)> Go(IteratorAsync<A> ma, IteratorAsync<A> mb)\n        {\n            var a = ma.Clone();\n            var b = mb.Clone();\n\n            while (!await a.IsEmpty && !await b.IsEmpty)\n            {\n                yield return (await a.Head, await b.Head);\n                a = await a.Tail;\n                b = await b.Tail;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Combine two sequences\n    /// </summary>\n    public static IteratorAsync<A> operator +(IteratorAsync<A> ma, IteratorAsync<A> mb) =>\n        ma.Concat(mb);\n\n    /// <summary>\n    /// Dispose\n    /// </summary>\n    public abstract ValueTask DisposeAsync();\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public IAsyncEnumerator<A> GetAsyncEnumerator(CancellationToken token) => \n        AsEnumerable(token).GetAsyncEnumerator(token);\n\n    [Pure]\n    public override string ToString() =>\n        \"async iterator\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/Operators/IteratorAsync.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IteratorAsyncExtensions\n{\n    extension<A>(K<IteratorAsync, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static IteratorAsync<A> operator +(K<IteratorAsync, A> ma) =>\n            (IteratorAsync<A>)ma;\n        \n        public static IteratorAsync<A> operator >> (K<IteratorAsync, A> ma, Lower lower) =>\n            (IteratorAsync<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/README.md",
    "content": "`IteratorAsync<A>` is a functional-wrapper for `IAsyncEnumerator<A>`.  The abstraction leaks a little, so it's worth \nunderstanding how it works by reading the details below.  On the whole it behaves like an immutable stream \nthat caches values as it goes, but there's some footguns that you should be aware of so that they can be \navoided.\n\n## Problem: `IAsyncEnumerator<A>`\n\n* It is mutable which means using it in immutable data-structures is problematic. \n* If you pass an `IAsyncEnumerator` reference to two threads, each thread can \ncall `MoveNext`and it will move the enumeration position for other thread, or even worse, move past the end\nof the sequence due to race conditions.\n* Enumerators start before the first item and use a complicated mechanism for accessing and testing the validity of\nthe element value.\n\n_Nobody in their right mind would invent an interface like `IAsyncEnumerator<A>` today._\n\n## Solution: `IteratorAsync<A>`\n\n`IteratorAsync<A>` still uses `IAsyncEnumerator<A>` internally, but it makes it thread-safe and functional.  From the outside\nthe type acts and works exactly like any other immutable sequence, but internally it does some quite complex\nprocessing to achieve this with an `IAsyncEnumerator<A>` reference.\n\n> You may say \"Why not just drop `IAsyncEnumerator<A>`?\" - which is a completely valid position to hold. Unfortunately, \n> `IAsyncEnumerable` and `IAsyncEnumerator` are baked into the CPS state-machine that is used for `yield return` and \n> `yield break`.  So, we don't get to ignore those types, and instead we need to make them play nice.\n\n`IAsyncEnumerable<A>` has a method called `GetAsyncEnumerator()` which is used to access an `IAsyncEnumerator<A>`.  A new extension\nmethod is available called `GetIteratorAsync()`, this will yield an `IteratorAsync<A>`.\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/IteratorAsync/Trait/IteratorAsync.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing G = System.Collections.Generic;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class IteratorAsync : \n    Monad<IteratorAsync>\n{\n    static K<IteratorAsync, B> Monad<IteratorAsync>.Recur<A, B>(A value, Func<A, K<IteratorAsync, Next<A, B>>> f) =>\n        Monad.unsafeRecur(value, f);\n    \n    static K<IteratorAsync, B> Monad<IteratorAsync>.Bind<A, B>(K<IteratorAsync, A> ma, Func<A, K<IteratorAsync, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<IteratorAsync, B> Functor<IteratorAsync>.Map<A, B>(Func<A, B> f, K<IteratorAsync, A> ma) => \n        ma.As().Map(f);\n\n    static K<IteratorAsync, A> Applicative<IteratorAsync>.Pure<A>(A value) =>\n        Cons(value, Nil<A>());\n\n    static K<IteratorAsync, B> Applicative<IteratorAsync>.Apply<A, B>(K<IteratorAsync, Func<A, B>> mf, K<IteratorAsync, A> ma) \n    {\n        return from(go());\n\n        async G.IAsyncEnumerable<B> go()\n        {\n            for (var fi = mf.As().Clone(); !await fi.IsEmpty; fi = await fi.Tail)\n            {\n                for (var ai = ma.As().Clone(); !await ai.IsEmpty; ai = await ai.Tail)\n                {\n                    yield return (await fi.Head)(await ai.Head);\n                }\n            }\n        }        \n    }   \n    \n    static K<IteratorAsync, B> Applicative<IteratorAsync>.Apply<A, B>(\n        K<IteratorAsync, Func<A, B>> mf, Memo<IteratorAsync, A> ma)\n    {\n        return from(go());\n\n        async G.IAsyncEnumerable<B> go()\n        {\n            for (var fi = mf.As().Clone(); !await fi.IsEmpty; fi = await fi.Tail)\n            {\n                for (var ai = ma.Value.As().Clone(); !await ai.IsEmpty; ai = await ai.Tail)\n                {\n                    yield return (await fi.Head)(await ai.Head);\n                }\n            }\n        }        \n    }   \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/Extensions/Lst.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class LstExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Lst<B> Map<A, B>(this Func<A, B> f, K<Lst, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Lst<B> Map<A, B>(this Func<A, B> f, Lst<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Lst<B> Action<A, B>(this Lst<A> ma, K<Lst, B> mb) =>\n        Applicative.action(ma, mb).As();    \n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Lst<B> Action<A, B>(this K<Lst, A> ma, K<Lst, B> mb) =>\n        Applicative.action(ma, mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Lst<B> Apply<A, B>(this Lst<Func<A, B>> mf, K<Lst, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Lst<B> Apply<A, B>(this K<Lst, Func<A, B>> mf, K<Lst, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/Extensions/Lst.Extensions.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Text;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class LstExtensions\n{\n    public static Lst<A> As<A>(this K<Lst, A> xs) =>\n        (Lst<A>)xs;\n\n    /// <summary>\n    /// Accesses the head of an enumerable and yields the remainder without multiple-enumerations\n    /// </summary>\n    /// <exception cref=\"ExpectedException\">Throws if sequence is empty</exception>\n    public static (A Head, IEnumerable<A> Tail) HeadAndTail<A>(this IEnumerable<A> ma) =>\n        ma.HeadAndTailSafe()\n          .IfNone(() => throw Exceptions.SequenceEmpty);\n    \n    /// <summary>\n    /// Accesses the head of an enumerable and yields the remainder without multiple-enumerations\n    /// </summary>\n    public static Option<(A Head, IEnumerable<A> Tail)> HeadAndTailSafe<A>(this IEnumerable<A> ma)\n    {\n        var iter = ma.GetEnumerator();\n        A head;\n        if (iter.MoveNext())\n        {\n            head = iter.Current;\n        }\n        else\n        {\n            iter.Dispose();\n            return None;\n        }\n        return Some((head, tail(iter)));\n\n        static IEnumerable<A> tail(IEnumerator<A> rest)\n        {\n            try\n            {\n                while (rest.MoveNext())\n                {\n                    yield return rest.Current;\n                }\n            }\n            finally\n            {\n                rest.Dispose();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Lst<A> Flatten<A>(this Lst<Lst<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static IEnumerable<A> Flatten<A>(this IEnumerable<IEnumerable<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Match empty list, or multi-item list\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"More\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    public static B Match<A, B>(this IEnumerable<A> list,\n        Func<B> Empty,\n        Func<Seq<A>, B> More) =>\n        toSeq(list).Match(Empty, More);\n\n    /// <summary>\n    /// List pattern matching\n    /// </summary>\n    [Pure]\n    public static B Match<A, B>(this IEnumerable<A> list,\n        Func<B> Empty,\n        Func<A, Seq<A>, B> More) =>\n        toSeq(list).Match(Empty, More);\n\n    /// <summary>\n    /// List pattern matching\n    /// </summary>\n    [Pure]\n    public static R Match<T, R>(this IEnumerable<T> list,\n        Func<R> Empty,\n        Func<T, R> One,\n        Func<T, Seq<T>, R> More ) =>\n        toSeq(list).Match(Empty, One, More);\n\n    /// <summary>\n    /// Get all items in the list except the last one\n    /// </summary>\n    /// <remarks>\n    /// Must evaluate the last item to know it's the last, but won't return it\n    /// </remarks>\n    /// <param name=\"list\">List</param>\n    /// <returns>The initial items (all but the last)</returns>\n    [Pure]\n    public static IEnumerable<A> Init<A>(this IEnumerable<A> list) =>\n        List.init(list);\n\n    /// <summary>\n    /// Get the tail of the list (skips the head item)\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Enumerable of T</returns>\n    [Pure]\n    public static Iterable<T> Tail<T>(this IEnumerable<T> list) =>\n        List.tail(list);\n\n    /// <summary>\n    /// Inject a value in between each item in the enumerable \n    /// </summary>\n    /// <param name=\"ma\">Enumerable to inject values into</param>\n    /// <param name=\"value\">Item to inject</param>\n    /// <typeparam name=\"A\">Bound type</typeparam>\n    /// <returns>An enumerable with the values injected</returns>\n    [Pure]\n    public static IEnumerable<A> Intersperse<A>(this IEnumerable<A> ma, A value)\n    {\n        var isFirst = true;\n        foreach(var item in ma)\n        {\n            if (!isFirst)\n            {\n                yield return value;\n            }\n\n            yield return item;\n            isFirst = false;\n        }\n    }\n\n    /// <summary>\n    /// Concatenate all strings into one\n    /// </summary>\n    [Pure]\n    public static string Concat(this IEnumerable<string> xs)\n    {\n        var sb = new StringBuilder();\n        foreach (var x in xs)\n        {\n            sb.Append(x);\n        }\n\n        return sb.ToString();\n    }\n\n    /// <summary>\n    /// Reverses the list (Reverse in LINQ)\n    /// </summary>\n    /// <typeparam name=\"A\">List item type</typeparam>\n    /// <param name=\"list\">Listto reverse</param>\n    /// <returns>Reversed list</returns>\n    [Pure]\n    public static Lst<A> Rev<A>(this Lst<A> list) =>\n        List.rev(list);\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from last element to first), threading \n    /// an accumulator argument through the computation. This function first applies the function \n    /// to the first two elements of the list. Then, it passes this result into the function along \n    /// with the third element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to reduce</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static T Reduce<T>(this IEnumerable<T> list, Func<T, T, T> reducer) =>\n        List.reduce(list, reducer);\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function first applies the function to the first two \n    /// elements of the list. Then, it passes this result into the function along with the third \n    /// element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to reduce</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static T ReduceBack<T>(this IEnumerable<T> list, Func<T, T, T> reducer) =>\n        List.reduceBack(list, reducer);\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function takes the state argument, and applies the function \n    /// to it and the first element of the list. Then, it passes this result into the function \n    /// along with the second element, and so on. Finally, it returns the list of intermediate \n    /// results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static IEnumerable<S> Scan<S, T>(this IEnumerable<T> list, S state, Func<S, T, S> folder) =>\n        List.scan(list, state, folder);\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from last element to first), \n    /// threading an accumulator argument through the computation. This function takes the state \n    /// argument, and applies the function to it and the first element of the list. Then, it \n    /// passes this result into the function along with the second element, and so on. Finally, \n    /// it returns the list of intermediate results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static IEnumerable<S> ScanBack<S, T>(this IEnumerable<T> list, S state, Func<S, T, S> folder) =>\n        List.scanBack(list, state, folder);\n\n    /// <summary>\n    /// Iterate each item in the enumerable in order (consume items)\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to consume</param>\n    /// <returns>Unit</returns>\n    public static Unit Consume<T>(this IEnumerable<T> list) =>\n        List.consume(list);\n\n    /// <summary>\n    /// Return a new enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <returns>A new enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static IEnumerable<T> Distinct<EQ, T>(this IEnumerable<T> list) where EQ : Eq<T> =>\n        List.distinct<EQ, T>(list);\n\n    /// <summary>\n    /// The tails function returns all final segments of the argument, longest first. For example,\n    ///  i.e. tails(['a','b','c']) == [['a','b','c'], ['b','c'], ['c'],[]]\n    /// </summary>\n    /// <typeparam name=\"T\">List item type</typeparam>\n    /// <param name=\"self\">List</param>\n    /// <returns>Enumerable of Enumerables of T</returns>\n    [Pure]\n    public static IEnumerable<IEnumerable<T>> Tails<T>(this IEnumerable<T> self) =>\n        List.tails(self);\n\n    /// <summary>\n    /// Span, applied to a predicate 'pred' and a list, returns a tuple where first element is \n    /// longest prefix (possibly empty) of elements that satisfy 'pred' and second element is the \n    /// remainder of the list:\n    /// </summary>\n    /// <example>\n    /// List.span(List(1,2,3,4,1,2,3,4), x => x 〈 3) == (List(1,2),List(3,4,1,2,3,4))\n    /// </example>\n    /// <example>\n    /// List.span(List(1,2,3), x => x 〈 9) == (List(1,2,3),List())\n    /// </example>\n    /// <example>\n    /// List.span(List(1,2,3), x => x 〈 0) == (List(),List(1,2,3))\n    /// </example>\n    /// <typeparam name=\"T\">List element type</typeparam>\n    /// <param name=\"self\">List</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Split list</returns>\n    [Pure]\n    public static (IEnumerable<T>, IEnumerable<T>) Span<T>(this IEnumerable<T> self, Func<T, bool> pred) =>\n        List.span(self, pred);\n\n    /// <summary>\n    /// Monadic bind function for IEnumerable\n    /// </summary>\n    [Pure]\n    public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> self, Func<T, IEnumerable<R>> binder) =>\n        EnumerableOptimal.BindFast(self, binder);\n\n    /// <summary>\n    /// LINQ Select implementation for Lst\n    /// </summary>\n    [Pure]\n    public static Lst<B> Select<A, B>(this Lst<A> self, Func<A, B> map) =>\n        new (self.AsIterable().Select(map));\n\n    /// <summary>\n    /// Monadic bind function for Lst that returns an IEnumerable\n    /// </summary>\n    [Pure]\n    public static IEnumerable<B> BindEnumerable<A, B>(this Lst<A> self, Func<A, Lst<B>> binder) =>\n        EnumerableOptimal.BindFast(self, binder);\n\n    /// <summary>\n    /// Monadic bind function\n    /// </summary>\n    [Pure]\n    public static Lst<B> Bind<A, B>(this Lst<A> self, Func<A, Lst<B>> binder) =>\n        new (self.BindEnumerable(binder));\n\n    /// <summary>\n    /// Monadic bind function\n    /// </summary>\n    [Pure]\n    public static Lst<B> Bind<A, B>(this Lst<A> self, Func<A, K<Lst, B>> binder) =>\n        Bind(self, x => binder(x).As());\n\n    /// <summary>\n    /// Returns the number of items in the Lst T\n    /// </summary>\n    /// <typeparam name=\"A\">Item type</typeparam>\n    /// <param name=\"list\">List to count</param>\n    /// <returns>The number of items in the list</returns>\n    [Pure]\n    public static int Count<A>(this Lst<A> self) =>\n        self.Count;\n\n    /// <summary>\n    /// LINQ bind implementation for Lst\n    /// </summary>\n    [Pure]\n    public static Lst<C> SelectMany<A, B, C>(this Lst<A> self, Func<A, Lst<B>> bind, Func<A, B, C> project) =>\n        self.Bind(t => bind(t).Map(u => project(t, u)));\n\n    /// <summary>\n    /// Take all but the last item in an enumerable\n    /// </summary>\n    /// <typeparam name=\"T\">Bound value type</typeparam>\n    public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> self)\n    {\n        using var iter = self.GetEnumerator();\n        bool remaining;\n        var first = true;\n        T? item = default;\n\n        do\n        {\n            remaining = iter.MoveNext();\n            if (remaining)\n            {\n                if (!first) yield return item!;\n                item = iter.Current;\n                first = false;\n            }\n        } while (remaining);\n    }\n\n    /// <summary>\n    /// Take all but the last n items in an enumerable\n    /// </summary>\n    /// <typeparam name=\"T\">Bound value type</typeparam>\n    public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> self, int n)\n    {\n        using var iter = self.GetEnumerator();\n        bool remaining ;\n        var cache = new Queue<T>(n + 1);\n\n        do\n        {\n            remaining = iter.MoveNext();\n            if (remaining)\n            {\n                cache.Enqueue(iter.Current);\n                if (cache.Count > n) yield return cache.Dequeue();\n            }\n        } while (remaining);\n    }\n\n    /// <summary>\n    /// Convert the enumerable to an Option.  \n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"self\">This</param>\n    /// <returns>If enumerable is empty then return None, else Some(head)</returns>\n    public static Option<A> ToOption<A>(this IEnumerable<A> self) =>\n        self.Match(\n            ()     => Option<A>.None,\n            (x, _) => Option.Some(x));\n    \n    /// <summary>\n    /// Convert to a queryable \n    /// </summary>\n    [Pure]\n    public static IQueryable<A> AsQueryable<A>(this Lst<A> source) =>\n        // NOTE TO FUTURE ME: Don't delete this thinking it's not needed!\n        source.Value.AsQueryable();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/Internal/Lst.Internal.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable list\n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\n[Serializable]\ninternal class LstInternal<A> : \n    IReadOnlyList<A>,\n    IEquatable<LstInternal<A>>,\n    ListInfo \n{\n    /// <summary>\n    /// Empty list\n    /// </summary>\n    public static readonly LstInternal<A> Empty = new ();\n\n    internal ListItem<A> root;\n    internal int hashCode;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal LstInternal(IEnumerable<A> items)\n    {\n        hashCode = 0;\n        if (items is Lst<A> lst)\n        {\n            root = lst.Value.Root;\n        }\n        else\n        {\n            root = ListItem<A>.EmptyM;\n            root = ListModuleM.InsertMany<A>(root, items, 0);\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal LstInternal(ReadOnlySpan<A> items)\n    {\n        hashCode = 0;\n        root = ListItem<A>.EmptyM;\n        root = ListModuleM.InsertMany<A>(root, items, 0);\n    }\n\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static LstInternal<A> Wrap(ListItem<A> list) =>\n        new (list);\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal LstInternal()\n    {\n        hashCode = 0;\n        root = ListItem<A>.Empty;\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal LstInternal(ListItem<A> root)\n    {\n        hashCode = 0;\n        this.root = root;\n    }\n\n    internal ListItem<A> Root\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => root;\n    }\n\n    /// <summary>\n    /// Index accessor\n    /// </summary>\n    [Pure]\n    public A this[int index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            if (index < 0 || index >= Root.Count) throw new IndexOutOfRangeException();\n            return ListModule.GetItem(Root, index);\n        }\n    }\n\n    /// <summary>\n    /// Number of items in the list\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Root.Count;\n    }\n\n    [Pure]\n    int IReadOnlyCollection<A>.Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Count;\n    }\n\n    [Pure]\n    A IReadOnlyList<A>.this[int index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            if (index < 0 || index >= Root.Count) throw new IndexOutOfRangeException();\n            return ListModule.GetItem(Root, index);\n        }\n    }\n\n    /// <summary>\n    /// Add an item to the end of the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Add(A value) =>\n        Wrap(ListModule.Add(Root, value));\n\n    /// <summary>\n    /// Add a range of items to the end of the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> AddRange(IEnumerable<A> items)\n    {\n        if (Count == 0) return new LstInternal<A>(items);\n        return Wrap(ListModule.AddRange<A>(Root, items));\n    }\n\n    /// <summary>\n    /// Clear the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ListEnumerator<A> GetEnumerator() =>\n        new (Root, false, 0);\n\n    /// <summary>\n    /// Find the index of an item\n    /// </summary>\n    [Pure]\n    public int IndexOf(A item, int index = 0, int count = -1, IEqualityComparer<A>? equalityComparer = null)\n    {\n        count = count == -1\n                    ? Count\n                    : count;\n\n        equalityComparer ??= EqualityComparer<A>.Default;\n\n        if (count == 0) return -1;\n        if (index < 0 || index >= Root.Count) throw new IndexOutOfRangeException();\n\n        foreach (var x in Skip(index))\n        {\n            if (equalityComparer.Equals(x, item))\n            {\n                return index;\n            }\n            index++;\n            count--;\n            if (count == 0) return -1;\n        }\n        return -1;\n    }\n\n    /// <summary>\n    /// Insert value at specified index\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Insert(int index, A value)\n    {\n        if (index < 0 || index > Root.Count) throw new IndexOutOfRangeException();\n        return Wrap(ListModule.Insert(Root, value, index));\n    }\n\n    /// <summary>\n    /// Insert range of values at specified index\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> InsertRange(int index, IEnumerable<A> items)\n    {\n        if (index < 0 || index > Root.Count) throw new IndexOutOfRangeException();\n        return Wrap(ListModule.InsertMany<A>(Root, items, index));\n    }\n\n    /// <summary>\n    /// Find the last index of an item in the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int LastIndexOf(A item, int index = 0, int count = -1, IEqualityComparer<A>? equalityComparer = null) =>\n        Count - Reverse().IndexOf(item, index, count, equalityComparer) - 1;\n\n    /// <summary>\n    /// Remove an item from the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Remove(A value) => \n        Remove(value, EqualityComparer<A>.Default);\n\n    /// <summary>\n    /// Remove all items that match `value` from the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Remove(A value, IEqualityComparer<A> equalityComparer) =>\n        Wrap(ListModule.Remove(Root, value, equalityComparer));\n\n    /// <summary>\n    /// Remove all items that match a predicate\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> RemoveAll(Func<A, bool> pred) =>\n        Wrap(ListModule.Remove(Root, pred));\n\n    /// <summary>\n    /// Remove item at location\n    /// </summary>\n    /// <param name=\"index\"></param>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> RemoveAt(int index)\n    {\n        if (index < 0 || index >= Root.Count) throw new IndexOutOfRangeException();\n        return Wrap(ListModule.Remove(Root, index));\n    }\n\n    /// <summary>\n    /// Remove a range of items\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> RemoveRange(int index, int count)\n    {\n        if (index < 0 || index >= Root.Count) throw new IndexOutOfRangeException();\n        if (index + count > Root.Count) throw new IndexOutOfRangeException();\n\n        var self = this;\n        for (; count > 0; count--)\n        {\n            self = self.RemoveAt(index);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Set an item at the specified index\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> SetItem(int index, A value)\n    {\n        if (isnull(value)) throw new ArgumentNullException(nameof(value));\n        if (index < 0 || index >= Root.Count) throw new IndexOutOfRangeException();\n        return new LstInternal<A>(ListModule.SetItem(Root, value, index));\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        new ListEnumerator<A>(Root, false, 0);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<A> IEnumerable<A>.GetEnumerator() =>\n        new ListEnumerator<A>(Root, false, 0);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> Skip(int amount)\n    {\n        return Iterable.createRange(Go());\n        IEnumerable<A> Go()\n        {\n            var iter = new ListEnumerator<A>(Root, false, amount);\n            while (iter.MoveNext())\n            {\n                yield return iter.Current;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Reverse the order of the items in the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Reverse() =>\n        new (this.AsEnumerable().Reverse());\n\n    /// <summary>\n    /// Fold\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, A, S> folder)\n    {\n        foreach (var item in this)\n        {\n            state = folder(state, item);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<U> Map<U>(Func<A, U> map) =>\n        new (this.AsEnumerable().Select(map));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> FindRange(int index, int count)\n    {\n        if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index));\n        if (count < 0) throw new ArgumentOutOfRangeException(nameof(index));\n        return Iterable.createRange(Go());\n\n        IEnumerable<A> Go()\n        {\n            var iter = new ListEnumerator<A>(Root, false, index, count);\n            while (iter.MoveNext())\n            {\n                yield return iter.Current;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Filter\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Filter(Func<A, bool> pred)\n    {\n        IEnumerable<A> Yield()\n        {\n            foreach (var item in this)\n            {\n                if (pred(item))\n                {\n                    yield return item;\n                }\n            }\n        }\n        return new LstInternal<A>(Yield());\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static LstInternal<A> operator +(LstInternal<A> lhs, A rhs) =>\n        lhs.Add(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static LstInternal<A> operator +(A rhs, LstInternal<A> lhs) =>\n        new (rhs.Cons(lhs));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static LstInternal<A> operator +(LstInternal<A> lhs, LstInternal<A> rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Combine(LstInternal<A> rhs) =>\n        AddRange(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static LstInternal<A> operator -(LstInternal<A> lhs, LstInternal<A> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public LstInternal<A> Subtract(LstInternal<A> rhs)\n    {\n        var self = this;\n        foreach (var item in rhs)\n        {\n            self = self.Remove(item);\n        }\n        return self;\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is LstInternal<A> @as &&\n        Equals(@as);\n\n    /// <summary>\n    /// Get the hash code\n    /// Lazily (and once only) calculates the hash from the elements in the list\n    /// Empty list hash == 0\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        hashCode == 0\n            ? hashCode = FNV32.Hash<HashableDefault<A>, A>(this.AsEnumerable())\n            : hashCode;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(LstInternal<A>? other)\n    {\n        if (ReferenceEquals(this, other)) return true;\n        if (ReferenceEquals(other, null)) return false;\n        return Count == other.Count && EqEnumerable<A>.Equals(this, other);\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(LstInternal<A> lhs, LstInternal<A> rhs) =>\n        lhs.Equals(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(LstInternal<A> lhs, LstInternal<A> rhs) =>\n        !lhs.Equals(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(LstInternal<A> other)\n    {\n        var cmp = Count.CompareTo(other.Count);\n        if (cmp != 0) return cmp;\n        using var iterA = GetEnumerator();\n        using var iterB = other.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            cmp = OrdDefault<A>.Compare(iterA.Current, iterB.Current);\n            if (cmp != 0) return cmp;\n        }\n        return 0;\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo<OrdA>(LstInternal<A> other) where OrdA : Ord<A>\n    {\n        var cmp = Count.CompareTo(other.Count);\n        if (cmp != 0) return cmp;\n        using var iterA = GetEnumerator();\n        using var iterB = other.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            cmp = OrdA.Compare(iterA.Current, iterB.Current);\n            if (cmp != 0) return cmp;\n        }\n        return 0;\n    }\n}\n\n[Serializable]\nclass ListItem<T>\n{\n    public static ListItem<T> EmptyM => new (0, 0, null!, default!, null!);\n    public static readonly ListItem<T> Empty = new(0, 0, null!, default!, null!);\n\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Count == 0;\n    }\n    public int Count;\n    public byte Height;\n    public ListItem<T> Left;\n    public ListItem<T> Right;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal ListItem(byte height, int count, ListItem<T> left, T key, ListItem<T> right)\n    {\n        Count = count;\n        Height = height;\n        Key = key;\n        Left = left;\n        Right = right;\n    }\n\n    internal int BalanceFactor\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get =>\n            Count == 0\n                ? 0\n                : Right.Height - Left.Height;\n    }\n\n    public T Key\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get;\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        internal set;\n    }\n\n    public bool IsBalanced\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => (uint)(BalanceFactor + 1) <= 2;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        IsEmpty\n            ? \"(empty)\"\n            : Key?.ToString() ?? \"[null]\";\n}\n\ninternal static class ListModuleM\n{\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<A> InsertMany<A>(ListItem<A> node, IEnumerable<A> items, int index) =>\n        Insert(node, BuildSubTree(items), index);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<A> InsertMany<A>(ListItem<A> node, ReadOnlySpan<A> items, int index) =>\n        Insert(node, BuildSubTree(items), index);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<A> BuildSubTree<A>(IEnumerable<A> items)\n    {\n        var root = ListItem<A>.EmptyM;\n\n        var subIndex = 0;\n        foreach (var item in items)\n        {\n            root = Insert(root, new ListItem<A>(1, 1, ListItem<A>.Empty, item, ListItem<A>.Empty), subIndex);\n            subIndex++;\n        }\n\n        return root;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<A> BuildSubTree<A>(ReadOnlySpan<A> items)\n    {\n        var root = ListItem<A>.EmptyM;\n\n        var subIndex = 0;\n        foreach (var item in items)\n        {\n            root = Insert(root, new ListItem<A>(1, 1, ListItem<A>.Empty, item, ListItem<A>.Empty), subIndex);\n            subIndex++;\n        }\n\n        return root;\n    }\n\n    public static ListItem<A> Insert<A>(ListItem<A> node, ListItem<A> insertNode, int index)\n    {\n        if (node.IsEmpty)\n        {\n            return insertNode;\n        }\n        else if (index == node.Left.Count)\n        {\n            insertNode.Left = node.Left;\n            insertNode = Balance(insertNode);\n\n            node.Left = insertNode;\n            node = Balance(node);\n\n            return node;\n        }\n        else if (index < node.Left.Count)\n        {\n            node.Left = Insert(node.Left, insertNode, index);\n            return Balance(node);\n        }\n        else\n        {\n            node.Right = Insert(node.Right, insertNode, index - node.Left.Count - 1);\n            return Balance(node);\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> Balance<T>(ListItem<T> node)\n    {\n        node.Height = (byte)(1 + Math.Max(node.Left.Height, node.Right.Height));\n        node.Count = 1 + node.Left.Count + node.Right.Count;\n\n        return node.BalanceFactor >= 2\n                   ? node.Right.BalanceFactor < 0\n                         ? DblRotLeft(node)\n                         : RotLeft(node)\n                   : node.BalanceFactor <= -2\n                       ? node.Left.BalanceFactor > 0\n                             ? DblRotRight(node)\n                             : RotRight(node)\n                       : node;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> DblRotRight<T>(ListItem<T> node)\n    {\n        node.Left = RotLeft(node.Left);\n        return RotRight(node);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> DblRotLeft<T>(ListItem<T> node)\n    {\n        node.Right = RotRight(node.Right);\n        return RotLeft(node);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<A> RotRight<A>(ListItem<A> node)\n    {\n        if (node.IsEmpty || node.Left.IsEmpty) return node;\n\n        var y  = node;\n        var x  = y.Left;\n        var t2 = x.Right;\n        x.Right = y;\n        y.Left = t2;\n        y.Height = (byte)(1 + Math.Max(y.Left.Height, y.Right.Height));\n        x.Height = (byte)(1 + Math.Max(x.Left.Height, x.Right.Height));\n        y.Count = 1 + y.Left.Count + y.Right.Count;\n        x.Count = 1 + x.Left.Count + x.Right.Count;\n\n        return x;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<A> RotLeft<A>(ListItem<A> node)\n    {\n        if (node.IsEmpty || node.Right.IsEmpty) return node;\n\n        var x  = node;\n        var y  = x.Right;\n        var t2 = y.Left;\n        y.Left = x;\n        x.Right = t2;\n        x.Height = (byte)(1 + Math.Max(x.Left.Height, x.Right.Height));\n        y.Height = (byte)(1 + Math.Max(y.Left.Height, y.Right.Height));\n        x.Count = 1 + x.Left.Count + x.Right.Count;\n        y.Count = 1 + y.Left.Count + y.Right.Count;\n\n        return y;\n    }\n}\n\nstatic class ListModule\n{\n    public static S Fold<S, T>(ListItem<T> node, S state, Func<S, T, S> folder)\n    {\n        if (node.IsEmpty)\n        {\n            return state;\n        }\n\n        state = Fold(node.Left, state, folder);\n        state = folder(state, node.Key);\n        state = Fold(node.Right, state, folder);\n        return state;\n    }\n\n    public static bool ForAll<A>(ListItem<A> node, Func<A, bool> pred) =>\n        node.IsEmpty || (pred(node.Key) && ForAll(node.Left, pred) && ForAll(node.Right, pred));\n\n    public static bool Exists<T>(ListItem<T> node, Func<T, bool> pred) =>\n        !node.IsEmpty && (pred(node.Key) || Exists(node.Left, pred) || Exists(node.Right, pred));\n\n    public static ListItem<U> Map<T, U>(ListItem<T> node, Func<T, U> f) =>\n        node.IsEmpty\n            ? ListItem<U>.Empty\n            : new ListItem<U>(node.Height, node.Count, Map(node.Left, f), f(node.Key), Map(node.Right, f));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<A> AddRange<A>(ListItem<A> node, IEnumerable<A> items) =>\n        AddRange(node, ListModuleM.BuildSubTree(items));\n\n    static ListItem<A> AddRange<A>(ListItem<A> node, ListItem<A> insertNode) =>\n        node.IsEmpty\n            ? insertNode\n            : Balance(Make(node.Key, node.Left, AddRange(node.Right, insertNode)));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<A> InsertMany<A>(ListItem<A> node, IEnumerable<A> items, int index)\n    {\n        var root     = node;\n        var subIndex = index;\n        foreach(var item in items)\n        {\n            root = Insert(root, item, subIndex);\n            subIndex++;\n        }\n        return root;\n    }\n\n    public static ListItem<A> Insert<A>(ListItem<A> node, A key, int index)\n    {\n        if (node.IsEmpty)\n        {\n            return new ListItem<A>(1, 1, ListItem<A>.Empty, key, ListItem<A>.Empty);\n        }\n        else if (index == node.Left.Count)\n        {\n            var insertedLeft = Balance(Make(key, node.Left, ListItem<A>.Empty));\n            var newThis      = Balance(Make(node.Key, insertedLeft, node.Right));\n            return newThis;\n        }\n        else if (index < node.Left.Count)\n        {\n            return Balance(Make(node.Key, Insert(node.Left, key, index), node.Right));\n        }\n        else\n        {\n            return Balance(Make(node.Key, node.Left, Insert(node.Right, key, index - node.Left.Count - 1)));\n        }\n    }\n\n    public static ListItem<A> Add<A>(ListItem<A> node, A key) =>\n        node.IsEmpty\n            ? new ListItem<A>(1, 1, ListItem<A>.Empty, key, ListItem<A>.Empty)\n            : Balance(Make(node.Key, node.Left, Add(node.Right, key)));\n\n    public static ListItem<A> SetItem<A>(ListItem<A> node, A key, int index)\n    {\n        if (node.IsEmpty)\n        {\n            throw new ArgumentException(\"Index outside the bounds of the list\");\n        }\n\n        if (index == node.Left.Count)\n        {\n            return new ListItem<A>(node.Height, node.Count, node.Left, key, node.Right);\n        }\n        else if (index < node.Left.Count)\n        {\n            return new ListItem<A>(node.Height, node.Count, SetItem(node.Left, key, index), node.Key, node.Right);\n        }\n        else\n        {\n            return new ListItem<A>(node.Height, node.Count, node.Left, node.Key, SetItem(node.Right, key, index - node.Left.Count - 1));\n        }\n    }\n\n    public static T GetItem<T>(ListItem<T> node, int index)\n    {\n        if (node.IsEmpty)\n        {\n            throw new ArgumentException(\"Index outside the bounds of the list\");\n        }\n\n        if (index == node.Left.Count)\n        {\n            return node.Key;\n        }\n        else if (index < node.Left.Count)\n        {\n            return GetItem(node.Left, index);\n        }\n        else\n        {\n            return GetItem(node.Right, index - node.Left.Count - 1);\n        }\n    }\n\n    public static ListItem<T> Remove<T>(ListItem<T> node, Func<T, bool> pred)\n    {\n        if (node.IsEmpty)\n        {\n            return node;\n        }\n\n        var result = node;\n\n        var left  = node.Left.IsEmpty ? node.Left : Remove(node.Left, pred);\n        var right = node.Right.IsEmpty ? node.Right : Remove(node.Right, pred);\n\n        if (pred(node.Key))\n        {\n            if (right.IsEmpty && left.IsEmpty)\n            {\n                result = ListItem<T>.Empty;\n            }\n            else if (right.IsEmpty && !left.IsEmpty)\n            {\n                result = left;\n            }\n            else if (!right.IsEmpty && left.IsEmpty)\n            {\n                result = Balance(right);\n            }\n            else\n            {\n                var next = right;\n                while (!next.Left.IsEmpty)\n                {\n                    next = next.Left;\n                }\n\n                right = Remove(right, 0);\n                result = Balance(Make(next.Key, left, right));\n            }\n        }\n        else\n        {\n            if (!ReferenceEquals(left, node.Left) || !ReferenceEquals(right, node.Right))\n            {\n                result = Balance(Make(node.Key, left, right));\n            }\n        }\n\n        return result.IsEmpty || result.IsBalanced ? result : Balance(result);\n    }\n\n    public static ListItem<T> Remove<T>(ListItem<T> node, T value, IEqualityComparer<T> compare)\n    {\n        if (node.IsEmpty)\n        {\n            return node;\n        }\n\n        var result = node;\n\n        var left  = node.Left.IsEmpty ? node.Left : Remove(node.Left, value, compare);\n        var right = node.Right.IsEmpty ? node.Right : Remove(node.Right, value, compare);\n\n        if (ReferenceEquals(node.Key, value) || compare.Equals(node.Key, value))\n        {\n            if (right.IsEmpty && left.IsEmpty)\n            {\n                result = ListItem<T>.Empty;\n            }\n            else if (right.IsEmpty && !left.IsEmpty)\n            {\n                result = left;\n            }\n            else if (!right.IsEmpty && left.IsEmpty)\n            {\n                result = Balance(right);\n            }\n            else\n            {\n                var next = right;\n                while (!next.Left.IsEmpty)\n                {\n                    next = next.Left;\n                }\n\n                right = Remove(right, 0);\n                result = Balance(Make(next.Key, left, right));\n            }\n        }\n        else\n        {\n            if(!ReferenceEquals(left, node.Left) || !ReferenceEquals(right, node.Right))\n            {\n                result = Balance(Make(node.Key, left, right));\n            }\n        }\n\n        return result.IsEmpty || result.IsBalanced ? result : Balance(result);\n    }\n\n    public static ListItem<T> Remove<T>(ListItem<T> node, int index)\n    {\n        if (node.IsEmpty)\n        {\n            return node;\n        }\n\n        ListItem<T> result;\n\n        if (index == node.Left.Count)\n        {\n            if (node.Right.IsEmpty && node.Left.IsEmpty)\n            {\n                result = ListItem<T>.Empty;\n            }\n            else if (node.Right.IsEmpty && !node.Left.IsEmpty)\n            {\n                result = node.Left;\n            }\n            else if (!node.Right.IsEmpty && node.Left.IsEmpty)\n            {\n                result = Balance(node.Right);\n            }\n            else\n            {\n                var next = node.Right;\n                while (!next.Left.IsEmpty)\n                {\n                    next = next.Left;\n                }\n\n                var right = Remove(node.Right, 0);\n                result = Balance(Make(next.Key, node.Left, right));\n            }\n        }\n        else if (index < node.Left.Count)\n        {\n            var left = Remove(node.Left, index);\n            result = Make(node.Key, left, node.Right);\n        }\n        else\n        {\n            var right = Remove(node.Right, index - node.Left.Count - 1);\n            result = Make(node.Key, node.Left, right);\n        }\n        return result.IsEmpty || result.IsBalanced ? result : Balance(result);\n    }\n\n    public static int Find<T>(ListItem<T> node, T key, int index, int count, IComparer<T> comparer)\n    {\n        if (node.IsEmpty || node.Count <= 0)\n        {\n            return ~index;\n        }\n\n        int nodeIndex = node.Left.Count;\n        if (index + count <= nodeIndex)\n        {\n            return Find(node.Left, key, index, count, comparer);\n        }\n        else if (index > nodeIndex)\n        {\n            int result = Find(node.Right, key, index - nodeIndex - 1, count, comparer);\n            int offset = nodeIndex + 1;\n            return result < 0 ? result - offset : result + offset;\n        }\n        int compare = comparer.Compare(key, node.Key);\n        if (compare == 0)\n        {\n            return nodeIndex;\n        }\n        else if (compare > 0)\n        {\n            int adjcount = count - (nodeIndex - index) - 1;\n            int result   = adjcount < 0 ? -1 : Find(node.Right,key, 0, adjcount, comparer);\n            int offset   = nodeIndex + 1;\n            return result < 0 ? result - offset : result + offset;\n        }\n        else\n        {\n            if (index == nodeIndex)\n            {\n                return ~index;\n            }\n            return Find(node.Left,key,index,count,comparer);\n        }\n    }\n\n    public static ListItem<T> Skip<T>(ListItem<T> node, int amount)\n    {\n        if (amount == 0 || node.IsEmpty)\n        {\n            return node;\n        }\n        if (amount > node.Count)\n        {\n            return ListItem<T>.Empty;\n        }\n        if (!node.Left.IsEmpty && node.Left.Count == amount)\n        {\n            return Balance(Make(node.Key, ListItem<T>.Empty, node.Right));\n        }\n        if (!node.Left.IsEmpty && node.Left.Count == amount - 1)\n        {\n            return node.Right;\n        }\n        if (node.Left.IsEmpty)\n        {\n            return Skip(node.Right, amount - 1);\n        }\n\n        var newleft   = Skip(node.Left, amount);\n        var remaining = amount - node.Left.Count - newleft.Count;\n        if (remaining > 0)\n        {\n            return Skip(Balance(Make(node.Key, newleft, node.Right)), remaining);\n        }\n        else\n        {\n            return Balance(Make(node.Key, newleft, node.Right));\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> Make<T>(T k, ListItem<T> l, ListItem<T> r) =>\n        new ((byte)(1 + Math.Max(l.Height, r.Height)), l.Count + r.Count + 1, l, k, r);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> Balance<T>(ListItem<T> node) =>\n        node.BalanceFactor >= 2\n            ? node.Right.BalanceFactor < 0\n                  ? DblRotLeft(node)\n                  : RotLeft(node)\n            : node.BalanceFactor <= -2\n                ? node.Left.BalanceFactor > 0\n                      ? DblRotRight(node)\n                      : RotRight(node)\n                : node;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> RotRight<T>(ListItem<T> node) =>\n        node.IsEmpty || node.Left.IsEmpty\n            ? node\n            : Make(node.Left.Key, node.Left.Left, Make(node.Key, node.Left.Right, node.Right));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> RotLeft<T>(ListItem<T> node) =>\n        node.IsEmpty || node.Right.IsEmpty\n            ? node\n            : Make(node.Right.Key, Make(node.Key, node.Left, node.Right.Left), node.Right.Right);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> DblRotRight<T>(ListItem<T> node) =>\n        node.IsEmpty\n            ? node\n            : RotRight(Make(node.Key, RotLeft(node.Left), node.Right));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ListItem<T> DblRotLeft<T>(ListItem<T> node) =>\n        node.IsEmpty\n            ? node\n            : RotLeft(Make(node.Key, node.Left, RotRight(node.Right)));\n}\n\npublic struct ListEnumerator<T> : IEnumerator<T>\n{\n    internal struct NewStack : New<ListItem<T>[]>\n    {\n        public ListItem<T>[] New() =>\n            new ListItem<T>[32];\n    }\n\n    ListItem<T>[] stack;\n    int stackDepth;\n    readonly ListItem<T> map;\n    int left;\n    readonly bool rev;\n    readonly int start;\n    int count;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal ListEnumerator(ListItem<T> root, bool rev, int start, int count = int.MaxValue)\n    {\n        this.rev = rev;\n        this.start = start;\n        map = root;\n        stack = Pool<NewStack, ListItem<T>[]>.Pop();\n        this.count = count;\n        stackDepth = default;\n        left = default;\n        NodeCurrent = default!;\n        Reset();\n    }\n\n    private ListItem<T> NodeCurrent\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get;\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        set;\n    }\n\n    public readonly T Current\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => NodeCurrent.Key;\n    }\n\n    object IEnumerator.Current\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => NodeCurrent.Key!;\n    }\n\n    public void Dispose()\n    {\n        if (stack != null)\n        {\n            Pool<NewStack, ListItem<T>[]>.Push(stack);\n            stack = null!;\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    private ListItem<T> Next(ListItem<T> node) =>\n        rev ? node.Left : node.Right;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    private ListItem<T> Prev(ListItem<T> node) =>\n        rev ? node.Right : node.Left;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    private void Push(ListItem<T> node)\n    {\n        while (!node.IsEmpty)\n        {\n            stack[stackDepth] = node;\n            stackDepth++;\n            node = Prev(node);\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool MoveNext()\n    {\n        if (count > 0 && left > 0 && stackDepth > 0)\n        {\n            stackDepth--;\n            NodeCurrent = stack[stackDepth];\n            Push(Next(NodeCurrent));\n            left--;\n            count--;\n            return true;\n        }\n\n        NodeCurrent = default!;\n        return false;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public void Reset()\n    {\n        var skip = rev ? map.Count - start - 1 : start;\n\n        stackDepth = 0;\n        NodeCurrent = map;\n        left = map.Count;\n\n        while (!NodeCurrent.IsEmpty && skip != Prev(NodeCurrent).Count)\n        {\n            if (skip < Prev(NodeCurrent).Count)\n            {\n                stack[stackDepth] = NodeCurrent;\n                stackDepth++;\n                NodeCurrent = Prev(NodeCurrent);\n            }\n            else\n            {\n                skip -= Prev(NodeCurrent).Count + 1;\n                NodeCurrent = Next(NodeCurrent);\n            }\n        }\n\n        if (!NodeCurrent.IsEmpty)\n        {\n            stack[stackDepth] = NodeCurrent;\n            stackDepth++;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/ListInfo.cs",
    "content": "﻿namespace LanguageExt;\n\npublic interface ListInfo\n{\n    int Count { get; }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/Lst.Module.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\npublic static class List\n{\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Lst<A> flatten<A>(Lst<Lst<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Iterable<A> flatten<A>(IEnumerable<IEnumerable<A>> ma) =>\n        ma.Bind(identity).AsIterable();\n\n    /// <summary>\n    /// Create an empty IEnumerable T\n    /// </summary>\n    [Pure]\n    public static Lst<T> empty<T>() =>\n        Lst<T>.Empty;\n\n    /// <summary>\n    /// Create a singleton collection\n    /// </summary>\n    /// <param name=\"value\">Single value</param>\n    /// <returns>Collection with a single item in it</returns>\n    [Pure]\n    public static Lst<A> singleton<A>(A value) =>\n        [value];\n\n    /// <summary>\n    /// Create a new empty list\n    /// </summary>\n    /// <returns>Lst T</returns>\n    [Pure]\n    public static Lst<T> create<T>() =>\n        Lst<T>.Empty;\n\n    /// <summary>\n    /// Create a list from a initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>Lst T</returns>\n    [Pure]\n    public static Lst<T> create<T>(params T[] items) =>\n        new (items.AsSpan());\n\n    /// <summary>\n    /// Create a list from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>Lst T</returns>\n    [Pure]\n    public static Lst<T> createRange<T>(IEnumerable<T> items) =>\n        new (items);\n\n    /// <summary>\n    /// Create a list from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>Lst T</returns>\n    [Pure]\n    public static Lst<A> createRange<A>(ReadOnlySpan<A> items) =>\n        items.IsEmpty\n            ? Lst<A>.Empty\n            : new (items);\n\n    /// <summary>\n    /// Generates a sequence of T using the provided delegate to initialise\n    /// each item.\n    /// </summary>\n    [Pure]\n    public static Iterable<T> generate<T>(int count, Func<int, T> generator) =>\n        IterableExtensions.AsIterable(Range(0, count)).Map(generator);\n\n    /// <summary>\n    /// Generates an int.MaxValue sequence of T using the provided delegate to initialise\n    /// each item.\n    /// </summary>\n    [Pure]\n    public static Iterable<T> generate<T>(Func<int, T> generator) =>\n        IterableExtensions.AsIterable(Range(0, int.MaxValue)).Map(generator);\n\n    /// <summary>\n    /// Generates a sequence that contains one repeated value.\n    /// </summary>\n    [Pure]\n    public static Iterable<T> repeat<T>(T item, int count) =>\n        IterableExtensions.AsIterable(Range(0, count)).Map(_ => item);\n\n    /// <summary>\n    /// Add an item to the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <param name=\"value\">Item to add</param>\n    /// <returns>A new Lst T</returns>\n    [Pure]\n    public static Lst<T> add<T>(Lst<T> list, T value) =>\n        list.Add(value);\n\n    /// <summary>\n    /// Add a range of items to the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <param name=\"value\">Items to add</param>\n    /// <returns>A new Lst T</returns>\n    [Pure]\n    public static Lst<T> addRange<T>(Lst<T> list, IEnumerable<T> value) =>\n        list.AddRange(value);\n\n    /// <summary>\n    /// Remove an item from the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <param name=\"value\">value to remove</param>\n    /// <returns>A new Lst T</returns>\n    [Pure]\n    public static Lst<T> remove<T>(Lst<T> list, T value) =>\n        list.Remove(value);\n\n    /// <summary>\n    /// Remove an item at a specified index in the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <param name=\"index\">Index of item to remove</param>\n    /// <returns>A new Lst T</returns>\n    [Pure]\n    public static Lst<T> removeAt<T>(Lst<T> list, int index) =>\n        list.RemoveAt(index);\n\n    /// <summary>\n    /// Get the item at the head (first) of the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Head item</returns>\n    [Pure]\n    public static T head<T>(IEnumerable<T> list) => \n        list.First();\n    /// <summary>\n    /// Get the item at the head (first) of the list or None if the list is empty\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Optional head item</returns>\n    [Pure]\n    public static Option<A> headOrNone<A>(IEnumerable<A> list) =>\n        list.Select(Option.Some)\n            .DefaultIfEmpty(Option<A>.None)\n            .FirstOrDefault();\n\n    /// <summary>\n    /// Get the item at the head (first) of the list or Left if the list is empty\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Either head item or left</returns>\n    [Pure]\n    public static Either<L, R> headOrLeft<L, R>(IEnumerable<R> list, L left) =>\n        list.Select(Either.Right<L, R>)\n            .DefaultIfEmpty(Either.Left<L, R>(left))\n            .FirstOrDefault() ?? left;\n\n    /// <summary>\n    /// Get the item at the head (first) of the list or fail if the list is empty\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Either head item or fail</returns>\n    [Pure]\n    public static Validation<Fail, Success> headOrInvalid<Fail, Success>(IEnumerable<Success> list, Fail fail) \n        where Fail : Monoid<Fail> =>\n        list.Select(Validation.Success<Fail, Success>)\n            .DefaultIfEmpty(Validation.Fail<Fail, Success>(fail))\n            .FirstOrDefault() ?? Fail.Empty;\n\n    /// <summary>\n    /// Get the item at the head (first) of the list or fail if the list is empty\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Either head item or fail</returns>\n    [Pure]\n    public static Validation<Fail, Success> headOrInvalid<Fail, Success>(IEnumerable<Success> list)\n        where Fail : Monoid<Fail> =>\n        list.Select(Validation.Success<Fail, Success>)\n            .DefaultIfEmpty(Validation.Fail<Fail, Success>(Fail.Empty))\n            .FirstOrDefault() ?? Fail.Empty;\n\n    /// <summary>\n    /// Get the last item of the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Last item</returns>\n    [Pure]\n    public static A last<A>(IEnumerable<A> list) =>\n        list.Last();\n\n    /// <summary>\n    /// Get the last item of the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Last item</returns>\n    [Pure]\n    public static Option<A> lastOrNone<A>(IEnumerable<A> list) =>\n        list.Select(Option.Some)\n            .DefaultIfEmpty(Option<A>.None)\n            .LastOrDefault();\n\n    /// <summary>\n    /// Get the last item of the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Last item</returns>\n    [Pure]\n    public static Either<L, R> lastOrLeft<L, R>(IEnumerable<R> list, L left) =>\n        list.Select(Either.Right<L, R>)\n            .DefaultIfEmpty(Either.Left<L, R>(left))\n            .LastOrDefault() ?? left;\n\n    /// <summary>\n    /// Get the last item of the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Last item</returns>\n    [Pure]\n    public static Validation<Fail, Success> lastOrInvalid<Fail, Success>(IEnumerable<Success> list, Fail fail)\n        where Fail : Monoid<Fail> =>\n        list.Select(Validation.Success<Fail, Success>)\n            .DefaultIfEmpty(Validation.Fail<Fail, Success>(fail))\n            .LastOrDefault() ?? fail;\n\n    /// <summary>\n    /// Get the last item of the list\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Last item</returns>\n    [Pure]\n    public static Validation<Fail, Success> lastOrInvalid<Fail, Success>(IEnumerable<Success> list)\n        where Fail : Monoid<Fail> =>\n        list.Select(Validation.Success<Fail, Success>)\n            .DefaultIfEmpty(Validation.Fail<Fail, Success>(Fail.Empty))\n            .LastOrDefault() ?? Fail.Empty;\n\n    /// <summary>\n    /// Get all items in the list except the last one\n    /// </summary>\n    /// <remarks>\n    /// Must evaluate the last item to know it's the last, but won't return it\n    /// </remarks>\n    /// <param name=\"list\">List</param>\n    /// <returns>The initial items (all but the last)</returns>\n    [Pure]\n    public static Seq<A> init<A>(IEnumerable<A> list)\n    {\n        var items = list.ToArray();\n        return new Seq<A>(new SeqStrict<A>(items, 0, Math.Max(0, items.Length - 1), 0, 0));\n    }\n\n    /// <summary>\n    /// Get the tail of the list (skips the head item)\n    /// </summary>\n    /// <param name=\"list\">List</param>\n    /// <returns>Enumerable of T</returns>\n    [Pure]\n    public static Iterable<T> tail<T>(IEnumerable<T> list) =>\n        list.Skip(1).AsIterable();\n\n    /// <summary>\n    /// Projects the values in the enumerable using a map function into a new enumerable (Select in LINQ).\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Iterable<R> map<T, R>(IEnumerable<T> list, Func<T, R> map) =>\n        list.Select(map).AsIterable();\n\n    /// <summary>\n    /// Projects the values in the enumerable into a new enumerable using a map function, which is also given an index value\n    /// (Select in LINQ - note that the order of the arguments of the map function are the other way around, here the index\n    /// is the first argument).\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Iterable<R> map<T, R>(IEnumerable<T> list, Func<int, T, R> map) =>\n        zip(list, Range(0, int.MaxValue), (t, i) => map(i, t)).AsIterable();\n\n    /// <summary>\n    /// Removes items from the list that do not match the given predicate (Where in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to filter</param>\n    /// <param name=\"predicate\">Predicate function</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public static Iterable<T> filter<T>(IEnumerable<T> list, Func<T, bool> predicate) =>\n        list.Where(predicate).AsIterable();\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the list. Returns the list comprised of \n    /// the results for each element where the function returns Some(f(x)).\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered enumerable</returns>\n    [Pure]\n    public static Iterable<R> choose<T, R>(IEnumerable<T> list, Func<T, Option<R>> selector) =>\n        map(filter(map(list, selector), t => t.IsSome), t => t.Value!);\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the list. Returns the list comprised of \n    /// the results for each element where the function returns Some(f(x)).\n    /// An index value is passed through to the selector function also.\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered enumerable</returns>\n    [Pure]\n    public static Iterable<R> choose<T, R>(IEnumerable<T> list, Func<int, T, Option<R>> selector) =>\n        map(filter(map(list, selector), t => t.IsSome), t => t.Value!);\n\n    /// <summary>\n    /// For each element of the list, applies the given function. Concatenates all the results and \n    /// returns the combined list.\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Iterable<R> collect<T, R>(IEnumerable<T> list, Func<T, IEnumerable<R>> map) =>\n        (from t in list\n         from r in map(t)\n         select r).AsIterable();\n\n    /// <summary>\n    /// Returns the sum total of all the items in the list (Sum in LINQ)\n    /// </summary>\n    /// <param name=\"list\">List to sum</param>\n    /// <returns>Sum total</returns>\n    [Pure]\n    public static int sum(IEnumerable<int> list) =>\n        fold(list, 0, (s, x) => s + x);\n\n    /// <summary>\n    /// Returns the sum total of all the items in the list (Sum in LINQ)\n    /// </summary>\n    /// <param name=\"list\">List to sum</param>\n    /// <returns>Sum total</returns>\n    [Pure]\n    public static float sum(IEnumerable<float> list) =>\n        fold(list, 0.0f, (s, x) => s + x);\n\n    /// <summary>\n    /// Returns the sum total of all the items in the list (Sum in LINQ)\n    /// </summary>\n    /// <param name=\"list\">List to sum</param>\n    /// <returns>Sum total</returns>\n    [Pure]\n    public static double sum(IEnumerable<double> list) =>\n        fold(list, 0.0, (s, x) => s + x);\n\n    /// <summary>\n    /// Returns the sum total of all the items in the list (Sum in LINQ)\n    /// </summary>\n    /// <param name=\"list\">List to sum</param>\n    /// <returns>Sum total</returns>\n    [Pure]\n    public static decimal sum(IEnumerable<decimal> list) =>\n        fold(list, (decimal)0, (s, x) => s + x);\n\n    /// <summary>\n    /// Reverses the enumerable (Reverse in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to reverse</param>\n    /// <returns>Reversed enumerable</returns>\n    [Pure]\n    public static Iterable<T> rev<T>(IEnumerable<T> list) =>\n        list.Reverse().AsIterable();\n\n    /// <summary>\n    /// Reverses the list (Reverse in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">List item type</typeparam>\n    /// <param name=\"list\">List to reverse</param>\n    /// <returns>Reversed list</returns>\n    [Pure]\n    public static Lst<T> rev<T>(Lst<T> list) =>\n        list.Reverse();\n\n    /// <summary>\n    /// Concatenate two enumerables (Concat in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"lhs\">First enumerable</param>\n    /// <param name=\"rhs\">Second enumerable</param>\n    /// <returns>Concatenated enumerable</returns>\n    [Pure]\n    public static Iterable<T> append<T>(IEnumerable<T> lhs, IEnumerable<T> rhs) =>\n        lhs.ConcatFast(rhs).AsIterable();\n\n    /// <summary>\n    /// Concatenate an enumerable and an enumerable of enumerables\n    /// </summary>\n    /// <typeparam name=\"T\">List item type</typeparam>\n    /// <param name=\"lhs\">First list</param>\n    /// <param name=\"rhs\">Second list</param>\n    /// <returns>Concatenated list</returns>\n    [Pure]\n    public static Iterable<T> append<T>(IEnumerable<T> x, IEnumerable<IEnumerable<T>> xs) =>\n        xs.HeadAndTailSafe()\n          .Match(\n               None: x.AsIterable,\n               Some: tuple => append(x, append(tuple.Head, tuple.Tail)));\n\n    /// <summary>\n    /// Concatenate N enumerables\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable type</typeparam>\n    /// <param name=\"lists\">Enumerables to concatenate</param>\n    /// <returns>A single enumerable with all of the items concatenated</returns>\n    [Pure]\n    public static Iterable<T> append<T>(params IEnumerable<T>[] lists) =>\n        lists.Length == 0\n            ? Iterable.empty<T>()\n            : lists.Length == 1\n                ? lists[0].AsIterable()\n                : append(lists[0], lists.Skip(1));\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the list. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S fold<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder)\n    {\n        foreach (var item in list)\n        {\n            state = folder(state, item);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the list. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBack<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder) =>\n        fold(rev(list), state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection whilst the predicate function \n    /// returns True for the item being processed, threading an aggregate state through the \n    /// computation. The fold function takes the state argument, and applies the function 'folder' \n    /// to it and the first element of the list. Then, it feeds this result into the function 'folder' \n    /// along with the second element, and so on. It returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"preditem\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldWhile<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder, Func<T, bool> preditem)\n    {\n        foreach (var item in list)\n        {\n            if (!preditem(item))\n            {\n                return state;\n            }\n            state = folder(state, item);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation (and whilst the predicate function returns True when passed \n    /// the aggregate state). The fold function takes the state argument, and applies the function \n    /// 'folder' to it and the first element of the list. Then, it feeds this result into the \n    /// function 'folder' along with the second element, and so on. It returns the final result. \n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"predstate\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldWhile<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder, Func<S, bool> predstate)\n    {\n        foreach (var item in list)\n        {\n            if (!predstate(state))\n            {\n                return state;\n            }\n            state = folder(state, item);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first)\n    /// whilst the predicate function returns True for the item being processed, threading an \n    /// aggregate state through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the list. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"preditem\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBackWhile<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder, Func<T, bool> preditem) =>\n        foldWhile(rev(list), state, folder, preditem: preditem);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an accumulator argument through the computation (and whilst the predicate function \n    /// returns True when passed the aggregate state). The fold function takes the state argument, \n    /// and applies the function 'folder' to it and the first element of the list. Then, it feeds \n    /// this result into the function 'folder' along with the second element, and so on. It returns \n    /// the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"predstate\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBackWhile<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder, Func<S, bool> predstate) =>\n        foldWhile(rev(list), state, folder, predstate: predstate);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection whilst the predicate function \n    /// returns False for the item being processed, threading an aggregate state through the \n    /// computation. The fold function takes the state argument, and applies the function 'folder' \n    /// to it and the first element of the list. Then, it feeds this result into the function 'folder' \n    /// along with the second element, and so on. It returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"preditem\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldUntil<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder, Func<T, bool> preditem)\n    {\n        foreach (var item in list)\n        {\n            if (preditem(item))\n            {\n                return state;\n            }\n            state = folder(state, item);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation (and whilst the predicate function returns False when passed \n    /// the aggregate state). The fold function takes the state argument, and applies the function \n    /// 'folder' to it and the first element of the list. Then, it feeds this result into the \n    /// function 'folder' along with the second element, and so on. It returns the final result. \n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"predstate\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldUntil<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder, Func<S, bool> predstate)\n    {\n        foreach (var item in list)\n        {\n            if (predstate(state))\n            {\n                return state;\n            }\n            state = folder(state, item);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first)\n    /// whilst the predicate function returns False for the item being processed, threading an \n    /// aggregate state through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the list. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"preditem\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBackUntil<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder, Func<T, bool> preditem) =>\n        foldUntil(rev(list), state, folder, preditem: preditem);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an accumulator argument through the computation (and whilst the predicate function \n    /// returns False when passed the aggregate state). The fold function takes the state argument, \n    /// and applies the function 'folder' to it and the first element of the list. Then, it feeds \n    /// this result into the function 'folder' along with the second element, and so on. It returns \n    /// the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"predstate\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBackUntil<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder, Func<S, bool> predstate) =>\n        foldUntil(rev(list), state, folder, predstate: predstate);\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from first element to last), threading \n    /// an accumulator argument through the computation. This function first applies the function \n    /// to the first two elements of the list. Then, it passes this result into the function along \n    /// with the third element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <remarks>The enumerable must contain at least one item or an excpetion will be thrown</remarks>\n    /// <typeparam name=\"A\">Bound item type</typeparam>\n    /// <param name=\"list\">Enumerable to reduce</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static A reduce<A>(IEnumerable<A> list, Func<A, A, A> reducer) =>\n        list.Match(\n            ()      => failwith<A>(\"Input list was empty\"),\n            (x, xs) => fold(xs, x, reducer));\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from first element to last), threading \n    /// an accumulator argument through the computation. This function first applies the function \n    /// to the first two elements of the list. Then, it passes this result into the function along \n    /// with the third element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <remarks>The enumerable must contain at least one item or None will be returned</remarks>\n    /// <typeparam name=\"A\">Bound item type</typeparam>\n    /// <param name=\"list\">Enumerable to reduce</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Optional aggregate value</returns>\n    [Pure]\n    public static Option<A> reduceOrNone<A>(IEnumerable<A> list, Func<A, A, A> reducer) =>\n        list.Match(\n            ()      => None,\n            (x, xs) => Some(fold(xs, x, reducer)));\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function first applies the function to the first two \n    /// elements of the list. Then, it passes this result into the function along with the third \n    /// element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <remarks>The enumerable must contain at least one item or an excpetion will be thrown</remarks>\n    /// <typeparam name=\"A\">Bound item type</typeparam>\n    /// <param name=\"list\">Enumerable to reduce</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static A reduceBack<A>(IEnumerable<A> list, Func<A, A, A> reducer) =>\n        list.Match(\n            ()      => failwith<A>(\"Input list was empty\"),\n            (x, xs) => foldBack(xs, x, reducer));\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function first applies the function to the first two \n    /// elements of the list. Then, it passes this result into the function along with the third \n    /// element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <remarks>The enumerable must contain at least one item or None will be returned</remarks>\n    /// <typeparam name=\"A\">Bound item type</typeparam>\n    /// <param name=\"list\">Enumerable to reduce</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Optional aggregate value</returns>\n    [Pure]\n    public static Option<A> reduceBackOrNone<A>(IEnumerable<A> list, Func<A, A, A> reducer) =>\n        list.Match(\n            ()      => None,\n            (x, xs) => Some(foldBack(xs, x, reducer)));\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function takes the state argument, and applies the function \n    /// to it and the first element of the list. Then, it passes this result into the function \n    /// along with the second element, and so on. Finally, it returns the list of intermediate \n    /// results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static IEnumerable<S> scan<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder)\n    {\n        yield return state;\n        foreach (var item in list)\n        {\n            state = folder(state, item);\n            yield return state;\n        }\n    }\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from last element to first), \n    /// threading an accumulator argument through the computation. This function takes the state \n    /// argument, and applies the function to it and the first element of the list. Then, it \n    /// passes this result into the function along with the second element, and so on. Finally, \n    /// it returns the list of intermediate results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static IEnumerable<S> scanBack<S, T>(IEnumerable<T> list, S state, Func<S, T, S> folder) =>\n        scan(rev(list), state, folder);\n\n    /// <summary>\n    /// Returns Some(x) for the first item in the list that matches the predicate \n    /// provided, None otherwise.\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to search</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Some(x) for the first item in the list that matches the predicate \n    /// provided, None otherwise.</returns>\n    [Pure]\n    public static Option<T> find<T>(IEnumerable<T> list, Func<T, bool> pred)\n    {\n        foreach (var item in list)\n        {\n            if (pred(item)) return Some(item);\n        }\n        return None;\n    }\n\n    /// <summary>\n    /// Returns [x] for the first item in the list that matches the predicate \n    /// provided, [] otherwise.\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to search</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>[x] for the first item in the list that matches the predicate \n    /// provided, [] otherwise.</returns>\n    [Pure]\n    public static IEnumerable<T> findSeq<T>(IEnumerable<T> list, Func<T, bool> pred)\n    {\n        foreach (var item in list)\n        {\n            if (pred(item))\n            {\n                yield return item;\n                break;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Convert any enumerable into an immutable Lst T\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to convert</param>\n    /// <returns>Lst of T</returns>\n    [Pure]\n    public static Lst<T> freeze<T>(IEnumerable<T> list) =>\n        toList(list);\n\n    /// <summary>\n    /// Joins two enumerables together either into a single enumerable\n    /// using the join function provided\n    /// </summary>\n    /// <param name=\"list\">First list to join</param>\n    /// <param name=\"other\">Second list to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined enumerable</returns>\n    [Pure]\n    public static IEnumerable<V> zip<T, U, V>(IEnumerable<T> list, IEnumerable<U> other, Func<T, U, V> zipper) =>\n        list.Zip(other, zipper);\n\n    /// <summary>\n    /// Joins two enumerables together either into an enumerables of tuples\n    /// </summary>\n    /// <param name=\"list\">First list to join</param>\n    /// <param name=\"other\">Second list to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined enumerable of tuples</returns>\n    [Pure]\n    public static IEnumerable<(T First, U Second)> zip<T, U>(IEnumerable<T> list, IEnumerable<U> other) =>\n        list.Zip(other, (t, u) => (t, u));\n\n    /// <summary>\n    /// Returns the number of items in the enumerable\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to count</param>\n    /// <returns>The number of items in the enumerable</returns>\n    [Pure]\n    public static int length<T>(IEnumerable<T> list) =>\n        list.Count();\n\n    /// <summary>\n    /// Invokes an action for each item in the enumerable in order\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to iterate</param>\n    /// <param name=\"action\">Action to invoke with each item</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<T>(IEnumerable<T> list, Action<T> action)\n    {\n        foreach (var item in list)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Invokes an action for each item in the enumerable in order and supplies\n    /// a running index value.\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to iterate</param>\n    /// <param name=\"action\">Action to invoke with each item</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<T>(IEnumerable<T> list, Action<int, T> action)\n    {\n        var i = 0;\n        foreach (var item in list)\n        {\n            action(i++, item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Iterate each item in the enumerable in order (consume items)\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to consume</param>\n    /// <returns>Unit</returns>\n    public static Unit consume<T>(IEnumerable<T> list)\n    {\n        foreach (var _ in list)\n        {\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Returns true if all items in the enumerable match a predicate (Any in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to test</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the enumerable match the predicate</returns>\n    [Pure]\n    public static bool forall<T>(IEnumerable<T> list, Func<T, bool> pred) =>\n        list.All(pred);\n\n    /// <summary>\n    /// Return a new enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <returns>A new enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static IEnumerable<T> distinct<T>(IEnumerable<T> list) =>\n        list.Distinct();\n\n    /// <summary>\n    /// Return a new enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <returns>A new enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static IEnumerable<T> distinct<EQ, T>(IEnumerable<T> list) where EQ : Eq<T> =>\n        list.Distinct(new EqCompare<T>(static (x, y) => EQ.Equals(x, y), static x => EQ.GetHashCode(x)));\n\n    /// <summary>\n    /// Return a new enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <returns>A new enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static IEnumerable<T> distinct<T, K>(IEnumerable<T> list, Func<T, K> keySelector, Option<Func<K, K, bool>> compare = default) =>\n        list.Distinct(new EqCompare<T>(\n                          (a, b) => compare.IfNone(EqDefault<K>.Equals)(keySelector(a), keySelector(b)), \n                          a => keySelector(a)?.GetHashCode() ?? 0));\n\n    /// <summary>\n    /// Returns a new enumerable with the first 'count' items from the enumerable provided\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first 'count' items from the enumerable provided</returns>\n    [Pure]\n    public static IEnumerable<T> take<T>(IEnumerable<T> list, int count) =>\n        list.Take(count);\n\n    /// <summary>\n    /// Iterate the list, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first items that match the predicate</returns>\n    [Pure]\n    public static IEnumerable<T> takeWhile<T>(IEnumerable<T> list, Func<T, bool> pred) =>\n        list.TakeWhile(pred);\n\n    /// <summary>\n    /// Iterate the list, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't.  An index value is also provided to the predicate function.\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first items that match the predicate</returns>\n    [Pure]\n    public static IEnumerable<T> takeWhile<T>(IEnumerable<T> list, Func<T, int, bool> pred) =>\n        list.TakeWhile(pred);\n\n    /// <summary>\n    /// Generate a new list from an intial state value and an 'unfolding' function.\n    /// The unfold function generates the items in the resulting list until None is returned.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"unfolder\">Unfold function</param>\n    /// <returns>Unfolded enumerable</returns>\n    [Pure]\n    public static IEnumerable<S> unfold<S>(S state, Func<S, Option<S>> unfolder)\n    {\n        while (true)\n        {\n            yield return state;\n            var res = unfolder(state);\n            if (res.IsNone)\n            {\n                yield break;\n            }\n            else\n            {\n                state = res.Value!;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Generate a new list from an intial state value and an 'unfolding' function.  An aggregate\n    /// state value is threaded through separately to the yielded value.\n    /// The unfold function generates the items in the resulting list until None is returned.\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value of resulting enumerable</typeparam>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"unfolder\">Unfold function</param>\n    /// <returns>Unfolded enumerable</returns>\n    [Pure]\n    public static IEnumerable<A> unfold<S, A>(S state, Func<S, Option<(A, S)>> unfolder)\n    {\n        while (true)\n        {\n            var res = unfolder(state);\n            if (res.IsNone)\n            {\n                yield break;\n            }\n            else\n            {\n                state = res.Value.Item2;\n                yield return res.Value.Item1;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Generate a new list from an intial state value and an 'unfolding' function.  An aggregate\n    /// state value is threaded through separately to the yielded value.\n    /// The unfold function generates the items in the resulting list until None is returned.\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value of resulting enumerable</typeparam>\n    /// <typeparam name=\"S1\">State type</typeparam>\n    /// <typeparam name=\"S2\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"unfolder\">Unfold function</param>\n    /// <returns>Unfolded enumerable</returns>\n    [Pure]\n    public static IEnumerable<A> unfold<S1, S2, A>((S1, S2) state, Func<S1, S2, Option<(A, S1, S2)>> unfolder)\n    {\n        while (true)\n        {\n            var res = unfolder(state.Item1, state.Item2);\n            if (res.IsNone)\n            {\n                yield break;\n            }\n            else\n            {\n                state = (res.Value.Item2, res.Value.Item3);\n                yield return res.Value.Item1;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Generate a new list from an intial state value and an 'unfolding' function.  An aggregate\n    /// state value is threaded through separately to the yielded value.\n    /// The unfold function generates the items in the resulting list until None is returned.\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value of resulting enumerable</typeparam>\n    /// <typeparam name=\"S1\">State type</typeparam>\n    /// <typeparam name=\"S2\">State type</typeparam>\n    /// <typeparam name=\"S3\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"unfolder\">Unfold function</param>\n    /// <returns>Unfolded enumerable</returns>\n    [Pure]\n    public static IEnumerable<A> unfold<S1, S2, S3, A>((S1, S2, S3) state, Func<S1, S2, S3, Option<(A, S1, S2, S3)>> unfolder)\n    {\n        while (true)\n        {\n            var res = unfolder(state.Item1, state.Item2, state.Item3);\n            if (res.IsNone)\n            {\n                yield break;\n            }\n            else\n            {\n                state = (res.Value.Item2, res.Value.Item3, res.Value.Item4);\n                yield return res.Value.Item1;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Generate a new list from an intial state value and an 'unfolding' function.  An aggregate\n    /// state value is threaded through separately to the yielded value.\n    /// The unfold function generates the items in the resulting list until None is returned.\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value of resulting enumerable</typeparam>\n    /// <typeparam name=\"S1\">State type</typeparam>\n    /// <typeparam name=\"S2\">State type</typeparam>\n    /// <typeparam name=\"S3\">State type</typeparam>\n    /// <typeparam name=\"S4\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"unfolder\">Unfold function</param>\n    /// <returns>Unfolded enumerable</returns>\n    [Pure]\n    public static IEnumerable<A> unfold<S1, S2, S3, S4, A>((S1, S2, S3, S4) state, Func<S1, S2, S3, S4, Option<(A, S1, S2, S3, S4)>> unfolder)\n    {\n        while (true)\n        {\n            var res = unfolder(state.Item1, state.Item2, state.Item3, state.Item4);\n            if (res.IsNone)\n            {\n                yield break;\n            }\n            else\n            {\n                state = (res.Value.Item2, res.Value.Item3, res.Value.Item4, res.Value.Item5);\n                yield return res.Value.Item1;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Returns true if any item in the enumerable matches the predicate provided\n    /// </summary>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to test</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if any item in the enumerable matches the predicate provided</returns>\n    [Pure]\n    public static bool exists<T>(IEnumerable<T> list, Func<T, bool> pred)\n    {\n        foreach (var item in list)\n        {\n            if (pred(item))\n                return true;\n        }\n        return false;\n    }\n\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    [Obsolete(\"headSafe has been deprecated, please use headOrNone\")]\n    public static Option<T> headSafe<T>(IEnumerable<T> list) =>\n        (from x in list\n         select Some(x))\n       .DefaultIfEmpty(None)\n       .FirstOrDefault();\n\n    /// <summary>\n    /// The tails function returns all final segments of the argument, longest first. For example,\n    ///  i.e. tails(['a','b','c']) == [['a','b','c'], ['b','c'], ['c'],[]]\n    /// </summary>\n    /// <typeparam name=\"T\">List item type</typeparam>\n    /// <param name=\"self\">List</param>\n    /// <returns>Enumerable of Enumerables of T</returns>\n    [Pure]\n    public static IEnumerable<IEnumerable<T>> tails<T>(IEnumerable<T> self)\n    {\n        var lst = new List<T>(self);\n        for (var skip = 0; skip < lst.Count; skip++)\n        {\n            yield return lst.Skip(skip);\n        }\n        yield return Enumerable.Empty<T>();\n    }\n\n    /// <summary>\n    /// Span, applied to a predicate 'pred' and a list, returns a tuple where first element is \n    /// longest prefix (possibly empty) of elements that satisfy 'pred' and second element is the \n    /// remainder of the list:\n    /// </summary>\n    /// <example>\n    /// List.span(List(1,2,3,4,1,2,3,4), x => x 〈 3) == (List(1,2),List(3,4,1,2,3,4))\n    /// </example>\n    /// <example>\n    /// List.span(List(1,2,3), x => x 〈 9) == (List(1,2,3),List())\n    /// </example>\n    /// <example>\n    /// List.span(List(1,2,3), x => x 〈 0) == (List(),List(1,2,3))\n    /// </example>\n    /// <typeparam name=\"T\">List element type</typeparam>\n    /// <param name=\"self\">List</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Split list</returns>\n    [Pure]\n    public static (IEnumerable<T> Initial, IEnumerable<T> Remainder) span<T>(IEnumerable<T> self, Func<T, bool> pred)\n    {\n        var iter    = self.GetEnumerator();\n        var diposed = false;\n\n        IEnumerable<T> first(IEnumerator<T> items)\n        {\n            while (items.MoveNext())\n            {\n                if (pred(items.Current))\n                {\n                    yield return items.Current;\n                }\n                else\n                {\n                    yield break;\n                }\n            }\n            items.Dispose();\n            diposed = true;\n        }\n\n        IEnumerable<T> second(IEnumerator<T> items)\n        {\n            if (diposed) yield break;\n            while (items.MoveNext())\n            {\n                yield return items.Current;\n            }\n            items.Dispose();\n        }\n\n        return (first(iter), second(iter));\n    }\n}\n\nclass EqCompare<T> : IEqualityComparer<T>\n{\n    readonly Func<T, T, bool> compare;\n    readonly Option<Func<T, int>> hashCode = None;\n\n    public EqCompare(Func<T, T, bool> compare) =>\n        this.compare = compare;\n\n    public EqCompare(Func<T, T, bool> compare, Func<T, int> hashCode)\n    {\n        this.compare = compare;\n        this.hashCode = hashCode;\n    }\n\n    [Pure]\n    public bool Equals(T? x, T? y) =>\n        isnull(x) && isnull(y) || (!isnull(x) && !isnull(y) && compare(x!, y!));\n\n    [Pure]\n    public int GetHashCode(T obj) =>\n        hashCode.Match(\n            f => isnull(obj) ? 0 : f(obj),\n            () => 0);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/Lst.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable list\n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\n[Serializable]\n[CollectionBuilder(typeof(List), nameof(List.createRange))]\npublic readonly struct Lst<A> :\n    IComparable<Lst<A>>,\n    IComparable,\n    IReadOnlyList<A>,\n    IEquatable<Lst<A>>,\n    IComparisonOperators<Lst<A>, Lst<A>, bool>,\n    IAdditionOperators<Lst<A>, Lst<A>, Lst<A>>,\n    ISubtractionOperators<Lst<A>, Lst<A>, Lst<A>>,\n    IAdditiveIdentity<Lst<A>, Lst<A>>,\n    Monoid<Lst<A>>,\n    K<Lst, A>\n{\n    /// <summary>\n    /// Empty list\n    /// </summary>\n    public static Lst<A> Empty { get; } = new (System.Array.Empty<A>().AsSpan());\n    \n    readonly LstInternal<A>? value;\n    internal LstInternal<A> Value\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value ?? LstInternal<A>.Empty;\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst(IEnumerable<A> initial) =>\n        value = new LstInternal<A>(initial);\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst(ReadOnlySpan<A> initial) =>\n        value = new LstInternal<A>(initial);\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    Lst(LstInternal<A> initial) =>\n        value = initial;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal Lst(ListItem<A> root) =>\n        value = new LstInternal<A>(root);\n\n    ListItem<A> Root\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.Root;\n    }\n\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Count == 0;\n    }\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = null\n    ///     Singleton collection = A\n    ///     More                 = (A, Seq〈A〉)   -- head and tail\n    ///\n    ///  Example:\n    ///\n    ///     var res = list.Case switch\n    ///     {\n    ///       \n    ///        A value         => ...,\n    ///        (var x, var xs) => ...,\n    ///        _               => ...\n    ///     }\n    ///\n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty \n            ? null\n            : Count == 1\n                ? this[0]\n                : toSeq(this).Case;\n\n    /// <summary>\n    /// Head lens\n    /// </summary>\n    [Pure]\n    public static Lens<Lst<A>, A> head\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Lens<Lst<A>, A>.New(\n            Get: la => la.Count == 0 ? throw new IndexOutOfRangeException() : la[0],\n            Set: a => la => la.Count == 0 ? throw new IndexOutOfRangeException() : la.SetItem(0, a));\n    }\n\n    /// <summary>\n    /// Head or none lens\n    /// </summary>\n    [Pure]\n    public static Lens<Lst<A>, Option<A>> headOrNone\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Lens<Lst<A>, Option<A>>.New(\n            Get: la => la.Count == 0 ? None : Some(la[0]),\n            Set: a => la => la.Count == 0 || a.IsNone ? la : la.SetItem(0, a.Value!));\n    }\n\n    /// <summary>\n    /// Tail lens\n    /// </summary>\n    [Pure]\n    public static Lens<Lst<A>, A> tail\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Lens<Lst<A>, A>.New(\n            Get: la => la.Count == 0 ? throw new IndexOutOfRangeException() : la[^1],\n            Set: a => la => la.Count == 0 ? throw new IndexOutOfRangeException() : la.SetItem(la.Count - 1, a));\n    }\n\n    /// <summary>\n    /// Tail or none lens\n    /// </summary>\n    [Pure]\n    public static Lens<Lst<A>, Option<A>> tailOrNone\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Lens<Lst<A>, Option<A>>.New(\n            Get: la => la.Count == 0 ? None : Some(la[la.Count - 1]),\n            Set: a => la => la.Count == 0 || a.IsNone ? la : la.SetItem(la.Count - 1, a.Value!));\n    }\n\n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Lst<A>, A> item(int index) => Lens<Lst<A>, A>.New(\n        Get: la => la.Count == 0 ? throw new IndexOutOfRangeException() : la[index],\n        Set: a => la => la.Count == 0 ? throw new IndexOutOfRangeException() : la.SetItem(index, a)\n    );\n\n    /// <summary>\n    /// Item or none at index lens\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Lst<A>, Option<A>> itemOrNone(int index) => Lens<Lst<A>, Option<A>>.New(\n        Get: la => la.Count < index - 1 ? None : Some(la[index]),\n        Set: a => la => la.Count < index - 1 || a.IsSome ? la : la.SetItem(index, a.Value!)\n    );\n\n    /// <summary>\n    /// Lens map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Lst<A>, Lst<B>> map<B>(Lens<A, B> lens) => Lens<Lst<A>, Lst<B>>.New(\n        Get: la => la.Map(lens.Get),\n        Set: lb => la => la.Zip(lb).Map(ab => lens.Set(ab.Item2, ab.Item1)).ToLst()\n    );\n\n    /// <summary>\n    /// Index accessor\n    /// </summary>\n    [Pure]\n    public A this[Index index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            if (index.Value < 0 || index.Value >= Root.Count) throw new IndexOutOfRangeException();\n            return ListModule.GetItem(Root, index.GetOffset(Count));\n        }\n    }\n\n    /// <summary>\n    /// Safe index accessor\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<A> At(int index)\n    {\n        if (index < 0 || index >= Root.Count) return default;\n        return ListModule.GetItem(Root, index);\n    }\n\n    /// <summary>\n    /// Number of items in the list\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Root.Count;\n    }\n\n    [Pure]\n    int IReadOnlyCollection<A>.Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Count;\n    }\n\n    /*\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public StreamT<M, A> AsStream<M>()\n        where M : Monad<M> =>\n        StreamT<M, A>.Lift(this);\n        */\n\n    [Pure]\n    A IReadOnlyList<A>.this[int index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            if (index < 0 || index >= Root.Count) throw new IndexOutOfRangeException();\n            return ListModule.GetItem(Root, index);\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    Lst<A> Wrap(LstInternal<A> list) =>\n        new (list);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static Lst<X> Wrap<X>(LstInternal<X> list) =>\n        new (list);\n\n    /// <summary>\n    /// Find if a value is in the collection\n    /// </summary>\n    /// <param name=\"value\">Value to test</param>\n    /// <returns>True if collection contains value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(A value) =>\n        Value.AsIterable().Find(a => EqDefault<A>.Equals(a, value)).IsSome;\n\n    /// <summary>\n    /// Contains with provided Eq class instance\n    /// </summary>\n    /// <typeparam name=\"EqA\">Eq class instance</typeparam>\n    /// <param name=\"value\">Value to test</param>\n    /// <returns>True if collection contains value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains<EqA>(A value) where EqA : Eq<A> =>\n        Value.AsIterable().Find(a => EqA.Equals(a, value)).IsSome;\n\n    /// <summary>\n    /// Add an item to the end of the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Add(A value) =>\n        Wrap(Value.Add(value));\n\n    /// <summary>\n    /// Add a range of items to the end of the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> AddRange(IEnumerable<A> items) =>\n        Wrap(Value.AddRange(items));\n\n    /// <summary>\n    /// Clear the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ListEnumerator<A> GetEnumerator() =>\n        new (Root, false, 0);\n\n    /// <summary>\n    /// Find the index of an item\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int IndexOf(A item, int index = 0, int count = -1, IEqualityComparer<A>? equalityComparer = null) =>\n        Value.IndexOf(item, index, count, equalityComparer);\n\n    /// <summary>\n    /// Insert value at specified index\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Insert(int index, A value) =>\n        Wrap(Value.Insert(index, value));\n\n    /// <summary>\n    /// Insert range of values at specified index\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> InsertRange(int index, IEnumerable<A> items) =>\n        Wrap(Value.InsertRange(index, items));\n\n    /// <summary>\n    /// Find the last index of an item in the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int LastIndexOf(A item, int index = 0, int count = -1, IEqualityComparer<A>? equalityComparer = null) =>\n        Value.LastIndexOf(item, index, count, equalityComparer);\n\n    /// <summary>\n    /// Remove all items that match the value from the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Remove(A value) =>\n        Wrap(Value.Remove(value));\n\n    /// <summary>\n    /// Remove all items that match the value from the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Remove(A value, IEqualityComparer<A> equalityComparer) =>\n        Wrap(Value.Remove(value, equalityComparer));\n\n    /// <summary>\n    /// Remove all items that match a predicate\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> RemoveAll(Func<A, bool> pred) =>\n        Wrap(Value.RemoveAll(pred));\n\n    /// <summary>\n    /// Remove item at location\n    /// </summary>\n    /// <param name=\"index\"></param>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> RemoveAt(int index) =>\n        Wrap(Value.RemoveAt(index));\n\n    /// <summary>\n    /// Remove a range of items\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> RemoveRange(int index, int count) =>\n        Wrap(Value.RemoveRange(index, count));\n\n    /// <summary>\n    /// Set an item at the specified index\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> SetItem(int index, A value) =>\n        Wrap(Value.SetItem(index, value));\n\n    /// <summary>\n    /// Returns an enumerable range from the collection.  This is the fastest way of\n    /// iterating sub-ranges of the collection.\n    /// </summary>\n    /// <param name=\"index\">Index into the collection</param>\n    /// <param name=\"count\">Number of items to find</param>\n    /// <returns>IEnumerable of items</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> FindRange(int index, int count) =>\n        Value.FindRange(index, count);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        new ListEnumerator<A>(Root, false, 0);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<A> IEnumerable<A>.GetEnumerator() =>\n        new ListEnumerator<A>(Root, false, 0);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> ToSeq() =>\n        toSeq(this);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(this, Count);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(this, separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(this, separator);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> AsIterable() =>\n        Iterable.createRange(this);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> Skip(int amount) =>\n        Value.Skip(amount);\n\n    /// <summary>\n    /// Reverse the order of the items in the list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Reverse() =>\n        Wrap(Value.Reverse());\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Do(Action<A> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<U> Map<U>(Func<A, U> map) =>\n        Wrap(Value.Map(map));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Lst<B>> Traverse<F, B>(Func<A, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, Lst<B>> TraverseM<M, B>(Func<A, K<M, B>> f) \n        where M : Monad<M> =>\n        M.Map(x => x.As(), Traversable.traverseM(f, this));\n    \n    /// <summary>\n    /// Filter\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Filter(Func<A, bool> pred) =>\n        Wrap(Value.Filter(pred));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lst<A> operator +(Lst<A> lhs, A rhs) =>\n        lhs.Add(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lst<A> operator +(A lhs, Lst<A> rhs) =>\n        lhs.Cons(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lst<A> operator +(Lst<A> lhs, Lst<A> rhs) =>\n        lhs.Combine(rhs);\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lst<A> operator |(Lst<A> x, K<Lst, A> y) =>\n        x.Choose(y).As();\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lst<A> operator |(K<Lst, A> x, Lst<A> y) =>\n        x.Choose(y).As();\n    \n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Combine(Lst<A> rhs) =>\n        new (Value.Combine(rhs.Value));\n    \n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lst<A> operator -(Lst<A> lhs, Lst<A> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> Subtract(Lst<A> rhs) =>\n        Wrap(Value.Subtract(rhs.Value));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj switch\n        {\n            Lst<A> s         => Equals(s),\n            IEnumerable<A> e => Equals(e.AsIterable().ToLst()),\n            _                => false\n        };\n\n    /// <summary>\n    /// Get the hash code\n    /// Lazily (and once only) calculates the hash from the elements in the list\n    /// Empty list hash == 0\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            Lst<A> s         => CompareTo(s),\n            IEnumerable<A> e => CompareTo(e.AsIterable().ToLst()),\n            _                => 1\n        };\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(Lst<A> other) =>\n        Value.Equals(other.Value);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(Lst<A> lhs, Lst<A> rhs) =>\n        lhs.Value.Equals(rhs.Value);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(Lst<A> lhs, Lst<A> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <(Lst<A> lhs, Lst<A> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <=(Lst<A> lhs, Lst<A> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >(Lst<A> lhs, Lst<A> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >=(Lst<A> lhs, Lst<A> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> ToArr() =>\n        toArray(this);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal A[] ToArray() =>\n        Value.ToArray();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(Lst<A> other) =>\n        Value.CompareTo(other.Value);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Lst<A>(SeqEmpty _) =>\n        Empty;\n\n    public static Lst<A> AdditiveIdentity => \n        Empty;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/Operators/Lst.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SeqExtensions\n{\n    extension<A>(K<Lst, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Lst<A> operator +(K<Lst, A> ma) =>\n            (Lst<A>)ma;\n        \n        public static Lst<A> operator >> (K<Lst, A> ma, Lower lower) =>\n            (Lst<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/Prelude/Lst.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Lst<B> map<A, B>(Func<A, B> f, K<Lst, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Lst<B> action<A, B>(K<Lst, A> ma, K<Lst, B> mb) =>\n        Applicative.action(ma, mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Lst<B> apply<A, B>(K<Lst, Func<A, B>> mf, K<Lst, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/List/Trait/Lst.TraitImpl.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic class Lst : \n    Monad<Lst>, \n    MonoidK<Lst>,\n    Alternative<Lst>, \n    Traversable<Lst>\n{\n    static K<Lst, B> Monad<Lst>.Recur<A, B>(A value, Func<A, K<Lst, Next<A, B>>> f) =>\n        List.createRange(Monad.enumerableRecur(value, x =>f(x).As().AsEnumerable()));\n    \n    static K<Lst, B> Monad<Lst>.Bind<A, B>(K<Lst, A> ma, Func<A, K<Lst, B>> f)\n    {\n        return new Lst<B>(go());\n        IEnumerable<B> go()\n        {\n            foreach (var x in ma.As())\n            {\n                foreach (var y in f(x).As())\n                {\n                    yield return y;\n                }\n            }\n        }\n    }\n\n    static K<Lst, B> Functor<Lst>.Map<A, B>(Func<A, B> f, K<Lst, A> ma)\n    {\n        return new Lst<B>(go());\n        IEnumerable<B> go()\n        {\n            foreach (var x in ma.As())\n            {\n                yield return f(x);\n            }\n        }\n    }\n\n    static K<Lst, A> Applicative<Lst>.Pure<A>(A value) =>\n        List.singleton(value);\n\n    static K<Lst, B> Applicative<Lst>.Apply<A, B>(K<Lst, Func<A, B>> mf, K<Lst, A> ma)\n    {\n        return new Lst<B>(go());\n        IEnumerable<B> go()\n        {\n            foreach (var f in mf.As())\n            {\n                foreach (var a in ma.As())\n                {\n                    yield return f(a);\n                }\n            }\n        }\n    }\n\n    static K<Lst, B> Applicative<Lst>.Apply<A, B>(K<Lst, Func<A, B>> mf, Memo<Lst, A> ma)\n    {\n        return new Lst<B>(go());\n        IEnumerable<B> go()\n        {\n            foreach (var f in mf.As())\n            {\n                foreach (var a in ma.Value.As())\n                {\n                    yield return f(a);\n                }\n            }\n        }\n    }\n\n    static K<Lst, A> MonoidK<Lst>.Empty<A>() =>\n        Lst<A>.Empty;\n\n    static K<Lst, A> Alternative<Lst>.Empty<A>() =>\n        Lst<A>.Empty;\n\n    static K<Lst, A> SemigroupK<Lst>.Combine<A>(K<Lst, A> ma, K<Lst, A> mb) => \n        ma.As() + mb.As();\n\n    static K<Lst, A> Choice<Lst>.Choose<A>(K<Lst, A> ma, K<Lst, A> mb) => \n        ma.IsEmpty ? mb : ma;\n\n    static K<Lst, A> Choice<Lst>.Choose<A>(K<Lst, A> ma, Memo<Lst, A> mb) => \n        ma.IsEmpty ? mb.Value : ma;\n\n    static K<F, K<Lst, B>> Traversable<Lst>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Lst, A> ta)\n    {\n        return Foldable.fold(add, F.Pure(Lst<B>.Empty), ta)\n                       .Map(bs => bs.Kind());\n\n        Func<K<F, Lst<B>>, K<F, Lst<B>>> add(A value) =>\n            state =>\n                Applicative.lift((bs, b) => bs.Add(b), state, f(value));                                            \n    }\n\n    static K<F, K<Lst, B>> Traversable<Lst>.TraverseM<F, A, B>(Func<A, K<F, B>> f, K<Lst, A> ta) \n    {\n        return Foldable.fold(add, F.Pure(Lst<B>.Empty), ta)\n                       .Map(bs => bs.Kind());\n\n        Func<K<F, Lst<B>>, K<F, Lst<B>>> add(A value) =>\n            state =>\n                state.Bind(\n                    bs => f(value).Bind(\n                        b => F.Pure(bs.Add(b)))); \n    }    \n    \n    static S Foldable<Lst>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Lst, A> ta)\n    {\n        foreach (var x in ta.As())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(x)(state);\n        }\n        return state;\n    }\n    \n    static S Foldable<Lst>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S state, \n        K<Lst, A> ta)\n    {\n        foreach (var x in ta.As().Reverse())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(state)(x);\n        }\n        return state;\n    }\n\n    static int Foldable<Lst>.Count<A>(K<Lst, A> ta) =>\n        ta.As().Count;\n\n    static bool Foldable<Lst>.IsEmpty<A>(K<Lst, A> ta) =>\n        ta.As().IsEmpty;\n\n    static Option<A> Foldable<Lst>.At<A>(K<Lst, A> ta, Index index)\n    {\n        var list = ta.As().Value;\n        return index.Value >= 0 && index.Value < list.Count\n                   ? Some(list[index])\n                   : Option<A>.None;\n    }\n        \n    static Arr<A> Foldable<Lst>.ToArr<A>(K<Lst, A> ta) =>\n        new(ta.As());\n\n    static Lst<A> Foldable<Lst>.ToLst<A>(K<Lst, A> ta) =>\n        ta.As();\n\n    static Iterable<A> Foldable<Lst>.ToIterable<A>(K<Lst, A> ta) =>\n        Iterable.createRange (ta.As());\n    \n    static Seq<A> Foldable<Lst>.ToSeq<A>(K<Lst, A> ta) =>\n        new (ta.As());\n    \n    static Fold<A, S> Foldable<Lst>.FoldStep<A, S>(K<Lst, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }   \n    \n    static Fold<A, S> Foldable<Lst>.FoldStepBack<A, S>(K<Lst, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().Reverse().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }   \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.EnumeratorK.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\npublic struct MapKeyEnumerator<K, V> : IEnumerator<K>\n{\n    struct NewStack : New<MapItem<K, V>[]>\n    {\n        public MapItem<K, V>[] New() =>\n            new MapItem<K, V>[32];\n    }\n\n    int stackDepth;\n    MapItem<K, V>[] stack;\n    readonly MapItem<K, V> map;\n    int left;\n    readonly bool rev;\n    readonly int start;\n\n    internal MapKeyEnumerator(MapItem<K, V> root, bool rev, int start)\n    {\n        this.rev = rev;\n        this.start = start;\n        map = root;\n        stack = Pool<NewStack, MapItem<K, V>[]>.Pop();\n        stackDepth = default;\n        left = default;\n        NodeCurrent = default!;\n        Reset();\n    }\n\n    private MapItem<K, V> NodeCurrent\n    {\n        get;\n        set;\n    }\n\n    public readonly K Current => NodeCurrent.KeyValue.Key;\n    readonly object IEnumerator.Current => NodeCurrent.KeyValue.Key!;\n\n    public void Dispose()\n    {\n        if (stack is not null)\n        {\n            Pool<NewStack, MapItem<K, V>[]>.Push(stack);\n            stack = default!;\n        }\n    }\n\n    private MapItem<K, V> Next(MapItem<K, V> node) =>\n        rev ? node.Left : node.Right;\n\n    private MapItem<K, V> Prev(MapItem<K, V> node) =>\n        rev ? node.Right : node.Left;\n\n    private void Push(MapItem<K, V> node)\n    {\n        while (!node.IsEmpty)\n        {\n            stack[stackDepth] = node;\n            stackDepth++;\n            node = Prev(node);\n        }\n    }\n\n    public bool MoveNext()\n    {\n        if (left > 0 && stackDepth > 0)\n        {\n            stackDepth--;\n            NodeCurrent = stack[stackDepth];\n            Push(Next(NodeCurrent));\n            left--;\n            return true;\n        }\n\n        NodeCurrent = null!;\n        return false;\n    }\n\n    public void Reset()\n    {\n        var skip = rev ? map.Count - start - 1 : start;\n\n        stackDepth = 0;\n        NodeCurrent = map;\n        left = map.Count;\n\n        while (!NodeCurrent.IsEmpty && skip != Prev(NodeCurrent).Count)\n        {\n            if (skip < Prev(NodeCurrent).Count)\n            {\n                stack[stackDepth] = NodeCurrent;\n                stackDepth++;\n                NodeCurrent = Prev(NodeCurrent);\n            }\n            else\n            {\n                skip -= Prev(NodeCurrent).Count + 1;\n                NodeCurrent = Next(NodeCurrent);\n            }\n        }\n\n        if (!NodeCurrent.IsEmpty)\n        {\n            stack[stackDepth] = NodeCurrent;\n            stackDepth++;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.EnumeratorKV.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\npublic struct MapEnumerator<K, V> : IEnumerator<(K Key, V Value)>\n{\n    internal struct NewStack : New<MapItem<K, V>[]>\n    {\n        public MapItem<K, V>[] New() =>\n            new MapItem<K, V>[32];\n    }\n\n    int stackDepth;\n    MapItem<K, V>[] stack;\n    readonly MapItem<K, V> map;\n    int left;\n    readonly bool rev;\n    readonly int start;\n\n    internal MapEnumerator(MapItem<K, V> root, bool rev, int start)\n    {\n        this.rev = rev;\n        this.start = start;\n        map = root;\n        stack = Pool<NewStack, MapItem<K, V>[]>.Pop();\n        stackDepth = default;\n        left = default;\n        NodeCurrent = default!;\n        Reset();\n    }\n\n    private MapItem<K, V> NodeCurrent\n    {\n        get;\n        set;\n    }\n\n    public readonly (K Key, V Value) Current => NodeCurrent.KeyValue;\n    readonly object IEnumerator.Current => NodeCurrent.KeyValue;\n\n    public void Dispose()\n    {\n        if (stack is not null)\n        {\n            Pool<NewStack, MapItem<K, V>[]>.Push(stack);\n            stack = default!;\n        }\n    }\n\n    private MapItem<K, V> Next(MapItem<K, V> node) =>\n        rev ? node.Left : node.Right;\n\n    private MapItem<K, V> Prev(MapItem<K, V> node) =>\n        rev ? node.Right : node.Left;\n\n    private void Push(MapItem<K, V> node)\n    {\n        while (!node.IsEmpty)\n        {\n            stack[stackDepth] = node;\n            stackDepth++;\n            node = Prev(node);\n        }\n    }\n\n    public bool MoveNext()\n    {\n        if (left > 0 && stackDepth > 0)\n        {\n            stackDepth--;\n            NodeCurrent = stack[stackDepth];\n            Push(Next(NodeCurrent));\n            left--;\n            return true;\n        }\n\n        NodeCurrent = default!;\n        return false;\n    }\n\n    public void Reset()\n    {\n        var skip = rev ? map.Count - start - 1 : start;\n\n        stackDepth = 0;\n        NodeCurrent = map;\n        left = map.Count;\n\n        while (!NodeCurrent.IsEmpty && skip != Prev(NodeCurrent).Count)\n        {\n            if (skip < Prev(NodeCurrent).Count)\n            {\n                stack[stackDepth] = NodeCurrent;\n                stackDepth++;\n                NodeCurrent = Prev(NodeCurrent);\n            }\n            else\n            {\n                skip -= Prev(NodeCurrent).Count + 1;\n                NodeCurrent = Next(NodeCurrent);\n            }\n        }\n\n        if (!NodeCurrent.IsEmpty)\n        {\n            stack[stackDepth] = NodeCurrent;\n            stackDepth++;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.EnumeratorV.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\npublic struct MapValueEnumerator<K, V> : IEnumerator<V>\n{\n    internal struct NewStack : New<MapItem<K, V>[]>\n    {\n        public MapItem<K, V>[] New() =>\n            new MapItem<K, V>[32];\n    }\n\n    int stackDepth;\n    MapItem<K, V>[] stack;\n    readonly MapItem<K, V> map;\n    int left;\n    readonly bool rev;\n    readonly int start;\n\n    internal MapValueEnumerator(MapItem<K, V> root, bool rev, int start)\n    {\n        this.rev = rev;\n        this.start = start;\n        map = root;\n        stack = Pool<NewStack, MapItem<K, V>[]>.Pop();\n        stackDepth = default;\n        left = default;\n        NodeCurrent = default!;\n        Reset();\n    }\n\n    private MapItem<K, V> NodeCurrent\n    {\n        get;\n        set;\n    }\n\n    public readonly V Current => NodeCurrent.KeyValue.Value;\n    readonly object IEnumerator.Current => NodeCurrent.KeyValue.Value!;\n\n    public void Dispose()\n    {\n        if (stack is not null)\n        {\n            Pool<NewStack, MapItem<K, V>[]>.Push(stack);\n            stack = default!;\n        }\n    }\n\n    private MapItem<K, V> Next(MapItem<K, V> node) =>\n        rev ? node.Left : node.Right;\n\n    private MapItem<K, V> Prev(MapItem<K, V> node) =>\n        rev ? node.Right : node.Left;\n\n    private void Push(MapItem<K, V> node)\n    {\n        while (!node.IsEmpty)\n        {\n            stack[stackDepth] = node;\n            stackDepth++;\n            node = Prev(node);\n        }\n    }\n\n    public bool MoveNext()\n    {\n        if (left > 0 && stackDepth > 0)\n        {\n            stackDepth--;\n            NodeCurrent = stack[stackDepth];\n            Push(Next(NodeCurrent));\n            left--;\n            return true;\n        }\n\n        NodeCurrent = default!;\n        return false;\n    }\n\n    public void Reset()\n    {\n        var skip = rev ? map.Count - start - 1 : start;\n\n        stackDepth = 0;\n        NodeCurrent = map;\n        left = map.Count;\n\n        while (!NodeCurrent.IsEmpty && skip != Prev(NodeCurrent).Count)\n        {\n            if (skip < Prev(NodeCurrent).Count)\n            {\n                stack[stackDepth] = NodeCurrent;\n                stackDepth++;\n                NodeCurrent = Prev(NodeCurrent);\n            }\n            else\n            {\n                skip -= Prev(NodeCurrent).Count + 1;\n                NodeCurrent = Next(NodeCurrent);\n            }\n        }\n\n        if (!NodeCurrent.IsEmpty)\n        {\n            stack[stackDepth] = NodeCurrent;\n            stackDepth++;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class MapExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Map<Key, B> Map<Key, A, B>(this Func<A, B> f, K<Map<Key>, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Map<Key, B> Map<Key, A, B>(this Func<A, B> f, Map<Key, A> ma) =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Extensions.Ord.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing System;\nusing System.Linq;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class MapOrdExtensions\n{\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public static Map<OrdK, K, U> Map<OrdK, K, V, U>(this Map<OrdK, K, V> self, Func<V, U> mapper)\n        where OrdK : Ord<K> =>\n        new (self.AsEnumerable().Select(kv => (kv.Key, mapper(kv.Value))));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public static Map<OrdK, K, U> Map<OrdK, K, V, U>(this Map<OrdK, K, V> self, Func<K, V, U> mapper) where OrdK : Ord<K> =>\n        new (self.AsEnumerable().Select(kv => (kv.Key, mapper(kv.Key, kv.Value))));\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public static int Count<OrdK, K, V>(this Map<OrdK, K, V> self) where OrdK : Ord<K> =>\n        self.Count;\n\n    [Pure]\n    public static int Sum<OrdK, K>(this Map<OrdK, K, int> self) where OrdK : Ord<K> =>\n        self.Values.Sum();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Extensions.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class MapExtensions\n{\n    public static Map<Key, V> As<Key, V>(this K<Map<Key>, V> ma) =>\n        (Map<Key, V>)ma;\n    \n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<K, V> ToMap<K, V>(this IEnumerable<(K, V)> items) =>\n        LanguageExt.Map.createRange(items);\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<K, V> ToMap<K, V>(this IEnumerable<Tuple<K, V>> items) =>\n        LanguageExt.Map.createRange(items);\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<K, V> ToMap<K, V>(this IEnumerable<KeyValuePair<K, V>> items) =>\n        LanguageExt.Map.createRange(items);\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<(K1, K2), V> ToMap<K1, K2, V>(this IEnumerable<(K1, K2, V)> items) =>\n        new(items.Select(x => ((x.Item1, x.Item2), x.Item3)));\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<(K1, K2, K3), V> ToMap<K1, K2, K3, V>(this IEnumerable<(K1, K2, K3, V)> items) =>\n        new(items.Select(x => ((x.Item1, x.Item2, x.Item3), x.Item4)));\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<(K1, K2, K3, K4), V> ToMap<K1, K2, K3, K4, V>(this IEnumerable<(K1, K2, K3, K4, V)> items) =>\n        new(items.Select(x => ((x.Item1, x.Item2, x.Item3, x.Item4), x.Item5)));\n \n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public static Map<K, U> Map<K, V, U>(this Map<K, V> self, Func<V, U> mapper) =>\n        new (self.AsIterable().Select(kv => (kv.Key, mapper( kv.Value))));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public static Map<K, U> Map<K, V, U>(this Map<K, V> self, Func<K, V, U> mapper) =>\n        new (self.AsIterable().Select(kv => (kv.Key, mapper(kv.Key, kv.Value))));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Internal.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing static LanguageExt.Prelude;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.Serialization;\nusing LanguageExt.Traits;\nusing LanguageExt.ClassInstances;\nusing System.Runtime.CompilerServices;\n#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable map\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// [wikipedia.org/wiki/AVL_tree](http://en.wikipedia.org/wiki/AVL_tree)\n/// </summary>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\n[Serializable]\ninternal class MapInternal<OrdK, K, V> :\n    IEnumerable<(K Key, V Value)>\n    where OrdK : Ord<K>\n{\n    public static readonly MapInternal<OrdK, K, V> Empty = new (MapItem<K, V>.Empty, false);\n\n    internal readonly MapItem<K, V> Root;\n    internal readonly bool Rev;\n    int hashCode;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal MapInternal() =>\n        Root = MapItem<K, V>.Empty;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal MapInternal(MapItem<K, V> root, bool rev)\n    {\n        Root = root;\n        Rev = rev;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal MapInternal(ReadOnlySpan<(K Key, V Value)> items, MapModuleM.AddOpt option)\n    {\n        var root = MapItem<K, V>.Empty;\n        foreach (var item in items)\n        {\n            root = MapModuleM.Add<OrdK, K, V>(root, item.Key, item.Value, option);\n        }\n        Root = root;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal MapInternal(IEnumerable<(K Key, V Value)> items, MapModuleM.AddOpt option)\n    {\n        var root = MapItem<K, V>.Empty;\n        foreach (var item in items)\n        {\n            root = MapModuleM.Add<OrdK, K, V>(root, item.Key, item.Value, option);\n        }\n        Root = root;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal MapInternal(IEnumerable<KeyValuePair<K, V>> items, MapModuleM.AddOpt option)\n    {\n        var root = MapItem<K, V>.Empty;\n        foreach (var item in items)\n        {\n            root = MapModuleM.Add<OrdK, K, V>(root, item.Key, item.Value, option);\n        }\n        Root = root;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal MapInternal(IEnumerable<Tuple<K, V>> items, MapModuleM.AddOpt option)\n    {\n        var root = MapItem<K, V>.Empty;\n        foreach (var item in items)\n        {\n            root = MapModuleM.Add<OrdK, K, V>(root, item.Item1, item.Item2, option);\n        }\n        Root = root;\n    }\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public V this[K key]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Find(key).IfNone(() => failwith<V>(\"Key doesn't exist in map\"));\n    }\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Count == 0;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Root.Count;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Count;\n    }\n\n    [Pure]\n    public Option<(K, V)> Min\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Root.IsEmpty\n                   ? None\n                   : MapModule.Min(Root);\n    }\n\n    [Pure]\n    public Option<(K, V)> Max\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Root.IsEmpty\n                   ? None\n                   : MapModule.Max(Root);\n    }\n\n    /// <summary>\n    /// Get the hash code of all items in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        hashCode == 0\n            ? (hashCode = FNV32.Hash<HashablePair<OrdK, HashableDefault<V>, K, V>, (K, V)>(AsIterable()))\n            : hashCode;\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> Add(K key, V value)\n    {\n        if (isnull(key)) throw new ArgumentNullException(nameof(key));\n        if (isnull(value)) throw new ArgumentNullException(nameof(value));\n        return SetRoot(MapModule.Add<OrdK, K, V>(Root, key, value));\n    }\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> TryAdd(K key, V value)\n    {\n        if (isnull(key)) throw new ArgumentNullException(nameof(key));\n        return SetRoot(MapModule.TryAdd<OrdK, K, V>(Root, key, value));\n    }\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists then the Fail handler is called with the unaltered map \n    /// and the value already set for the key, it expects a new map returned.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <param name=\"Fail\">Delegate to handle failure, you're given the unaltered map \n    /// and the value already set for the key</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> TryAdd(K key, V value, Func<MapInternal<OrdK, K, V>, V, MapInternal<OrdK, K, V>> Fail)\n    {\n        if (isnull(key)) throw new ArgumentNullException(nameof(key));\n        return Find(key, v => Fail(this, v), () => Add(key, value));\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> AddRange(IEnumerable<Tuple<K, V>> range)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(range, MapModuleM.AddOpt.ThrowOnDuplicate);\n        }\n\n        var self = Root;\n        foreach (var item in range)\n        {\n            if (isnull(item.Item1)) throw new ArgumentNullException(nameof(item.Item1));\n            self = MapModule.Add<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> AddRange(IEnumerable<(K, V)> range)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(range, MapModuleM.AddOpt.ThrowOnDuplicate);\n        }\n\n        var self = Root;\n        foreach (var item in range)\n        {\n            if (isnull(item.Item1)) throw new ArgumentNullException(nameof(item.Item1));\n            self = MapModule.Add<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> TryAddRange(IEnumerable<Tuple<K, V>> range)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(range, MapModuleM.AddOpt.TryAdd);\n        }\n\n        var self = Root;\n        foreach (var item in range)\n        {\n            if (isnull(item.Item1)) throw new ArgumentNullException(nameof(item.Item1));\n            self = MapModule.TryAdd<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> TryAddRange(IEnumerable<(K, V)> range)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(range, MapModuleM.AddOpt.TryAdd);\n        }\n\n        var self = Root;\n        foreach (var item in range)\n        {\n            if (isnull(item.Item1)) throw new ArgumentNullException(nameof(item.Item1));\n            self = MapModule.TryAdd<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> TryAddRange(IEnumerable<KeyValuePair<K, V>> range)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(range, MapModuleM.AddOpt.TryAdd);\n        }\n\n        var self = Root;\n        foreach (var item in range)\n        {\n            if (isnull(item.Key)) throw new ArgumentNullException(nameof(item.Key));\n            self = MapModule.TryAdd<OrdK, K, V>(self, item.Key, item.Value);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> AddOrUpdateRange(IEnumerable<Tuple<K, V>> range)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(range, MapModuleM.AddOpt.TryUpdate);\n        }\n\n        var self = Root;\n        foreach (var item in range)\n        {\n            if (isnull(item.Item1)) throw new ArgumentNullException(nameof(item.Item1));\n            self = MapModule.AddOrUpdate<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> AddOrUpdateRange(IEnumerable<(K, V)> range)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(range, MapModuleM.AddOpt.TryUpdate);\n        }\n\n        var self = Root;\n        foreach (var item in range)\n        {\n            if (isnull(item.Item1)) throw new ArgumentNullException(nameof(item.Item1));\n            self = MapModule.AddOrUpdate<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(range, MapModuleM.AddOpt.TryUpdate);\n        }\n\n        var self = Root;\n        foreach (var item in range)\n        {\n            if (isnull(item.Key)) throw new ArgumentNullException(nameof(item.Key));\n            self = MapModule.AddOrUpdate<OrdK, K, V>(self, item.Key, item.Value);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> Remove(K key) =>\n        isnull(key)\n            ? this\n            : SetRoot(MapModule.Remove<OrdK, K, V>(Root, key));\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<V> Find(K key) =>\n        isnull(key)\n            ? None\n            : MapModule.TryFind<OrdK, K, V>(Root, key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<V> FindSeq(K key) =>\n        Find(key).ToSeq();\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) =>\n        isnull(key)\n            ? None()\n            : match(MapModule.TryFind<OrdK, K, V>(Root, key), Some, None);\n\n    /// <summary>\n    /// Retrieve the value from predecessor item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<(K, V)> FindPredecessor(K key) => MapModule.TryFindPredecessor<OrdK, K, V>(Root, key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the predecessor item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<(K, V)> FindOrPredecessor(K key) => MapModule.TryFindOrPredecessor<OrdK, K, V>(Root, key);\n\n    /// <summary>\n    /// Retrieve the value from next item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<(K, V)> FindSuccessor(K key) => MapModule.TryFindSuccessor<OrdK, K, V>(Root, key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the next item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<(K, V)> FindOrSuccessor(K key) => MapModule.TryFindOrSuccessor<OrdK, K, V>(Root, key);\n\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (MapInternal<OrdK, K, V> Map, V Value) FindOrAdd(K key, Func<V> None) =>\n        Find(key).Match(\n            Some: x => (this, x),\n            None: () =>\n                  {\n                      var v = None();\n                      return (Add(key, v), v);\n                  });\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (MapInternal<OrdK, K, V>, V Value) FindOrAdd(K key, V value) =>\n        Find(key).Match(\n            Some: x => (this, x),\n            None: () => (Add(key, value), value));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (MapInternal<OrdK, K, V>, Option<V> Value) FindOrMaybeAdd(K key, Func<Option<V>> value) =>\n        Find(key).Match(\n            Some: x => (this, Some(x)),\n            None: () => value().Map(v => (Add(key, v), Some(v)))\n                               .IfNone((this, None)));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (MapInternal<OrdK, K, V>, Option<V> Value) FindOrMaybeAdd(K key, Option<V> value) =>\n        Find(key).Match(\n            Some: x => (this, Some(x)),\n            None: () => value.Map(v => (Add(key, v), Some(v)))\n                             .IfNone((this, None)));\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> SetItem(K key, V value)\n    {\n        if (isnull(key)) throw new ArgumentNullException(nameof(key));\n        return SetRoot(MapModule.SetItem<OrdK, K, V>(Root, key, value));\n    }\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> SetItem(K key, Func<V, V> Some) =>\n        isnull(key)\n            ? this\n            : match(MapModule.TryFind<OrdK, K, V>(Root, key),\n                    Some: x => SetItem(key, Some(x)),\n                    None: () => throw new ArgumentException(\"Key not found in Map\"));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> TrySetItem(K key, V value)\n    {\n        if (isnull(key)) return this;\n        return SetRoot(MapModule.TrySetItem<OrdK, K, V>(Root, key, value));\n    }\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> TrySetItem(K key, Func<V, V> Some) =>\n        isnull(key)\n            ? this\n            : match(MapModule.TryFind<OrdK, K, V>(Root, key),\n                    Some: x => SetItem(key, Some(x)),\n                    None: () => this);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Calls the None delegate to return a new map if the item can't be found\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <param name=\"None\">delegate to return a new map if the item can't be found</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> TrySetItem(K key, Func<V, V> Some, Func<Map<K, V>, Map<K, V>> None) =>\n        isnull(key)\n            ? this\n            : match(MapModule.TryFind<OrdK, K, V>(Root, key),\n                    Some: x => SetItem(key, Some(x)),\n                    None: () => this);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> AddOrUpdate(K key, V value)\n    {\n        if (isnull(key)) throw new ArgumentNullException(nameof(key));\n        return SetRoot(MapModule.AddOrUpdate<OrdK, K, V>(Root, key, value));\n    }\n\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> AddOrUpdate(K key, Func<V, V> Some, Func<V> None) =>\n        isnull(key)\n            ? this\n            : match(MapModule.TryFind<OrdK, K, V>(Root, key),\n                    Some: x => SetItem(key, Some(x)),\n                    None: () => Add(key, None()));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> AddOrUpdate(K key, Func<V, V> Some, V None)\n    {\n        if (isnull(None)) throw new ArgumentNullException(nameof(None));\n\n        return isnull(key)\n                   ? this\n                   : match(MapModule.TryFind<OrdK, K, V>(Root, key),\n                           Some: x => SetItem(key, Some(x)),\n                           None: () => Add(key, None));\n    }\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<V> FindRange(K keyFrom, K keyTo)\n    {\n        if (isnull(keyFrom)) throw new ArgumentNullException(nameof(keyFrom));\n        if (isnull(keyTo)) throw new ArgumentNullException(nameof(keyTo));\n        return OrdK.Compare(keyFrom, keyTo) > 0\n                   ? MapModule.FindRange<OrdK, K, V>(Root, keyTo, keyFrom).AsIterable()\n                   : MapModule.FindRange<OrdK, K, V>(Root, keyFrom, keyTo).AsIterable();\n    }\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K, V)> FindRangePairs(K keyFrom, K keyTo)\n    {\n        if (isnull(keyFrom)) throw new ArgumentNullException(nameof(keyFrom));\n        if (isnull(keyTo)) throw new ArgumentNullException(nameof(keyTo));\n        return OrdK.Compare(keyFrom, keyTo) > 0\n                   ? MapModule.FindRangePairs<OrdK, K, V>(Root, keyTo, keyFrom).AsIterable()\n                   : MapModule.FindRangePairs<OrdK, K, V>(Root, keyFrom, keyTo).AsIterable();\n    }\n\n    /// <summary>\n    /// Skips 'amount' values and returns a new tree without the \n    /// skipped values.\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>New tree</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K Key, V Value)> Skip(int amount)\n    {\n        return Iterable.createRange(Go());\n\n        IEnumerable<(K, V)> Go()\n        {\n            using var enumer = new MapEnumerator<K, V>(Root, Rev, amount);\n            while (enumer.MoveNext())\n            {\n                yield return enumer.Current;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ContainsKey(K key) =>\n        !isnull(key) && (Find(key) ? true : false);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(K key, V value) =>\n        match(Find(key),\n              Some: v => ReferenceEquals(v, value),\n              None: () => false\n        );\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Atomically adds a range of items to the map\n    /// </summary>\n    /// <param name=\"pairs\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> AddRange(IEnumerable<KeyValuePair<K, V>> pairs) =>\n        AddRange(pairs.AsIterable().Map(kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> SetItems(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(items, MapModuleM.AddOpt.ThrowOnDuplicate);\n        }\n\n        var self = Root;\n        foreach (var item in items)\n        {\n            if (isnull(item.Key)) continue;\n            self = MapModule.SetItem<OrdK, K, V>(self, item.Key, item.Value);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> SetItems(IEnumerable<Tuple<K, V>> items)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(items, MapModuleM.AddOpt.ThrowOnDuplicate);\n        }\n\n        var self = Root;\n        foreach (var item in items)\n        {\n            if (isnull(item.Item1)) continue;\n            self = MapModule.SetItem<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> SetItems(IEnumerable<(K, V)> items)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(items, MapModuleM.AddOpt.ThrowOnDuplicate);\n        }\n\n        var self = Root;\n        foreach (var item in items)\n        {\n            if (isnull(item.Item1)) continue;\n            self = MapModule.SetItem<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> TrySetItems(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(items, MapModuleM.AddOpt.TryAdd);\n        }\n\n        var self = Root;\n        foreach (var item in items)\n        {\n            if (isnull(item.Key)) continue;\n            self = MapModule.TrySetItem<OrdK, K, V>(self, item.Key, item.Value);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> TrySetItems(IEnumerable<Tuple<K, V>> items)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(items, MapModuleM.AddOpt.TryAdd);\n        }\n\n        var self = Root;\n        foreach (var item in items)\n        {\n            if (isnull(item.Item1)) continue;\n            self = MapModule.TrySetItem<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public MapInternal<OrdK, K, V> TrySetItems(IEnumerable<(K, V)> items)\n    {\n        if (Count == 0)\n        {\n            return new MapInternal<OrdK, K, V>(items, MapModuleM.AddOpt.TryAdd);\n        }\n\n        var self = Root;\n        foreach (var item in items)\n        {\n            if (isnull(item.Item1)) continue;\n            self = MapModule.TrySetItem<OrdK, K, V>(self, item.Item1, item.Item2);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> TrySetItems(IEnumerable<K> keys, Func<V, V> Some)\n    {\n        var self = this;\n        foreach (var key in keys)\n        {\n            if (isnull(key)) continue;\n            self = TrySetItem(key, Some);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New map with the items removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> RemoveRange(IEnumerable<K> keys)\n    {\n        var self = Root;\n        foreach (var key in keys)\n        {\n            self = MapModule.Remove<OrdK, K, V>(self, key);\n        }\n        return SetRoot(self);\n    }\n\n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(KeyValuePair<K, V> pair) =>\n        match(MapModule.TryFind<OrdK, K, V>(Root, pair.Key),\n              Some: v => ReferenceEquals(v, pair.Value),\n              None: () => false);\n\n    /// <summary>\n    /// TryGetValue\n    /// </summary>\n    /// <param name=\"key\"></param>\n    /// <param name=\"value\"></param>\n    /// <returns></returns>\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    [Obsolete(\"TryGetValue is obsolete, use TryFind instead\")]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool TryGetValue(K key, out V value)\n    {\n        var res = match(Find(key), Some: x => (x, true), None: () => (default(V)!, false));\n        value = res.Item1;\n        return res.Item2;\n    }\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    public MapInternal<OrdK, K, U> Choose<U>(Func<K, V, Option<U>> selector)\n    {\n        IEnumerable<(K, U)> Yield()\n        {\n            foreach (var item in this)\n            {\n                var opt = selector(item.Key, item.Value);\n                if (opt.IsNone) continue;\n                yield return (item.Key, (U)opt);\n            }\n        }\n        return new MapInternal<OrdK, K, U>(Yield(), MapModuleM.AddOpt.TryAdd);\n    }\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    public MapInternal<OrdK, K, U> Choose<U>(Func<V, Option<U>> selector)\n    {\n        IEnumerable<(K, U)> Yield()\n        {\n            foreach (var item in this)\n            {\n                var opt = selector(item.Value);\n                if (opt.IsNone) continue;\n                yield return (item.Key, (U)opt);\n            }\n        }\n        return new MapInternal<OrdK, K, U>(Yield(), MapModuleM.AddOpt.TryAdd);\n    }\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            return Iterable.createRange(Go());\n            IEnumerable<K> Go()\n            {\n                using var iter = new MapKeyEnumerator<K, V>(Root, Rev, 0);\n                while (iter.MoveNext())\n                {\n                    yield return iter.Current;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            return Iterable.createRange(Go());\n            IEnumerable<V> Go()\n            {\n                using var iter = new MapValueEnumerator<K, V>(Root, Rev, 0);\n                while (iter.MoveNext())\n                {\n                    yield return iter.Current;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Map to a dictionary\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(Func<(K Key, V Value), KR> keySelector, Func<(K Key, V Value), VR> valueSelector) where KR : notnull =>\n        AsIterable().ToDictionary(keySelector, valueSelector);\n\n    /// <summary>\n    /// Enumerable of in-order tuples that make up the map\n    /// </summary>\n    /// <returns>Tuples</returns>\n    [Pure]\n    public Iterable<(K Key, V Value)> Pairs\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => AsIterable().Map(kv => (kv.Key, kv.Value));\n    }\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapEnumerator<K, V> GetEnumerator() =>\n        new(Root, Rev, 0);\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<(K Key, V Value)> IEnumerable<(K Key, V Value)>.GetEnumerator() =>\n        new MapEnumerator<K, V>(Root, Rev, 0);\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        new MapEnumerator<K, V>(Root, Rev, 0);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        toSeq(AsIterable());\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K Key, V Value)> AsIterable()\n    {\n        return Iterable.createRange(Go());\n        IEnumerable<(K, V)> Go()\n        {\n            using var iter = new MapEnumerator<K, V>(Root, Rev, 0);\n            while (iter.MoveNext())\n            {\n                yield return iter.Current;\n            }\n        }\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerable<(K Key, V Value)> AsEnumerable()\n    {\n        using var iter = new MapEnumerator<K, V>(Root, Rev, 0);\n        while (iter.MoveNext())\n        {\n            yield return iter.Current;\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static KeyValuePair<K, V> ToKeyValuePair((K Key, V Value) kv) => \n        new(kv.Key, kv.Value);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal MapInternal<OrdK, K, V> SetRoot(MapItem<K, V> root) =>\n        new(root, Rev);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapInternal<OrdK, K, V> operator +(MapInternal<OrdK, K, V> lhs, MapInternal<OrdK, K, V> rhs) =>\n        lhs.Append(rhs);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public MapInternal<OrdK, K, R> Union<V2, R>(MapInternal<OrdK, K, V2> other, WhenMissing<K, V, R> MapLeft, WhenMissing<K, V2, R> MapRight, WhenMatched<K, V, V2, R> Merge)\n    {\n        if (MapLeft  == null) throw new ArgumentNullException(nameof(MapLeft));\n        if (MapRight == null) throw new ArgumentNullException(nameof(MapRight));\n        if (Merge    == null) throw new ArgumentNullException(nameof(Merge));\n\n        var root = MapItem<K, R>.Empty;\n\n        foreach (var right in other)\n        {\n            var key  = right.Key;\n            var left = Find(key);\n            if (left.IsSome)\n            {\n                root = MapModuleM.Add<OrdK, K, R>(\n                    root,\n                    key,\n                    Merge(key, left.Value!, right.Value),\n                    MapModuleM.AddOpt.TryAdd);\n            }\n            else\n            {\n                root = MapModuleM.Add<OrdK, K, R>(\n                    root,\n                    key,\n                    MapRight(key, right.Value),\n                    MapModuleM.AddOpt.TryAdd);\n            }\n        }\n        foreach (var left in this)\n        {\n            var key   = left.Key;\n            var right = other.Find(key);\n            if (right.IsNone)\n            {\n                root = MapModuleM.Add<OrdK, K, R>(\n                    root,\n                    key,\n                    MapLeft(key, left.Value),\n                    MapModuleM.AddOpt.TryAdd);\n            }\n        }\n        return new MapInternal<OrdK, K, R>(root, Rev);\n    }\n\n    /// <summary>\n    /// Intersect two maps.  Only keys that are in both maps are\n    /// returned.  The merge function is called for every resulting\n    /// key.\n    /// </summary>\n    [Pure]\n    public MapInternal<OrdK, K, R> Intersect<V2, R>(MapInternal<OrdK, K, V2> other, WhenMatched<K, V, V2, R> Merge)\n    {\n        if (Merge == null) throw new ArgumentNullException(nameof(Merge));\n\n        var root = MapItem<K, R>.Empty;\n\n        foreach (var right in other)\n        {\n            var left = Find(right.Key);\n            if (left.IsSome)\n            {\n                root = MapModuleM.Add<OrdK, K, R>(\n                    root,\n                    right.Key,\n                    Merge(right.Key, left.Value!, right.Value),\n                    MapModuleM.AddOpt.TryAdd);\n            }\n        }\n        return new MapInternal<OrdK, K, R>(root, Rev);\n    }\n\n    /// <summary>\n    /// Map differencing based on key.  this - other.\n    /// </summary>\n    [Pure]\n    public MapInternal<OrdK, K, V> Except(MapInternal<OrdK, K, V> other)\n    {\n        var root = MapItem<K, V>.Empty;\n        foreach(var item in this)\n        {\n            if (!other.ContainsKey(item.Key))\n            {\n                root = MapModuleM.Add<OrdK, K, V>(\n                    root,\n                    item.Key,\n                    item.Value,\n                    MapModuleM.AddOpt.ThrowOnDuplicate);\n            }\n        }\n        return new MapInternal<OrdK, K, V>(root, Rev);\n    }\n\n    /// <summary>\n    /// Keys that are in both maps are dropped and the remaining\n    /// items are merged and returned.\n    /// </summary>\n    [Pure]\n    public MapInternal<OrdK, K, V> SymmetricExcept(MapInternal<OrdK, K, V> other)\n    {\n        var root = MapItem<K, V>.Empty;\n\n        foreach (var left in this)\n        {\n            if (!other.ContainsKey(left.Key))\n            {\n                root = MapModuleM.Add<OrdK, K, V>(\n                    root,\n                    left.Key,\n                    left.Value,\n                    MapModuleM.AddOpt.ThrowOnDuplicate);\n            }\n        }\n        foreach (var right in other)\n        {\n            if (!ContainsKey(right.Key))\n            {\n                //map = map.Add(right.Key, right.Value);\n                root = MapModuleM.Add<OrdK, K, V>(\n                    root,\n                    right.Key,\n                    right.Value,\n                    MapModuleM.AddOpt.ThrowOnDuplicate);\n            }\n        }\n        return new MapInternal<OrdK, K, V>(root, Rev);\n    }\n\n    [Pure]\n    public MapInternal<OrdK, K, V> Append(MapInternal<OrdK, K, V> rhs)\n    {\n        if (Count == 0)\n        {\n            return rhs;\n        }\n        if (rhs.Count == 0)\n        {\n            return this;\n        }\n\n        var self = this;\n        foreach (var item in rhs)\n        {\n            if (!self.ContainsKey(item.Key))\n            {\n                self = self.Add(item.Key, item.Value);\n            }\n        }\n        return self;\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapInternal<OrdK, K, V> operator -(MapInternal<OrdK, K, V> lhs, MapInternal<OrdK, K, V> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    public MapInternal<OrdK, K, V> Subtract(MapInternal<OrdK, K, V> rhs)\n    {\n        if(Count == 0)\n        {\n            return Empty;\n        }\n\n        if (rhs.Count == 0)\n        {\n            return this;\n        }\n\n        if (rhs.Count < Count)\n        {\n            var self = this;\n            foreach (var item in rhs)\n            {\n                self = self.Remove(item.Key);\n            }\n            return self;\n        }\n        else\n        {\n            var root = MapItem<K, V>.Empty;\n            foreach (var item in this)\n            {\n                if (!rhs.Contains(item))\n                {\n                    root = MapModuleM.Add<OrdK, K, V>(root, item.Key, item.Value, MapModuleM.AddOpt.TryAdd);\n                }\n            }\n            return new MapInternal<OrdK, K, V>(root, Rev);\n        }\n    }\n\n    [Pure]\n    public bool Equals<EqV>(MapInternal<OrdK, K, V> rhs) where EqV : Eq<V>\n    {\n        if (ReferenceEquals(this, rhs)) return true;\n        if (Count != rhs.Count) return false;\n        if (hashCode != 0 && rhs.hashCode != 0 && hashCode != rhs.hashCode) return false;\n\n        using var iterA = GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        var       count = Count;\n\n        for (int i = 0; i < count; i++)\n        {\n            iterA.MoveNext();\n            iterB.MoveNext();\n            if (!OrdK.Equals(iterA.Current.Key, iterB.Current.Key)) return false;\n            if (!EqV.Equals(iterA.Current.Value, iterB.Current.Value)) return false;\n        }\n        return true;\n    }\n\n    [Pure]\n    public int CompareTo<OrdV>(MapInternal<OrdK, K, V> other) where OrdV : Ord<V>\n    {\n        var cmp = Count.CompareTo(other.Count);\n        if (cmp != 0) return cmp;\n        using var iterA = GetEnumerator();\n        using var iterB = other.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            cmp = OrdK.Compare(iterA.Current.Key, iterB.Current.Key);\n            if (cmp != 0) return cmp;\n            cmp = OrdV.Compare(iterA.Current.Value, iterB.Current.Value);\n            if (cmp != 0) return cmp;\n        }\n        return 0;\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> Filter(Func<K, V, bool> f) =>\n        new(AsIterable().Filter(mi => f(mi.Key, mi.Value)), \n            MapModuleM.AddOpt.ThrowOnDuplicate);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapInternal<OrdK, K, V> Filter(Func<V, bool> f) =>\n        new(AsIterable().Filter(mi => f(mi.Value)),\n            MapModuleM.AddOpt.ThrowOnDuplicate);\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    public Fold<(K, V), S> FoldStep<S>(S initialState)\n    {\n        if(IsEmpty) return Fold.Done<(K, V), S>(initialState);\n        var nstack = new MapItem<K, V>[32];\n        var fstack = new int[32];\n        var top    = 1;\n        nstack[0] = Root;\n        fstack[0] = 0;\n\n        return node(initialState);\n\n        Fold<(K, V), S> node(S state)\n        {\n            while (true)\n            {\n                if (top == 0) return Fold.Done<(K, V), S>(state);\n\n                var t = top - 1;\n                var n = nstack[t];\n                var f = fstack[t];\n\n                if (n.IsEmpty)\n                {\n                    top--;\n                    continue;\n                }\n\n                fstack[t]++;\n                switch (f)\n                {\n                    case 0:\n                        nstack[top] = n.Left;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    case 1:\n                        return Fold.Loop(state, n.KeyValue, node);\n\n                    case 2:\n                        nstack[top] = n.Right;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    default:\n                        top--;\n                        continue;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Left/Node/Right traversal (in reverse order) in stepped form\n    /// </summary>\n    public Fold<(K, V), S> FoldStepBack<S>(S initialState)\n    {\n        if(IsEmpty) return Fold.Done<(K, V), S>(initialState);\n        var nstack = new MapItem<K, V>[32];\n        var fstack = new int[32];\n        var top    = 1;\n        nstack[0] = Root;\n        fstack[0] = 0;\n\n        return node(initialState);\n\n        Fold<(K, V), S> node(S state)\n        {\n            while (true)\n            {\n                if (top == 0) return Fold.Done<(K, V), S>(state);\n\n                var t = top - 1;\n                var n = nstack[t];\n                var f = fstack[t];\n\n                if (n.IsEmpty)\n                {\n                    top--;\n                    continue;\n                }\n\n                fstack[t]++;\n                switch (f)\n                {\n                    case 0:\n                        nstack[top] = n.Right;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    case 1:\n                        return Fold.Loop(state, n.KeyValue, node);\n\n                    case 2:\n                        nstack[top] = n.Left;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    default:\n                        top--;\n                        continue;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    public Fold<K, S> FoldStepKeys<S>(S initialState)\n    {\n        if(IsEmpty) return Fold.Done<K, S>(initialState);\n        var nstack = new MapItem<K, V>[32];\n        var fstack = new int[32];\n        var top   = 1;\n        nstack[0] = Root;\n        fstack[0] = 0;\n\n        return node(initialState);\n\n        Fold<K, S> node(S state)\n        {\n            while (true)\n            {\n                if (top == 0) return Fold.Done<K, S>(state);\n\n                var t = top - 1;\n                var n = nstack[t];\n                var f = fstack[t];\n\n                if (n.IsEmpty)\n                {\n                    top--;\n                    continue;\n                }\n\n                fstack[t]++;\n                switch (f)\n                {\n                    case 0:\n                        nstack[top] = n.Left;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    case 1:\n                        return Fold.Loop(state, n.KeyValue.Key, node);\n\n                    case 2:\n                        nstack[top] = n.Right;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    default:\n                        top--;\n                        continue;\n                }\n            }\n        }\n    }    \n\n    /// <summary>\n    /// Left/Node/Right traversal (in reverse order) in stepped form\n    /// </summary>\n    public Fold<K, S> FoldStepBackKeys<S>(S initialState)\n    {\n        if(IsEmpty) return Fold.Done<K, S>(initialState);\n        var nstack = new MapItem<K, V>[32];\n        var fstack = new int[32];\n        var top    = 1;\n        nstack[0] = Root;\n        fstack[0] = 0;\n\n        return node(initialState);\n\n        Fold<K, S> node(S state)\n        {\n            while (true)\n            {\n                if (top == 0) return Fold.Done<K, S>(state);\n\n                var t = top - 1;\n                var n = nstack[t];\n                var f = fstack[t];\n\n                if (n.IsEmpty)\n                {\n                    top--;\n                    continue;\n                }\n\n                fstack[t]++;\n                switch (f)\n                {\n                    case 0:\n                        nstack[top] = n.Right;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    case 1:\n                        return Fold.Loop(state, n.KeyValue.Key, node);\n\n                    case 2:\n                        nstack[top] = n.Left;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    default:\n                        top--;\n                        continue;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    public Fold<V, S> FoldStepValues<S>(S initialState)\n    {\n        if(IsEmpty) return Fold.Done<V, S>(initialState);\n        var nstack = new MapItem<K, V>[32];\n        var fstack = new byte[32];\n        var top    = 1;\n        nstack[0] = Root;\n        fstack[0] = 0;\n\n        return node(initialState);\n\n        Fold<V, S> node(S state)\n        {\n            while (true)\n            {\n                if (top == 0) return Fold.Done<V, S>(state);\n\n                var t = top - 1;\n                var n = nstack[t];\n                var f = fstack[t];\n\n                if (n.IsEmpty)\n                {\n                    top--;\n                    continue;\n                }\n\n                fstack[t]++;\n                switch (f)\n                {\n                    case 0:\n                        nstack[top] = n.Left;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    case 1:\n                        return Fold.Loop(state, n.KeyValue.Value, node);\n\n                    case 2:\n                        nstack[top] = n.Right;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    default:\n                        top--;\n                        continue;\n                }\n            }\n        }\n    }    \n    \n    /// <summary>\n    /// Left/Node/Right traversal (in reverse order) in stepped form\n    /// </summary>\n    public Fold<V, S> FoldStepBackValues<S>(S initialState)\n    {\n        if(IsEmpty) return Fold.Done<V, S>(initialState);\n        var nstack = new MapItem<K, V>[32];\n        var fstack = new byte[32];\n        var top    = 1;\n        nstack[0] = Root;\n        fstack[0] = 0;\n\n        return node(initialState);\n\n        Fold<V, S> node(S state)\n        {\n            while (true)\n            {\n                if (top == 0) return Fold.Done<V, S>(state);\n\n                var t = top - 1;\n                var n = nstack[t];\n                var f = fstack[t];\n\n                if (n.IsEmpty)\n                {\n                    top--;\n                    continue;\n                }\n\n                fstack[t]++;\n                switch (f)\n                {\n                    case 0:\n                        nstack[top] = n.Right;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    case 1:\n                        return Fold.Loop(state, n.KeyValue.Value, node);\n\n                    case 2:\n                        nstack[top] = n.Left;\n                        fstack[top] = 0;\n                        top++;\n                        continue;\n\n                    default:\n                        top--;\n                        continue;\n                }\n            }\n        }\n    }\n}\n\ninternal interface IMapItem<K, V>\n{\n    (K Key, V Value) KeyValue\n    {\n        get;\n    }\n}\n\n[Serializable]\nclass MapItem<K, V> :\n    ISerializable,\n    IMapItem<K, V>\n{\n    internal static readonly MapItem<K, V> Empty = new (0, 0, (default!, default!), default!, default!);\n\n    internal bool IsEmpty => Count == 0;\n    internal int Count;\n    internal byte Height;\n    internal MapItem<K, V> Left;\n    internal MapItem<K, V> Right;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    internal MapItem(byte height, int count, (K Key, V Value) keyValue, MapItem<K, V> left, MapItem<K, V> right)\n    {\n        Count = count;\n        Height = height;\n        KeyValue = keyValue;\n        Left = left;\n        Right = right;\n    }\n\n    /// <summary>\n    /// Deserialisation constructor\n    /// </summary>\n    MapItem(SerializationInfo info, StreamingContext context)\n    {\n        var key   = (K?)info.GetValue(\"Key\", typeof(K))   ?? throw new SerializationException();\n        var value = (V?)info.GetValue(\"Value\", typeof(V)) ?? throw new SerializationException();\n        KeyValue = (key, value);\n        Count = 1;\n        Height = 1;\n        Left = Empty;\n        Right = Empty;\n    }\n\n    /// <summary>\n    /// Serialisation support\n    /// </summary>\n    public void GetObjectData(SerializationInfo info, StreamingContext context)\n    {\n        info.AddValue(\"Key\", KeyValue.Key, typeof(K));\n        info.AddValue(\"Value\", KeyValue.Value, typeof(V));\n    }\n\n    internal int BalanceFactor\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Count == 0\n                   ? 0\n                   : Right.Height - Left.Height;\n    }\n\n    public (K Key, V Value) KeyValue\n    {\n        get;\n        internal set;\n    }\n}\n\ninternal static class MapModuleM\n{\n    public enum AddOpt\n    {\n        ThrowOnDuplicate,\n        TryAdd,\n        TryUpdate\n    }\n\n    public static MapItem<K, V> Add<OrdK, K, V>(MapItem<K, V> node, K key, V value, AddOpt option)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return new MapItem<K, V>(1, 1, (key, value), MapItem<K, V>.Empty, MapItem<K, V>.Empty);\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            node.Left = Add<OrdK, K, V>(node.Left, key, value, option);\n            return Balance(node);\n        }\n        else if (cmp > 0)\n        {\n            node.Right = Add<OrdK, K, V>(node.Right, key, value, option);\n            return Balance(node);\n        }\n        else if(option == AddOpt.TryAdd)\n        {\n            // Already exists, but we don't care\n            return node;\n        }\n        else if (option == AddOpt.TryUpdate)\n        {\n            // Already exists, and we want to update the content\n            node.KeyValue = (key, value);\n            return node;\n        }\n        else\n        {\n            throw new ArgumentException(\"An element with the same key already exists in the Map\");\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> Balance<K, V>(MapItem<K, V> node)\n    {\n        node.Height = (byte)(1 + Math.Max(node.Left.Height, node.Right.Height));\n        node.Count = 1 + node.Left.Count + node.Right.Count;\n\n        return node.BalanceFactor >= 2\n                   ? node.Right.BalanceFactor < 0\n                         ? DblRotLeft(node)\n                         : RotLeft(node)\n                   : node.BalanceFactor <= -2\n                       ? node.Left.BalanceFactor > 0\n                             ? DblRotRight(node)\n                             : RotRight(node)\n                       : node;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> DblRotRight<K, V>(MapItem<K, V> node)\n    {\n        node.Left = RotLeft(node.Left);\n        return RotRight(node);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> DblRotLeft<K, V>(MapItem<K, V> node)\n    {\n        node.Right = RotRight(node.Right);\n        return RotLeft(node);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> RotRight<K, V>(MapItem<K, V> node)\n    {\n        if (node.IsEmpty || node.Left.IsEmpty) return node;\n\n        var y  = node;\n        var x  = y.Left;\n        var t2 = x.Right;\n        x.Right = y;\n        y.Left = t2;\n        y.Height = (byte)(1 + Math.Max(y.Left.Height, y.Right.Height));\n        x.Height = (byte)(1 + Math.Max(x.Left.Height, x.Right.Height));\n        y.Count = 1 + y.Left.Count + y.Right.Count;\n        x.Count = 1 + x.Left.Count + x.Right.Count;\n\n        return x;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> RotLeft<K, V>(MapItem<K, V> node)\n    {\n        if (node.IsEmpty || node.Right.IsEmpty) return node;\n\n        var x  = node;\n        var y  = x.Right;\n        var t2 = y.Left;\n        y.Left = x;\n        x.Right = t2;\n        x.Height = (byte)(1 + Math.Max(x.Left.Height, x.Right.Height));\n        y.Height = (byte)(1 + Math.Max(y.Left.Height, y.Right.Height));\n        x.Count = 1 + x.Left.Count + x.Right.Count;\n        y.Count = 1 + y.Left.Count + y.Right.Count;\n\n        return y;\n    }\n}\n\nstatic class MapModule\n{\n    public static S Fold<S, K, V>(MapItem<K, V> node, S state, Func<S, K, V, S> folder)\n    {\n        if (node.IsEmpty)\n        {\n            return state;\n        }\n\n        state = Fold(node.Left, state, folder);\n        state = folder(state, node.KeyValue.Key, node.KeyValue.Value);\n        state = Fold(node.Right, state, folder);\n        return state;\n    }\n\n    public static S Fold<S, K, V>(MapItem<K, V> node, S state, Func<S, V, S> folder)\n    {\n        if (node.IsEmpty)\n        {\n            return state;\n        }\n\n        state = Fold(node.Left, state, folder);\n        state = folder(state, node.KeyValue.Value);\n        state = Fold(node.Right, state, folder);\n        return state;\n    }\n\n    public static bool ForAll<K, V>(MapItem<K, V> node, Func<K, V, bool> pred) =>\n        node.IsEmpty || pred(node.KeyValue.Key, node.KeyValue.Value) && ForAll(node.Left, pred) && ForAll(node.Right, pred);\n\n    public static bool Exists<K, V>(MapItem<K, V> node, Func<K, V, bool> pred) =>\n        !node.IsEmpty && (pred(node.KeyValue.Key, node.KeyValue.Value) || Exists(node.Left, pred) || Exists(node.Right, pred));\n\n    public static MapItem<K, V> Add<OrdK, K, V>(MapItem<K, V> node, K key, V value)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return new MapItem<K, V>(1, 1, (key, value), MapItem<K, V>.Empty, MapItem<K, V>.Empty);\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.KeyValue, Add<OrdK, K, V>(node.Left, key, value), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.KeyValue, node.Left, Add<OrdK, K, V>(node.Right, key, value)));\n        }\n        else\n        {\n            throw new ArgumentException(\"An element with the same key already exists in the Map\");\n        }\n    }\n\n    public static MapItem<K, V> SetItem<OrdK, K, V>(MapItem<K, V> node, K key, V value)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            throw new ArgumentException(\"Key not found in Map\");\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.KeyValue, SetItem<OrdK, K, V>(node.Left, key, value), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.KeyValue, node.Left, SetItem<OrdK, K, V>(node.Right, key, value)));\n        }\n        else\n        {\n            return new MapItem<K, V>(node.Height, node.Count, (key, value), node.Left, node.Right);\n        }\n    }\n\n    public static MapItem<K, V> TrySetItem<OrdK, K, V>(MapItem<K, V> node, K key, V value)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return node;\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.KeyValue, TrySetItem<OrdK, K, V>(node.Left, key, value), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.KeyValue, node.Left, TrySetItem<OrdK, K, V>(node.Right, key, value)));\n        }\n        else\n        {\n            return new MapItem<K, V>(node.Height, node.Count, (key, value), node.Left, node.Right);\n        }\n    }\n\n    public static MapItem<K, V> TryAdd<OrdK, K, V>(MapItem<K, V> node, K key, V value)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return new MapItem<K, V>(1, 1, (key, value), MapItem<K, V>.Empty, MapItem<K, V>.Empty);\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.KeyValue, TryAdd<OrdK, K, V>(node.Left, key, value), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.KeyValue, node.Left, TryAdd<OrdK, K, V>(node.Right, key, value)));\n        }\n        else\n        {\n            return node;\n        }\n    }\n\n    public static MapItem<K, V> AddOrUpdate<OrdK, K, V>(MapItem<K, V> node, K key, V value)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return new MapItem<K, V>(1, 1, (key, value), MapItem<K, V>.Empty, MapItem<K, V>.Empty);\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.KeyValue, AddOrUpdate<OrdK, K, V>(node.Left, key, value), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.KeyValue, node.Left, AddOrUpdate<OrdK, K, V>(node.Right, key, value)));\n        }\n        else\n        {\n            return new MapItem<K, V>(node.Height, node.Count, (node.KeyValue.Key, value), node.Left, node.Right);\n        }\n    }\n\n    public static MapItem<K, V> Remove<OrdK, K, V>(MapItem<K, V> node, K key)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return node;\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.KeyValue, Remove<OrdK, K, V>(node.Left, key), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.KeyValue, node.Left, Remove<OrdK, K, V>(node.Right, key)));\n        }\n        else\n        {\n            // If this is a leaf, just remove it \n            // by returning Empty.  If we have only one child,\n            // replace the node with the child.\n            if (node.Right.IsEmpty && node.Left.IsEmpty)\n            {\n                return MapItem<K, V>.Empty;\n            }\n            else if (node.Right.IsEmpty && !node.Left.IsEmpty)\n            {\n                return node.Left;\n            }\n            else if (!node.Right.IsEmpty && node.Left.IsEmpty)\n            {\n                return node.Right;\n            }\n            else\n            {\n                // We have two children. Remove the next-highest node and replace\n                // this node with it.\n                var successor = node.Right;\n                while (!successor.Left.IsEmpty)\n                {\n                    successor = successor.Left;\n                }\n\n                var newRight = Remove<OrdK, K, V>(node.Right, successor.KeyValue.Key);\n                return Balance(Make(successor.KeyValue, node.Left, newRight));\n            }\n        }\n    }\n\n    public static V Find<OrdK, K, V>(MapItem<K, V> node, K key)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            throw new ArgumentException(\"Key not found in Map\");\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            return Find<OrdK, K, V>(node.Left, key);\n        }\n        else if (cmp > 0)\n        {\n            return Find<OrdK, K, V>(node.Right, key);\n        }\n        else\n        {\n            return node.KeyValue.Value;\n        }\n    }\n\n    /// <summary>\n    /// TODO: I suspect this is suboptimal, it would be better with a custom Enumerator \n    /// that maintains a stack of nodes to retrace.\n    /// </summary>\n    public static IEnumerable<V> FindRange<OrdK, K, V>(MapItem<K, V> node, K a, K b)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            yield break;\n        }\n        if (OrdK.Compare(node.KeyValue.Key, a) < 0)\n        {\n            foreach (var item in FindRange<OrdK, K, V>(node.Right, a, b))\n            {\n                yield return item;\n            }\n        }\n        else if (OrdK.Compare(node.KeyValue.Key, b) > 0)\n        {\n            foreach (var item in FindRange<OrdK, K, V>(node.Left, a, b))\n            {\n                yield return item;\n            }\n        }\n        else\n        {\n            foreach (var item in FindRange<OrdK, K, V>(node.Left, a, b))\n            {\n                yield return item;\n            }\n            yield return node.KeyValue.Value;\n            foreach (var item in FindRange<OrdK, K, V>(node.Right, a, b))\n            {\n                yield return item;\n            }\n        }\n    }\n\n    /// <summary>\n    /// TODO: I suspect this is suboptimal, it would be better with a custom Enumerator \n    /// that maintains a stack of nodes to retrace.\n    /// </summary>\n    public static IEnumerable<(K, V)> FindRangePairs<OrdK, K, V>(MapItem<K, V> node, K a, K b)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            yield break;\n        }\n        if (OrdK.Compare(node.KeyValue.Key, a) < 0)\n        {\n            foreach (var item in FindRangePairs<OrdK, K, V>(node.Right, a, b))\n            {\n                yield return item;\n            }\n        }\n        else if (OrdK.Compare(node.KeyValue.Key, b) > 0)\n        {\n            foreach (var item in FindRangePairs<OrdK, K, V>(node.Left, a, b))\n            {\n                yield return item;\n            }\n        }\n        else\n        {\n            foreach (var item in FindRangePairs<OrdK, K, V>(node.Left, a, b))\n            {\n                yield return item;\n            }\n            yield return node.KeyValue;\n            foreach (var item in FindRangePairs<OrdK, K, V>(node.Right, a, b))\n            {\n                yield return item;\n            }\n        }\n    }\n\n    public static Option<V> TryFind<OrdK, K, V>(MapItem<K, V> node, K key)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return None;\n        }\n        var cmp = OrdK.Compare(key, node.KeyValue.Key);\n        if (cmp < 0)\n        {\n            return TryFind<OrdK, K, V>(node.Left, key);\n        }\n        else if (cmp > 0)\n        {\n            return TryFind<OrdK, K, V>(node.Right, key);\n        }\n        else\n        {\n            return Some(node.KeyValue.Value);\n        }\n    }\n\n    public static MapItem<K, V> Skip<K, V>(MapItem<K, V> node, int amount)\n    {\n        if (amount == 0 || node.IsEmpty)\n        {\n            return node;\n        }\n        if (amount > node.Count)\n        {\n            return MapItem<K, V>.Empty;\n        }\n        if (!node.Left.IsEmpty && node.Left.Count == amount)\n        {\n            return Balance(Make(node.KeyValue, MapItem<K, V>.Empty, node.Right));\n        }\n        if (!node.Left.IsEmpty && node.Left.Count == amount - 1)\n        {\n            return node.Right;\n        }\n        if (node.Left.IsEmpty)\n        {\n            return Skip(node.Right, amount - 1);\n        }\n\n        var newleft   = Skip(node.Left, amount);\n        var remaining = amount - node.Left.Count - newleft.Count;\n        if (remaining > 0)\n        {\n            return Skip(Balance(Make(node.KeyValue, newleft, node.Right)), remaining);\n        }\n        else\n        {\n            return Balance(Make(node.KeyValue, newleft, node.Right));\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> Make<K, V>((K,V) kv, MapItem<K, V> l, MapItem<K, V> r) =>\n        new ((byte)(1 + Math.Max(l.Height, r.Height)), l.Count + r.Count + 1, kv, l, r);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> Make<K, V>(K k, V v, MapItem<K, V> l, MapItem<K, V> r) =>\n        new ((byte)(1 + Math.Max(l.Height, r.Height)), l.Count + r.Count + 1, (k, v), l, r);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> Balance<K, V>(MapItem<K, V> node) =>\n        node.BalanceFactor >= 2\n            ? node.Right.BalanceFactor < 0\n                  ? DblRotLeft(node)\n                  : RotLeft(node)\n            : node.BalanceFactor <= -2\n                ? node.Left.BalanceFactor > 0\n                      ? DblRotRight(node)\n                      : RotRight(node)\n                : node;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> RotRight<K, V>(MapItem<K, V> node) =>\n        node.IsEmpty || node.Left.IsEmpty\n            ? node\n            : Make(node.Left.KeyValue, node.Left.Left, Make(node.KeyValue, node.Left.Right, node.Right));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> RotLeft<K, V>(MapItem<K, V> node) =>\n        node.IsEmpty || node.Right.IsEmpty\n            ? node\n            : Make(node.Right.KeyValue, Make(node.KeyValue, node.Left, node.Right.Left), node.Right.Right);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> DblRotRight<K, V>(MapItem<K, V> node) =>\n        node.IsEmpty || node.Left.IsEmpty\n            ? node\n            : RotRight(Make(node.KeyValue, RotLeft(node.Left), node.Right));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static MapItem<K, V> DblRotLeft<K, V>(MapItem<K, V> node) =>\n        node.IsEmpty || node.Right.IsEmpty\n            ? node\n            : RotLeft(Make(node.KeyValue, node.Left, RotRight(node.Right)));\n\n    internal static Option<(K, V)> Max<K, V>(MapItem<K, V> node) =>\n        node.Right.IsEmpty\n            ? node.KeyValue\n            : Max(node.Right);\n\n    internal static Option<(K, V)> Min<K, V>(MapItem<K, V> node) =>\n        node.Left.IsEmpty\n            ? node.KeyValue\n            : Min(node.Left);\n\n    internal static Option<(K, V)> TryFindPredecessor<OrdK, K, V>(MapItem<K, V> root, K key) where OrdK : Ord<K>\n    {\n        Option<(K, V)> predecessor = None;\n        var            current     = root;\n\n        if (root.IsEmpty)\n        {\n            return None;\n        }\n\n        do\n        {\n            var cmp = OrdK.Compare(key, current.KeyValue.Key);\n            if (cmp < 0)\n            {\n                current = current.Left;\n            }\n            else if (cmp > 0)\n            {\n                predecessor = current.KeyValue;\n                current = current.Right;\n            }\n            else\n            {\n                break;\n            }\n        }\n        while (!current.IsEmpty);\n\n        if (!current.IsEmpty && !current.Left.IsEmpty)\n        {\n            predecessor = Max(current.Left);\n        }\n\n        return predecessor;\n    }\n\n    internal static Option<(K, V)> TryFindOrPredecessor<OrdK, K, V>(MapItem<K, V> root, K key) where OrdK : Ord<K>\n    {\n        Option<(K, V)> predecessor = None;\n        var            current     = root;\n\n        if (root.IsEmpty)\n        {\n            return None;\n        }\n\n        do\n        {\n            var cmp = OrdK.Compare(key, current.KeyValue.Key);\n            if (cmp < 0)\n            {\n                current = current.Left;\n            }\n            else if (cmp > 0)\n            {\n                predecessor = current.KeyValue;\n                current = current.Right;\n            }\n            else\n            {\n                return current.KeyValue;\n            }\n        }\n        while (!current.IsEmpty);\n\n        if (!current.IsEmpty && !current.Left.IsEmpty)\n        {\n            predecessor = Max(current.Left);\n        }\n\n        return predecessor;\n    }\n\n    internal static Option<(K, V)> TryFindSuccessor<OrdK, K, V>(MapItem<K, V> root, K key) where OrdK : Ord<K>\n    {\n        Option<(K, V)> successor = None;\n        var            current   = root;\n\n        if (root.IsEmpty)\n        {\n            return None;\n        }\n\n        do\n        {\n            var cmp = OrdK.Compare(key, current.KeyValue.Key);\n            if (cmp < 0)\n            {\n                successor = current.KeyValue;\n                current = current.Left;\n            }\n            else if (cmp > 0)\n            {\n                current = current.Right;\n            }\n            else\n            {\n                break;\n            }\n        }\n        while (!current.IsEmpty);\n\n        if (!current.IsEmpty && !current.Right.IsEmpty)\n        {\n            successor = Min(current.Right);\n        }\n\n        return successor;        }\n\n    internal static Option<(K, V)> TryFindOrSuccessor<OrdK, K, V>(MapItem<K, V> root, K key) where OrdK : Ord<K>\n    {\n        Option<(K, V)> successor = None;\n        var            current   = root;\n\n        if (root.IsEmpty)\n        {\n            return None;\n        }\n\n        do\n        {\n            var cmp = OrdK.Compare(key, current.KeyValue.Key);\n            if (cmp < 0)\n            {\n                successor = current.KeyValue;\n                current = current.Left;\n            }\n            else if (cmp > 0)\n            {\n                current = current.Right;\n            }\n            else\n            {\n                return current.KeyValue;\n            }\n        }\n        while (!current.IsEmpty);\n\n        if (!current.IsEmpty && !current.Right.IsEmpty)\n        {\n            successor = Min(current.Right);\n        }\n\n        return successor;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Module.Ord.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable map module\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// [en.wikipedia.org/wiki/AVL_tree](http://en.wikipedia.org/wiki/AVL_tree)\n/// </summary>\npublic static partial class Map\n{\n    /// <summary>\n    /// Creates a new empty Map\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> empty<OrdK, K, V>() where OrdK : Ord<K> =>\n        Map<OrdK, K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new empty Map\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> singleton<OrdK, K, V>((K, V) value) where OrdK : Ord<K> =>\n        [value];\n\n    /// <summary>\n    /// Creates a new empty Map\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> singleton<OrdK, K, V>(K key, V value) where OrdK : Ord<K> =>\n        [(key, value)];\n\n    /// <summary>\n    /// Creates a new empty Map\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> create<OrdK, K, V>() where OrdK : Ord<K> =>\n        Map<OrdK, K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> create<OrdK, K, V>(Tuple<K,V> head, params Tuple<K, V>[] tail) where OrdK : Ord<K> =>\n        empty<OrdK, K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> create<OrdK, K, V>((K, V) head, params (K, V)[] tail) where OrdK : Ord<K> =>\n        empty<OrdK, K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> createRange<OrdK, K, V>(IEnumerable<Tuple<K, V>> keyValues) where OrdK : Ord<K> =>\n        empty<OrdK, K, V>().AddRange(keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> createRange<OrdK, K, V>(IEnumerable<(K, V)> keyValues) where OrdK : Ord<K> =>\n        new(keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> createRange<OrdK, K, V>(ReadOnlySpan<(K, V)> keyValues) where OrdK : Ord<K> =>\n        keyValues.IsEmpty\n            ? Map<OrdK, K, V>.Empty\n            : new(keyValues);\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> add<OrdK, K, V>(Map<OrdK, K, V> map, K key, V value) where OrdK : Ord<K> =>\n        map.Add(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> tryAdd<OrdK, K, V>(Map<OrdK, K, V> map, K key, V value) where OrdK : Ord<K> =>\n        map.TryAdd(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists then the Fail handler is called with the unaltered map \n    /// and the value already set for the key, it expects a new map returned.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <param name=\"Fail\">Delegate to handle failure, you're given the unaltered map \n    /// and the value already set for the key</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> tryAdd<OrdK, K, V>(Map<OrdK, K, V> map, K key, V value, Func<Map<OrdK, K, V>, V, Map<OrdK, K, V>> Fail) where OrdK : Ord<K> =>\n        map.TryAdd(key, value, Fail);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> addOrUpdate<OrdK, K, V>(Map<OrdK, K, V> map, K key, V value) where OrdK : Ord<K> =>\n        map.AddOrUpdate(key, value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static Map<OrdK, K, V> addOrUpdate<OrdK, K, V>(Map<OrdK, K, V> map, K key, Func<V, V> Some, Func<V> None) where OrdK : Ord<K> =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static Map<OrdK, K, V> addOrUpdate<OrdK, K, V>(Map<OrdK, K, V> map, K key, Func<V, V> Some, V None) where OrdK : Ord<K> =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> addRange<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<Tuple<K, V>> keyValues) where OrdK : Ord<K> =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> addRange<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<(K, V)> keyValues) where OrdK : Ord<K> =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> tryAddRange<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<Tuple<K, V>> keyValues) where OrdK : Ord<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> tryAddRange<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<(K, V)> keyValues) where OrdK : Ord<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> tryAddRange<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) where OrdK : Ord<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> addOrUpdateRange<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<Tuple<K, V>> range) where OrdK : Ord<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> addOrUpdateRange<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<(K, V)> range) where OrdK : Ord<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> addOrUpdateRange<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<KeyValuePair<K, V>> range) where OrdK : Ord<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public static Map<OrdK, K, V> remove<OrdK, K, V>(Map<OrdK, K, V> map, K key) where OrdK : Ord<K> =>\n        map.Remove(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool containsKey<OrdK, K, V>(Map<OrdK, K, V> map, K key) where OrdK : Ord<K> =>\n        map.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<OrdK, K, V>(Map<OrdK, K, V> map, KeyValuePair<K, V> kv) where OrdK : Ord<K> =>\n        map.Contains(kv.Key, kv.Value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<OrdK, K, V>(Map<OrdK, K, V> map, Tuple<K, V> kv) where OrdK : Ord<K> =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<OrdK, K, V>(Map<OrdK, K, V> map, (K, V) kv) where OrdK : Ord<K> =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> setItem<OrdK, K, V>(Map<OrdK, K, V> map, K key, V value) where OrdK : Ord<K> =>\n        map.SetItem(key, value);\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<OrdK, K, V> trySetItem<OrdK, K, V>(Map<OrdK, K, V> map, K key, V value) where OrdK : Ord<K> =>\n        map.TrySetItem(key, value);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map (Some), and then putting \n    /// it back. Silently fails if the value doesn't exist.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> trySetItem<OrdK, K, V>(Map<OrdK, K, V> map, K key, Func<V, V> Some) where OrdK : Ord<K> =>\n        map.TrySetItem(key, Some);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Calls the None delegate to return a new map if the item can't be found\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <param name=\"None\">delegate to return a new map if the item can't be found</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> trySetItem<OrdK, K, V>(Map<OrdK, K, V> map, K key, Func<V, V> Some, Func<Map<K, V>, Map<K, V>> None) where OrdK : Ord<K> =>\n        map.TrySetItem(key, Some, None);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> setItems<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<Tuple<K, V>> items) where OrdK : Ord<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> setItems<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<(K, V)> items) where OrdK : Ord<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> setItems<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<KeyValuePair<K, V>> items) where OrdK : Ord<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> trySetItems<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<Tuple<K, V>> items) where OrdK : Ord<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> trySetItems<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<(K, V)> items) where OrdK : Ord<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> trySetItems<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<KeyValuePair<K, V>> items) where OrdK : Ord<K> =>\n        map.TrySetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<OrdK, K, V> trySetItems<OrdK, K, V>(Map<OrdK, K, V> map, IEnumerable<K> keys, Func<V, V> Some) where OrdK : Ord<K> =>\n        map.TrySetItems(keys, Some);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static Option<V> find<OrdK, K, V>(Map<OrdK, K, V> map, K key) where OrdK : Ord<K> =>\n        map.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static IEnumerable<V> findSeq<OrdK, K, V>(Map<OrdK, K, V> map, K key) where OrdK : Ord<K> =>\n        map.FindSeq(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static R find<OrdK, K, V, R>(Map<OrdK, K, V> map, K key, Func<V, R> Some, Func<R> None) where OrdK : Ord<K> =>\n        map.Find(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static Map<OrdK, K, V> setItem<OrdK, K, V>(Map<OrdK, K, V> map, K key, Func<V, V> mapper) where OrdK : Ord<K> =>\n        map.SetItem(key, mapper);\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    public static IEnumerable<V> findRange<OrdK, K, V>(Map<OrdK, K, V> map, K keyFrom, K keyTo) where OrdK : Ord<K> =>\n        map.FindRange(keyFrom, keyTo);\n\n    /// <summary>\n    /// Skips 'amount' values and returns a new tree without the \n    /// skipped values.\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>Enumerable of map items</returns>\n    [Pure]\n    public static IEnumerable<(K Key, V Value)> skip<OrdK, K, V>(Map<OrdK, K, V> map, int amount) where OrdK : Ord<K> =>\n        map.Skip(amount);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<OrdK, K, V>(Map<OrdK, K, V> map, Action<V> action) where OrdK : Ord<K> =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<OrdK, K, V>(Map<OrdK, K, V> map, Action<K, V> action) where OrdK : Ord<K> =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<OrdK, K, V>(Map<OrdK, K, V> map, Func<V, bool> pred) where OrdK : Ord<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<OrdK, K, V>(Map<OrdK, K, V> map, Func<K, V, bool> pred) where OrdK : Ord<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<OrdK, K, V>(Map<OrdK, K, V> map, Func<Tuple<K, V>, bool> pred) where OrdK : Ord<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<OrdK, K, V>(Map<OrdK, K, V> map, Func<(K Key, V Value), bool> pred) where OrdK : Ord<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<OrdK, K, V>(Map<OrdK, K, V> map, Func<KeyValuePair<K, V>, bool> pred) where OrdK : Ord<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public static Map<OrdK, K, U> map<OrdK, K, T, U>(Map<OrdK, K, T> map, Func<T, U> f) where OrdK : Ord<K> =>\n        map.Select(f);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public static Map<OrdK, K, U> map<OrdK, K, T, U>(Map<OrdK, K, T> map, Func<K, T, U> f) where OrdK : Ord<K> =>\n        map.Select(f);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public static Map<OrdK, K, V> filter<OrdK, K, V>(Map<OrdK, K, V> map, Func<V, bool> predicate) where OrdK : Ord<K> =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public static Map<OrdK, K, V> filter<OrdK, K, V>(Map<OrdK, K, V> map, Func<K, V, bool> predicate) where OrdK : Ord<K> =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    public static Map<OrdK, K, R> choose<OrdK, K, T, R>(Map<OrdK, K, T> map, Func<T, Option<R>> selector) where OrdK : Ord<K> =>\n        map.Choose(selector);\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    public static Map<OrdK, K, R> choose<OrdK, K, T, R>(Map<OrdK, K, T> map, Func<K, T, Option<R>> selector) where OrdK : Ord<K> =>\n        map.Choose(selector);\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public static int length<OrdK, K, T>(Map<OrdK, K, T> map) where OrdK : Ord<K> =>\n        map.Count;\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<OrdK, S, K, V>(Map<OrdK, K, V> map, S state, Func<S, K, V, S> folder) where OrdK : Ord<K> =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<OrdK, S, K, V>(Map<OrdK, K, V> map, S state, Func<S, V, S> folder) where OrdK : Ord<K> =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<OrdK, K, V>(Map<OrdK, K, V> map, Func<K, V, bool> pred) where OrdK : Ord<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<OrdK, K, V>(Map<OrdK, K, V> map, Func<Tuple<K, V>, bool> pred) where OrdK : Ord<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<OrdK, K, V>(Map<OrdK, K, V> map, Func<(K Key, V Value), bool> pred) where OrdK : Ord<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<OrdK, K, V>(Map<OrdK, K, V> map, Func<KeyValuePair<K, V>, bool> pred) where OrdK : Ord<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<OrdK, K, V>(Map<OrdK, K, V> map, Func<V, bool> pred) where OrdK : Ord<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Convert any IDictionary into an immutable Map K V\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> toMap<OrdK, K, V>(IDictionary<K, V> dict) where OrdK : Ord<K> =>\n        Prelude.toMap<OrdK, K, V>(dict.AsIterable().Map(kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Convert any IDictionary into an immutable Map K V\n    /// </summary>\n    [Pure]\n    public static HashMap<OrdK, K, V> toHashMap<OrdK, K, V>(IDictionary<K, V> dict) where OrdK : Ord<K> =>\n        Prelude.toHashMap<OrdK, K, V>(dict.AsIterable().Map(kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Convert any IDictionary into an immutable Map K V\n    /// </summary>\n    [Pure]\n    public static HashMap<OrdK, K, V> ToHashMap<OrdK, K, V>(this IDictionary<K, V> dict) where OrdK : Ord<K> =>\n        Prelude.toHashMap<OrdK, K, V>(dict.AsIterable().Map(kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> union<OrdK, K, V>(Map<OrdK, K, V> left, Map<OrdK, K, V> right, WhenMatched<K, V, V, V> Merge) where OrdK : Ord<K> =>\n        left.Union(right, (_, v) => v, (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, A> union<OrdK, K, A, B>(Map<OrdK, K, A> left, Map<OrdK, K, B> right, WhenMissing<K, B, A> MapRight, WhenMatched<K, A, B, A> Merge) where OrdK : Ord<K> =>\n        left.Union(right, (_, v) => v, MapRight, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, B> union<OrdK, K, A, B>(Map<OrdK, K, A> left, Map<OrdK, K, B> right, WhenMissing<K, A, B> MapLeft, WhenMatched<K, A, B, B> Merge) where OrdK : Ord<K> =>\n        left.Union(right, MapLeft, (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, C> union<OrdK, K, A, B, C>(Map<OrdK, K, A> left, Map<OrdK, K, B> right, WhenMissing<K, A, C> MapLeft, WhenMissing<K, B, C> MapRight, WhenMatched<K, A, B, C> Merge) where OrdK : Ord<K> =>\n        left.Union(right, MapLeft, MapRight, Merge);\n\n    /// <summary>\n    /// Intersect two maps.  Only keys that are in both maps are\n    /// returned.  The merge function is called for every resulting\n    /// key.\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, R> intersect<OrdK, K, A, B, R>(Map<OrdK, K, A> left, Map<OrdK, K, B> right, WhenMatched<K, A, B, R> merge) where OrdK : Ord<K> =>\n        left.Intersect(right, merge);\n\n    /// <summary>\n    /// Map differencing based on key.  this - other.\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> except<OrdK, K, V>(Map<OrdK, K, V> left, Map<OrdK, K, V> right) where OrdK : Ord<K> =>\n        left.Except(right);\n\n    /// <summary>\n    /// Keys that are in both maps are dropped and the remaining\n    /// items are merged and returned.\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> symmetricExcept<OrdK, K, V>(Map<OrdK, K, V> left, Map<OrdK, K, V> right) where OrdK : Ord<K> =>\n        left.SymmetricExcept(right);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Module.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable map module\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// [wikipedia.org/wiki/AVL_tree](http://en.wikipedia.org/wiki/AVL_tree)\n/// </summary>\npublic static partial class Map\n{\n    /// <summary>\n    /// Creates a new empty `Map`\n    /// </summary>\n    [Pure]\n    public static Map<K, V> empty<K, V>() =>\n        Map<K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new singleton `Map`\n    /// </summary>\n    [Pure]\n    public static Map<K, V> singleton<K, V>((K, V) value) =>\n        [value];\n\n    /// <summary>\n    /// Creates a new singleton `Map`\n    /// </summary>\n    [Pure]\n    public static Map<K, V> singleton<K, V>(K key, V value) =>\n        [(key, value)];\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<K, V> create<K, V>() =>\n        Map<K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<K, V> create<K, V>(Tuple<K, V> head, params Tuple<K, V>[] tail) =>\n        empty<K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<K, V> create<K, V>(KeyValuePair<K, V> head, params KeyValuePair<K, V>[] tail) =>\n        empty<K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<K, V> create<K, V>((K, V) head, params (K, V)[] tail) =>\n        empty<K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<K, V> createRange<K, V>(IEnumerable<Tuple<K, V>> keyValues) =>\n        empty<K, V>().AddRange(keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<K, V> createRange<K, V>(IEnumerable<(K, V)> keyValues) =>\n        new (keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<K, V> createRange<K, V>(ReadOnlySpan<(K, V)> keyValues) =>\n        keyValues.IsEmpty\n            ? Map<K, V>.Empty\n            : new (keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static Map<K, V> createRange<K, V>(IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        empty<K, V>().AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<K, V> add<K, V>(Map<K, V> map, K key, V value) =>\n        map.Add(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<K, V> tryAdd<K, V>(Map<K, V> map, K key, V value) =>\n        map.TryAdd(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists then the Fail handler is called with the unaltered map \n    /// and the value already set for the key, it expects a new map returned.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <param name=\"Fail\">Delegate to handle failure, you're given the unaltered map \n    /// and the value already set for the key</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<K, V> tryAdd<K, V>(Map<K, V> map, K key, V value, Func<Map<K, V>, V, Map<K, V>> Fail) =>\n        map.TryAdd(key, value, Fail);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<K, V> addOrUpdate<K, V>(Map<K, V> map, K key, V value) =>\n        map.AddOrUpdate(key, value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static Map<K, V> addOrUpdate<K, V>(Map<K, V> map, K key, Func<V, V> Some, Func<V> None) =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static Map<K, V> addOrUpdate<K, V>(Map<K, V> map, K key, Func<V, V> Some, V None) =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> addRange<K, V>(Map<K, V> map, IEnumerable<Tuple<K, V>> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> addRange<K, V>(Map<K, V> map, IEnumerable<(K, V)> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> addRange<K, V>(Map<K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> tryAddRange<K, V>(Map<K, V> map, IEnumerable<Tuple<K, V>> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> tryAddRange<K, V>(Map<K, V> map, IEnumerable<(K, V)> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> tryAddRange<K, V>(Map<K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> addOrUpdateRange<K, V>(Map<K, V> map, IEnumerable<Tuple<K, V>> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> addOrUpdateRange<K, V>(Map<K, V> map, IEnumerable<(K, V)> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static Map<K, V> addOrUpdateRange<K, V>(Map<K, V> map, IEnumerable<KeyValuePair<K, V>> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public static Map<K, V> remove<K, V>(Map<K, V> map, K key) =>\n        map.Remove(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool containsKey<K, V>(Map<K, V> map, K key) =>\n        map.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<K, V>(Map<K, V> map, KeyValuePair<K, V> kv) =>\n        map.Contains(kv.Key, kv.Value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<K, V>(Map<K, V> map, Tuple<K, V> kv) =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<K, V>(Map<K, V> map, (K, V) kv) =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<K, V> setItem<K, V>(Map<K, V> map, K key, V value) =>\n        map.SetItem(key, value);\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static Map<K, V> trySetItem<K, V>(Map<K, V> map, K key, V value) =>\n        map.TrySetItem(key, value);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map (Some), and then putting \n    /// it back. Silently fails if the value doesn't exist.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public static Map<K, V> trySetItem<K, V>(Map<K, V> map, K key, Func<V, V> Some) =>\n        map.TrySetItem(key, Some);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Calls the None delegate to return a new map if the item can't be found\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <param name=\"None\">delegate to return a new map if the item can't be found</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public static Map<K, V> trySetItem<K, V>(Map<K, V> map, K key, Func<V, V> Some, Func<Map<K, V>, Map<K, V>> None) =>\n        map.TrySetItem(key, Some, None);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<K, V> setItems<K, V>(Map<K, V> map, IEnumerable<Tuple<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<K, V> setItems<K, V>(Map<K, V> map, IEnumerable<(K, V)> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<K, V> setItems<K, V>(Map<K, V> map, IEnumerable<KeyValuePair<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<K, V> trySetItems<K, V>(Map<K, V> map, IEnumerable<Tuple<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<K, V> trySetItems<K, V>(Map<K, V> map, IEnumerable<(K, V)> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<K, V> trySetItems<K, V>(Map<K, V> map, IEnumerable<KeyValuePair<K, V>> items) =>\n        map.TrySetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static Map<K, V> trySetItems<K, V>(Map<K, V> map, IEnumerable<K> keys, Func<V, V> Some) =>\n        map.TrySetItems(keys, Some);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static Option<V> find<K, V>(Map<K, V> map, K key) =>\n        map.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static IEnumerable<V> findSeq<K, V>(Map<K, V> map, K key) =>\n        map.FindSeq(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static R find<K, V, R>(Map<K, V> map, K key, Func<V, R> Some, Func<R> None) =>\n        map.Find(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static Map<K, V> setItem<K, V>(Map<K, V> map, K key, Func<V, V> mapper) =>\n        map.SetItem(key, mapper);\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    public static IEnumerable<V> findRange<K, V>(Map<K, V> map, K keyFrom, K keyTo) =>\n        map.FindRange(keyFrom, keyTo);\n\n    /// <summary>\n    /// Skips 'amount' values and returns a new tree without the \n    /// skipped values.\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>Enumerable of map items</returns>\n    [Pure]\n    public static IEnumerable<(K Key, V Value)> skip<K, V>(Map<K, V> map, int amount) =>\n        map.Skip(amount);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<K, V>(Map<K, V> map, Action<V> action) =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<K, V>(Map<K, V> map, Action<K, V> action) =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(Map<K, V> map, Func<V, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(Map<K, V> map, Func<K, V, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(Map<K, V> map, Func<Tuple<K, V>, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(Map<K, V> map, Func<(K Key, V Value), bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(Map<K, V> map, Func<KeyValuePair<K, V>, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public static Map<K, U> map<K, T, U>(Map<K, T> map, Func<T, U> f) =>\n        map.Select(f);\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    public static Map<K, U> map<K, T, U>(Map<K, T> map, Func<K, T, U> f) =>\n        map.Select(f);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public static Map<K, V> filter<K, V>(Map<K, V> map, Func<V, bool> predicate) =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public static Map<K, V> filter<K, V>(Map<K, V> map, Func<K, V, bool> predicate) =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    public static Map<K, R> choose<K, T, R>(Map<K, T> map, Func<T, Option<R>> selector) =>\n        map.Choose(selector);\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    public static Map<K, R> choose<K, T, R>(Map<K, T> map, Func<K, T, Option<R>> selector) =>\n        map.Choose(selector);\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public static int length<K, T>(Map<K, T> map) =>\n        map.Count;\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<S, K, V>(Map<K, V> map, S state, Func<S, K, V, S> folder) =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<S, K, V>(Map<K, V> map, S state, Func<S, V, S> folder) =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(Map<K, V> map, Func<K, V, bool> pred) =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(Map<K, V> map, Func<Tuple<K, V>, bool> pred) =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(Map<K, V> map, Func<(K Key, V Value), bool> pred) =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(Map<K, V> map, Func<KeyValuePair<K, V>, bool> pred) =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(Map<K, V> map, Func<V, bool> pred) =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Convert any IDictionary into an immutable Map K V\n    /// </summary>\n    [Pure]\n    public static Map<K, V> toMap<K, V>(IDictionary<K, V> dict) =>\n        Prelude.toMap(dict.AsIterable().Map(kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Convert any IDictionary into an immutable Map K V\n    /// </summary>\n    [Pure]\n    public static Map<K, V> ToMap<K, V>(this IDictionary<K, V> dict) =>\n        Prelude.toMap(dict.AsIterable().Map(kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Convert any IDictionary into an immutable Map K V\n    /// </summary>\n    [Pure]\n    public static HashMap<K, V> toHashMap<K, V>(IDictionary<K, V> dict) =>\n        Prelude.toHashMap(dict.AsIterable().Map(kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Convert any IDictionary into an immutable Map K V\n    /// </summary>\n    [Pure]\n    public static HashMap<K, V> ToHashMap<K, V>(this IDictionary<K, V> dict) =>\n        Prelude.toHashMap(dict.AsIterable().Map(kv => (kv.Key, kv.Value)));\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public static Map<K, V> union<K, V>(Map<K, V> left, Map<K, V> right, WhenMatched<K, V, V, V> Merge) =>\n        left.Union(right, (_, v) => v, (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public static Map<K, A> union<K, A, B>(Map<K, A> left, Map<K, B> right, WhenMissing<K, B, A> MapRight, WhenMatched<K, A, B, A> Merge) =>\n        left.Union(right, (_, v) => v, MapRight, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public static Map<K, B> union<K, A, B>(Map<K, A> left, Map<K, B> right, WhenMissing<K, A, B> MapLeft, WhenMatched<K, A, B, B> Merge) =>\n        left.Union(right, MapLeft, (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public static Map<K, C> union<K, A, B, C>(Map<K, A> left, Map<K, B> right, WhenMissing<K, A, C> MapLeft, WhenMissing<K, B, C> MapRight, WhenMatched<K, A, B, C> Merge) =>\n        left.Union(right, MapLeft, MapRight, Merge);\n\n    /// <summary>\n    /// Intersect two maps.  Only keys that are in both maps are\n    /// returned.  The merge function is called for every resulting\n    /// key.\n    /// </summary>\n    [Pure]\n    public static Map<K, R> intersect<K, A, B, R>(Map<K, A> left, Map<K, B> right, WhenMatched<K, A, B, R> merge) =>\n        left.Intersect(right, merge);\n\n    /// <summary>\n    /// Map differencing based on key.  this - other.\n    /// </summary>\n    [Pure]\n    public static Map<K, V> except<K, V>(Map<K, V> left, Map<K, V> right) =>\n        left.Except(right);\n\n    /// <summary>\n    /// Keys that are in both maps are dropped and the remaining\n    /// items are merged and returned.\n    /// </summary>\n    [Pure]\n    public static Map<K, V> symmetricExcept<K, V>(Map<K, V> left, Map<K, V> right) =>\n        left.SymmetricExcept(right);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Ord.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable map\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// [wikipedia.org/wiki/AVL_tree](http://en.wikipedia.org/wiki/AVL_tree)\n/// </summary>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\n[Serializable]\n[CollectionBuilder(typeof(Map), nameof(Map.createRange))]\npublic readonly struct Map<OrdK, K, V> :\n    IReadOnlyDictionary<K, V>,\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<Map<OrdK, K, V>>,\n    IComparable<Map<OrdK, K, V>>,\n    IComparisonOperators<Map<OrdK, K, V>, Map<OrdK, K, V>, bool>,\n    IAdditionOperators<Map<OrdK, K, V>, Map<OrdK, K, V>, Map<OrdK, K, V>>,\n    ISubtractionOperators<Map<OrdK, K, V>, Map<OrdK, K, V>, Map<OrdK, K, V>>,\n    IAdditiveIdentity<Map<OrdK, K, V>, Map<OrdK, K, V>>,\n    Monoid<Map<OrdK, K, V>>,\n    IComparable\n    where OrdK : Ord<K>\n{\n    public static Map<OrdK, K, V> Empty { get; } =\n        new(MapInternal<OrdDefault<K>, K, V>.Empty);\n\n    readonly MapInternal<OrdK, K, V> value;\n\n    internal static Map<OrdK, K, V> Wrap(MapInternal<OrdK, K, V> map) =>\n        new (map);\n\n    public Map(IEnumerable<(K Key, V Value)> items) : this(items, true)\n    { }\n\n    public Map(ReadOnlySpan<(K Key, V Value)> items) : this(items, true)\n    { }\n\n    public Map(IEnumerable<(K Key, V Value)> items, bool tryAdd) =>\n        value = new MapInternal<OrdK, K, V>(\n            items,\n            tryAdd\n                ? MapModuleM.AddOpt.TryAdd\n                : MapModuleM.AddOpt.ThrowOnDuplicate);\n\n    public Map(ReadOnlySpan<(K Key, V Value)> items, bool tryAdd) =>\n        value = new MapInternal<OrdK, K, V>(\n            items,\n            tryAdd\n                ? MapModuleM.AddOpt.TryAdd\n                : MapModuleM.AddOpt.ThrowOnDuplicate);\n\n    internal Map(MapInternal<OrdK, K, V> value) =>\n        this.value = value;\n\n    internal Map(MapItem<K, V> root, bool rev) =>\n        this.value = new MapInternal<OrdK, K, V>(root, rev);\n\n    internal MapInternal<OrdK, K, V> Value =>\n        value ?? MapInternal<OrdK, K, V>.Empty;\n        \n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = null\n    ///     Singleton collection = (K, V)\n    ///     More                 = ((K, V), Seq〈(K, V)〉)   -- head and tail\n    ///\n    ///     var res = list.Case switch\n    ///     {\n    ///       \n    ///        (var x, var xs) => ...,\n    ///        A value         => ...,\n    ///        _               => ...\n    ///     }\n    /// \n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty \n            ? null\n            : AsIterable().ToSeq().Case;\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public V this[K key] => Value[key];\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public Map<OrdK, K, V> Add(K key, V value) => Wrap(Value.Add(key,value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public Map<OrdK, K, V> TryAdd(K key, V value) => Wrap(Value.TryAdd(key, value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists then the Fail handler is called with the unaltered map \n    /// and the value already set for the key, it expects a new map returned.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <param name=\"Fail\">Delegate to handle failure, you're given the unaltered map \n    /// and the value already set for the key</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public Map<OrdK, K, V> TryAdd(K key, V value, Func<Map<OrdK, K, V>, V, Map<OrdK, K, V>> Fail) => \n        Wrap(Value.TryAdd(key, value, (m,v) => Fail(Wrap(m),v).Value));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public Map<OrdK, K, V> AddRange(IEnumerable<Tuple<K, V>> range) => Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public Map<OrdK, K, V> AddRange(IEnumerable<(K, V)> range) => Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public Map<OrdK, K, V> TryAddRange(IEnumerable<Tuple<K, V>> range) => Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public Map<OrdK, K, V> TryAddRange(IEnumerable<(K, V)> range) => Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public Map<OrdK, K, V> TryAddRange(IEnumerable<KeyValuePair<K, V>> range) => Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public Map<OrdK, K, V> AddOrUpdateRange(IEnumerable<Tuple<K, V>> range) => Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public Map<OrdK, K, V> AddOrUpdateRange(IEnumerable<(K, V)> range) => Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public Map<OrdK, K, V> AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range) => Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public Map<OrdK, K, V> Remove(K key) => Wrap(Value.Remove(key));\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Option<V> Find(K key) => Value.Find(key);\n        \n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Seq<V> FindSeq(K key) => Value.FindSeq(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) => Value.Find(key, Some, None);\n\n    /// <summary>\n    /// Retrieve the value from previous item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key/value</returns>\n    [Pure]\n    public Option<(K Key, V Value)> FindPredecessor(K key) => Value.FindPredecessor(key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the previous item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key/value</returns>\n    [Pure]\n    public Option<(K Key, V Value)> FindExactOrPredecessor(K key) => Value.FindOrPredecessor(key);\n\n    /// <summary>\n    /// Retrieve the value from next item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key/value</returns>\n    [Pure]\n    public Option<(K Key, V Value)> FindSuccessor(K key) => Value.FindSuccessor(key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the next item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key/value</returns>\n    [Pure]\n    public Option<(K Key, V Value)> FindExactOrSuccessor(K key) => Value.FindOrSuccessor(key);\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (Map<OrdK, K, V> Map, V Value) FindOrAdd(K key, Func<V> None) =>\n        Value.FindOrAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (Map<OrdK, K, V>, V Value) FindOrAdd(K key, V value) =>\n        Value.FindOrAdd(key, value).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (Map<OrdK, K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Func<Option<V>> None) =>\n        Value.FindOrMaybeAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (Map<OrdK, K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Option<V> None) =>\n        Value.FindOrMaybeAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public Map<OrdK, K, V> SetItem(K key, V value) => Wrap(Value.SetItem(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public Map<OrdK, K, V> SetItem(K key, Func<V, V> Some) => Wrap(Value.SetItem(key, Some));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public Map<OrdK, K, V> TrySetItem(K key, V value) => Wrap(Value.TrySetItem(key, value));\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public Map<OrdK, K, V> TrySetItem(K key, Func<V, V> Some) => Wrap(Value.TrySetItem(key, Some));\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Calls the None delegate to return a new map if the item can't be found\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <param name=\"None\">delegate to return a new map if the item can't be found</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public Map<OrdK, K, V> TrySetItem(K key, Func<V, V> Some, Func<Map<K, V>, Map<K, V>> None) => Wrap(Value.TrySetItem(key, Some, None));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public Map<OrdK, K, V> AddOrUpdate(K key, V value) => Wrap(Value.AddOrUpdate(key,value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public Map<OrdK, K, V> AddOrUpdate(K key, Func<V, V> Some, Func<V> None) => Wrap(Value.AddOrUpdate(key, Some, None));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public Map<OrdK, K, V> AddOrUpdate(K key, Func<V, V> Some, V None) => Wrap(Value.AddOrUpdate(key, Some, None));\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    public Iterable<V> FindRange(K keyFrom, K keyTo) => Value.FindRange(keyFrom, keyTo);\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    public Iterable<(K Key, V Value)> FindRangePairs(K keyFrom, K keyTo) => Value.FindRangePairs(keyFrom, keyTo);\n\n    /// <summary>\n    /// Skips 'amount' values and returns a new tree without the \n    /// skipped values.\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>New tree</returns>\n    [Pure]\n    public Iterable<(K Key, V Value)> Skip(int amount) => Value.Skip(amount);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool ContainsKey(K key) => Value.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains(K key, V value) => Value.Contains(key, value);\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    public Map<OrdK, K, V> Clear() => Wrap(Value.Clear());\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public Map<OrdK, K, V> SetItems(IEnumerable<KeyValuePair<K, V>> items) => Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public Map<OrdK, K, V> SetItems(IEnumerable<Tuple<K, V>> items) => Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public Map<OrdK, K, V> SetItems(IEnumerable<(K, V)> items) => Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public Map<OrdK, K, V> TrySetItems(IEnumerable<KeyValuePair<K, V>> items) => Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public Map<OrdK, K, V> TrySetItems(IEnumerable<Tuple<K, V>> items) => Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public Map<OrdK, K, V> TrySetItems(IEnumerable<(K, V)> items) => Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public Map<OrdK, K, V> TrySetItems(IEnumerable<K> keys, Func<V, V> Some) => Wrap(Value.TrySetItems(keys, Some));\n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New map with the items removed</returns>\n    [Pure]\n    public Map<OrdK, K, V> RemoveRange(IEnumerable<K> keys) => Wrap(Value.RemoveRange(keys));\n\n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    public bool Contains(KeyValuePair<K, V> pair) => Value.Contains(pair);\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys => Value.Keys;\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values => Value.Values;\n\n    /// <summary>\n    /// Map the map the a dictionary\n    /// </summary>\n    [Pure]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(Func<(K Key, V Value), KR> keySelector, Func<(K Key, V Value), VR> valueSelector) \n        where KR : notnull => \n        Value.ToDictionary(keySelector, valueSelector);\n\n    /// <summary>\n    /// Enumerable of in-order tuples that make up the map\n    /// </summary>\n    /// <returns>Tuples</returns>\n    [Pure]\n    public Iterable<(K Key, V Value)> Pairs =>\n        Value.Pairs;\n\n    /// <summary>\n    /// Enumerable of in-order tuples that make up the map\n    /// </summary>\n    /// <returns>Tuples</returns>\n    [Pure]\n    [Obsolete(\"Use `Pairs` instead\")]\n    public Iterable<(K Key, V Value)> ValueTuples =>\n        Value.Pairs;\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    public IEnumerator<(K Key, V Value)> GetEnumerator() => \n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() => \n        Value.GetEnumerator();\n\n    [Pure]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        AsIterable().ToSeq();\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(Pairs.Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(Pairs.Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(Pairs.Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    public Iterable<(K Key, V Value)> AsIterable() => \n        Value.AsIterable();\n\n    [Pure] public IEnumerable<(K Key, V Value)> AsEnumerable() => \n        Value.AsEnumerable();\n\n    internal Map<OrdK, K, V> SetRoot(MapItem<K, V> root) => \n        new(new MapInternal<OrdK, K, V>(root, Value.Rev));\n\n    [Pure]\n    public static bool operator ==(Map<OrdK, K, V> lhs, Map<OrdK, K, V> rhs) =>\n        lhs.Value == rhs.Value;\n\n    [Pure]\n    public static bool operator !=(Map<OrdK, K, V> lhs, Map<OrdK, K, V> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public static bool operator <(Map<OrdK, K, V> lhs, Map<OrdK, K, V> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    [Pure]\n    public static bool operator <=(Map<OrdK, K, V> lhs, Map<OrdK, K, V> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    [Pure]\n    public static bool operator >(Map<OrdK, K, V> lhs, Map<OrdK, K, V> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    [Pure]\n    public static bool operator >=(Map<OrdK, K, V> lhs, Map<OrdK, K, V> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    [Pure]\n    public Map<OrdK, K, V> Combine(Map<OrdK, K, V> y) => \n        this + y;\n\n    [Pure]\n    public static Map<OrdK, K, V> operator +(Map<OrdK, K, V> lhs, Map<OrdK, K, V> rhs) =>\n        new(lhs.Value + rhs.Value);\n\n    [Pure]\n    public static Map<OrdK, K, V> operator -(Map<OrdK, K, V> lhs, Map<OrdK, K, V> rhs) =>\n        new(lhs.Value - rhs.Value);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is Map<OrdK, K, V> m && Equals(m);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals(Map<OrdK, K, V> y) =>\n        Value.Equals<EqDefault<V>>(y.Value);\n\n    /// <summary>\n    /// Equality of keys and values\n    /// </summary>\n    [Pure]\n    public bool Equals<EqV>(Map<OrdK, K, V> y) where EqV : Eq<V> =>\n        Value.Equals<EqV>(y.Value);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    public bool EqualsKeys(Map<OrdK, K, V> y) =>\n        Value.Equals<EqTrue<V>>(y.Value);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj is Map<OrdK, K, V> t ? CompareTo(t) : 1;\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Map<OrdK, K, V> Do(Action<V> f)\n    {\n        Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public Map<OrdK, K, U> Select<U>(Func<V, U> mapper) =>\n        new (AsEnumerable().Select(kv => (kv.Key, mapper(kv.Value))));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public Map<OrdK, K, U> Select<U>(Func<K, V, U> mapper) =>\n        new (AsEnumerable().Select(kv => (kv.Key, mapper(kv.Key, kv.Value))));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"valuePred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public Map<OrdK, K, V> Where(Func<V, bool> valuePred) =>\n        new (Value.Filter(valuePred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"keyValuePred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public Map<OrdK, K, V> Where(Func<K, V, bool> keyValuePred) =>\n        new (Value.Filter(keyValuePred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"valuePred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public Map<OrdK, K, V> Filter(Func<V, bool> valuePred) =>\n        new(Value.Filter(valuePred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"keyValuePred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public Map<OrdK, K, V> Filter(Func<K, V, bool> keyValuePred) =>\n        new(Value.Filter(keyValuePred));\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<K, V, bool> pred) =>\n        MapModule.ForAll(Value.Root, pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<Tuple<K, V>, bool> pred) =>\n        MapModule.ForAll(Value.Root, (k, v) => pred(new Tuple<K, V>(k, v)));\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        MapModule.ForAll(Value.Root, (k, v) => pred((k, v)));\n\n    /// <summary>\n    /// Return true if *all* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<KeyValuePair<K, V>, bool> pred) =>\n        MapModule.ForAll(Value.Root, (k, v) => pred(new KeyValuePair<K, V>(k, v)));\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<V, bool> pred) =>\n        MapModule.ForAll(Value.Root, (_, v) => pred(v));\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<K, V, bool> pred) =>\n        MapModule.Exists(Value.Root, pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<Tuple<K, V>, bool> pred) =>\n        MapModule.Exists(Value.Root, (k, v) => pred(new Tuple<K, V>(k, v)));\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<(K, V), bool> pred) =>\n        MapModule.Exists(Value.Root, (k, v) => pred((k, v)));\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<KeyValuePair<K, V>, bool> pred) =>\n        MapModule.Exists(Value.Root, (k, v) => pred(new KeyValuePair<K, V>(k, v)));\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<V, bool> pred) =>\n        MapModule.Exists(Value.Root, (_, v) => pred(v));\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<K, V> action) \n    {\n        foreach (var item in this)\n        {\n            action(item.Key, item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<V> action) \n    {\n        foreach (var item in this)\n        {\n            action(item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<Tuple<K, V>> action) \n    {\n        foreach (var item in this)\n        {\n            action(new Tuple<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<(K, V)> action) \n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<KeyValuePair<K, V>> action) \n    {\n        foreach (var item in this)\n        {\n            action(new KeyValuePair<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    public Map<OrdK, K, U> Choose<U>(Func<K, V, Option<U>> selector) =>\n        new(Value.Choose(selector));\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    public Map<OrdK, K, U> Choose<U>(Func<V, Option<U>> selector) =>\n        new(Value.Choose(selector));\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        MapModule.Fold(Value.Root, state, folder);\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, V, S> folder) =>\n        MapModule.Fold(Value.Root, state, folder);\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(ValueTuple<(K, V)> items) =>\n        [items.Item1];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V)) items) =>\n        [items.Item1, items.Item2];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<OrdK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15, items.Item16];\n\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public Map<OrdK, K, V> Union(Map<OrdK, K, V> other, WhenMatched<K, V, V, V> Merge) =>\n        Union(other, (_, v) => v, (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public Map<OrdK, K, V> Union<V2>(Map<OrdK, K, V2> other, WhenMissing<K, V2, V> MapRight, WhenMatched<K, V, V2, V> Merge) =>\n        Union(other, (_, v) => v, MapRight, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public Map<OrdK, K, V2> Union<V2>(Map<OrdK, K, V2> other, WhenMissing<K, V, V2> MapLeft, WhenMatched<K, V, V2, V2> Merge) =>\n        Union(other, MapLeft, (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    public Map<OrdK, K, R> Union<V2, R>(Map<OrdK, K, V2> other, WhenMissing<K, V, R> MapLeft, WhenMissing<K, V2, R> MapRight, WhenMatched<K, V, V2, R> Merge) =>\n        new (Value.Union(other.Value, MapLeft, MapRight, Merge));\n\n    /// <summary>\n    /// Intersect two maps.  Only keys that are in both maps are\n    /// returned.  The merge function is called for every resulting\n    /// key.\n    /// </summary>\n    [Pure]\n    public Map<OrdK, K, R> Intersect<V2, R>(Map<OrdK, K, V2> other, WhenMatched<K, V, V2, R> Merge) =>\n        new (Value.Intersect(other.Value, Merge));\n\n    /// <summary>\n    /// Map differencing based on key.  this - other.\n    /// </summary>\n    [Pure]\n    public Map<OrdK, K, V> Except(Map<OrdK, K, V> other) =>\n        new (Value.Except(other.Value));\n\n    /// <summary>\n    /// Keys that are in both maps are dropped and the remaining\n    /// items are merged and returned.\n    /// </summary>\n    [Pure]\n    public Map<OrdK, K, V> SymmetricExcept(Map<OrdK, K, V> other) =>\n        new (Value.SymmetricExcept(other.Value));\n\n    /// <summary>\n    /// Compare keys and values (values use `OrdDefault〈V〉` for ordering)\n    /// </summary>\n    [Pure]\n    public int CompareTo(Map<OrdK, K, V> other) =>\n        Value.CompareTo<OrdDefault<V>>(other.Value);\n\n    /// <summary>\n    /// Compare keys and values (values use `OrdV` for ordering)\n    /// </summary>\n    [Pure]\n    public int CompareTo<OrdV>(Map<OrdK, K, V> other) where OrdV : Ord<V> =>\n        Value.CompareTo<OrdV>(other.Value);\n\n    /// <summary>\n    /// Compare keys only\n    /// </summary>\n    [Pure]\n    public int CompareKeysTo(Map<OrdK, K, V> other) =>\n        Value.CompareTo<OrdTrue<V>>(other.Value);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    public static implicit operator Map<OrdK, K, V>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Creates a new map from a range/slice of this map\n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <returns></returns>\n    [Pure]\n    public Map<OrdK, K, V> Slice(K keyFrom, K keyTo) =>\n        new (FindRangePairs(keyFrom, keyTo));\n\n    /// <summary>\n    /// Find the lowest ordered item in the map\n    /// </summary>\n    [Pure]\n    public Option<(K Key, V Value)> Min => Value.Min;\n\n    /// <summary>\n    /// Find the highest ordered item in the map\n    /// </summary>\n    [Pure]\n    public Option<(K Key, V Value)> Max => Value.Max;\n    \n    [Pure]\n    IEnumerable<K> IReadOnlyDictionary<K, V>.Keys => Keys;\n\n    [Pure]\n    IEnumerable<V> IReadOnlyDictionary<K, V>.Values => Values;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool TryGetValue(K key, out V value)\n    {\n        var v = Find(key);\n        if (v.IsSome)\n        {\n            value = (V)v;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() =>\n        AsIterable().Map(p => new KeyValuePair<K, V>(p.Key, p.Value)).GetEnumerator();    \n\n    public static Map<OrdK, K, V> AdditiveIdentity => \n        Empty;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Map<Key, B> map<Key, A, B>(Func<A, B> f, K<Map<Key>, A> ma) =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.Trait.Implementations.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Map<Key> : Foldable<Map<Key>>, Functor<Map<Key>>, MonoidK<Map<Key>>\n{\n    static K<Map<Key>, B> Functor<Map<Key>>.Map<A, B>(Func<A, B> f, K<Map<Key>, A> ma)\n    {\n        return new Map<Key, B>(Go());\n        IEnumerable<(Key, B)> Go()\n        {\n            foreach (var x in ma.As())\n            {\n                yield return (x.Key, f(x.Value));\n            }\n        }\n    }\n    \n    static S Foldable<Map<Key>>.FoldWhile<A, S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S state, K<Map<Key>, A> ta)\n    {\n        foreach (var x in ta.As())\n        {\n            if (!predicate((state, x.Value))) return state;\n            state = f(x.Value)(state);\n        }\n        return state;\n    }\n    \n    static S Foldable<Map<Key>>.FoldBackWhile<A, S>(Func<S, Func<A, S>> f, Func<(S State, A Value), bool> predicate, S state, K<Map<Key>, A> ta)\n    {\n        foreach (var x in ta.As().Value.Reverse())\n        {\n            if (!predicate((state, x.Value))) return state;\n            state = f(state)(x.Value);\n        }\n        return state;\n    }\n    \n        \n    static int Foldable<Map<Key>>.Count<A>(K<Map<Key>, A> ta) =>\n        ta.As().Count;\n\n    static bool Foldable<Map<Key>>.IsEmpty<A>(K<Map<Key>, A> ta) =>\n        ta.As().IsEmpty;\n\n    static Option<A> Foldable<Map<Key>>.Head<A>(K<Map<Key>, A> ta) =>\n        ta.As().Min.Map(kv => kv.Value);\n\n    static Option<A> Foldable<Map<Key>>.Last<A>(K<Map<Key>, A> ta) =>\n        ta.As().Max.Map(kv => kv.Value);\n\n    static Option<A> Foldable<Map<Key>>.Min<A>(K<Map<Key>, A> ta) =>\n        ta.As().Min.Map(kv => kv.Value);\n\n    static Option<A> Foldable<Map<Key>>.Max<A>(K<Map<Key>, A> ta) =>\n        ta.As().Max.Map(kv => kv.Value);\n\n    static K<Map<Key>, A> SemigroupK<Map<Key>>.Combine<A>(K<Map<Key>, A> lhs, K<Map<Key>, A> rhs) =>\n        lhs.As() + rhs.As();\n\n    static K<Map<Key>, A> MonoidK<Map<Key>>.Empty<A>() =>\n        Map<Key, A>.Empty;\n    \n    static Fold<A, S> Foldable<Map<Key>>.FoldStep<A, S>(K<Map<Key>, A> ta, S initialState) =>\n        ta.As().FoldStepValues(initialState);\n    \n    static Fold<A, S> Foldable<Map<Key>>.FoldStepBack<A, S>(K<Map<Key>, A> ta, S initialState) =>\n        ta.As().FoldStepBackValues(initialState);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Map/Map.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.ClassInstances;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic delegate B WhenMissing<in K, in A, out B>(K key, A value);\npublic delegate C WhenMatched<in K, in A, in B, out C>(K key, A left, B right);\n\n/// <summary>\n/// Immutable map\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// [wikipedia.org/wiki/AVL_tree](http://en.wikipedia.org/wiki/AVL_tree)\n/// </summary>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value type</typeparam>\n[Serializable]\n[CollectionBuilder(typeof(Map), nameof(Map.createRange))]\npublic readonly struct Map<K, V> :\n    IReadOnlyDictionary<K, V>,\n    IEnumerable<(K Key, V Value)>,\n    IComparable<Map<K, V>>,\n    IComparable,\n    IEquatable<Map<K, V>>,\n    IComparisonOperators<Map<K, V>, Map<K, V>, bool>,\n    IAdditionOperators<Map<K, V>, Map<K, V>, Map<K, V>>,\n    ISubtractionOperators<Map<K, V>, Map<K, V>, Map<K, V>>,\n    IAdditiveIdentity<Map<K, V>, Map<K, V>>,\n    Monoid<Map<K, V>>,\n    K<Map<K>, V>\n{\n    public static Map<K, V> Empty { get; } =\n        new(MapInternal<OrdDefault<K>, K, V>.Empty);\n\n    readonly MapInternal<OrdDefault<K>, K, V> value;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static Map<K, V> Wrap(MapInternal<OrdDefault<K>, K, V> map) =>\n        new (map);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map(IEnumerable<(K Key, V Value)> items) : this(items, true)\n    { }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map(IEnumerable<(K Key, V Value)> items, bool tryAdd) =>\n        value = new MapInternal<OrdDefault<K>, K, V>(\n            items, tryAdd\n                       ? MapModuleM.AddOpt.TryAdd\n                       : MapModuleM.AddOpt.ThrowOnDuplicate);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map(ReadOnlySpan<(K Key, V Value)> items) : this(items, true)\n    { }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map(ReadOnlySpan<(K Key, V Value)> items, bool tryAdd) =>\n        value = new MapInternal<OrdDefault<K>, K, V>(\n            items,\n            tryAdd\n                ? MapModuleM.AddOpt.TryAdd\n                : MapModuleM.AddOpt.ThrowOnDuplicate);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal Map(MapInternal<OrdDefault<K>, K, V> value) =>\n        this.value = value;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal Map(MapItem<K, V> root, bool rev) =>\n        value = new MapInternal<OrdDefault<K>, K, V>(root, rev);\n\n    internal MapInternal<OrdDefault<K>, K, V> Value\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value ?? MapInternal<OrdDefault<K>, K, V>.Empty;\n    }\n        \n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = null\n    ///     Singleton collection = (K, V)\n    ///     More                 = ((K, V), Seq〈(K, V)〉)   -- head and tail\n    ///\n    ///     var res = list.Case switch\n    ///     {\n    ///       \n    ///        (var x, var xs) => ...,\n    ///        A value         => ...,\n    ///        _               => ...\n    ///     }\n    /// \n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty \n            ? null\n            : AsIterable().ToSeq().Case;\n        \n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Map<K, V>, V> item(K key) => Lens<Map<K, V>, V>.New(\n        Get: la => la[key],\n        Set: a  => la => la.AddOrUpdate(key, a)\n    );\n\n    /// <summary>\n    /// Item or none at index lens\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Map<K, V>, Option<V>> itemOrNone(K key) => Lens<Map<K, V>, Option<V>>.New(\n        Get: la => la.Find(key),\n        Set: a => la => a.Match(Some: x => la.AddOrUpdate(key, x), None: () => la.Remove(key))\n    );\n\n    /// <summary>\n    /// Lens map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lens<Map<K, V>, Map<K, B>> map<B>(Lens<V, B> lens) => Lens<Map<K, V>, Map<K, B>>.New(\n        Get: la => la.Map(lens.Get),\n        Set: lb => la =>\n                   {\n                       foreach (var item in lb)\n                       {\n                           la = la.AddOrUpdate(item.Key, lens.Set(item.Value, la[item.Key]));\n                       }\n                       return la;\n                   });\n    \n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>value</returns>\n    [Pure]\n    public V this[K key]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value[key];\n    }\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n        \n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Add(K key, V value) => Wrap(Value.Add(key,value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TryAdd(K key, V value) => Wrap(Value.TryAdd(key, value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists then the Fail handler is called with the unaltered map \n    /// and the value already set for the key, it expects a new map returned.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <param name=\"Fail\">Delegate to handle failure, you're given the unaltered map \n    /// and the value already set for the key</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TryAdd(K key, V value, Func<Map<K, V>, V, Map<K, V>> Fail) =>\n        Wrap(Value.TryAdd(key, value, (m, v) => Fail(Wrap(m), v).Value));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddRange(IEnumerable<Tuple<K, V>> range) => Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddRange(IEnumerable<(K, V)> range) => Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TryAddRange(IEnumerable<Tuple<K, V>> range) => Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TryAddRange(IEnumerable<(K, V)> range) => Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TryAddRange(IEnumerable<KeyValuePair<K, V>> range) => Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddOrUpdateRange(IEnumerable<Tuple<K, V>> range) => Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddOrUpdateRange(IEnumerable<(K, V)> range) => Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range) => Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Remove(K key) => Wrap(Value.Remove(key));\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<V> Find(K key) => Value.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<V> FindSeq(K key) => Value.FindSeq(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) => Value.Find(key, Some, None);\n\n    /// <summary>\n    /// Retrieve the value from previous item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key/value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<(K Key, V Value)> FindPredecessor(K key) => Value.FindPredecessor(key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the previous item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key/value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<(K Key, V Value)> FindExactOrPredecessor(K key) => Value.FindOrPredecessor(key);\n\n    /// <summary>\n    /// Retrieve the value from next item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key/value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<(K Key, V Value)> FindSuccessor(K key) => Value.FindSuccessor(key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the next item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key/value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<(K Key, V Value)> FindExactOrSuccessor(K key) => Value.FindOrSuccessor(key);\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (Map<K, V> Map, V Value) FindOrAdd(K key, Func<V> None) =>\n        Value.FindOrAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (Map<K, V>, V Value) FindOrAdd(K key, V value) =>\n        Value.FindOrAdd(key, value).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (Map<K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Func<Option<V>> None) =>\n        Value.FindOrMaybeAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (Map<K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Option<V> None) =>\n        Value.FindOrMaybeAdd(key, None).Map((x, y) => (Wrap(x), y));\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> SetItem(K key, V value) => Wrap(Value.SetItem(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> SetItem(K key, Func<V, V> Some) => Wrap(Value.SetItem(key, Some));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TrySetItem(K key, V value) => Wrap(Value.TrySetItem(key, value));\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TrySetItem(K key, Func<V, V> Some) => Wrap(Value.TrySetItem(key, Some));\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Calls the None delegate to return a new map if the item can't be found\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <param name=\"None\">delegate to return a new map if the item can't be found</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TrySetItem(K key, Func<V, V> Some, Func<Map<K, V>, Map<K, V>> None) => Wrap(Value.TrySetItem(key, Some, None));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddOrUpdate(K key, V value) => Wrap(Value.AddOrUpdate(key,value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddOrUpdate(K key, Func<V, V> Some, Func<V> None) => Wrap(Value.AddOrUpdate(key, Some, None));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddOrUpdate(K key, Func<V, V> Some, V None) => Wrap(Value.AddOrUpdate(key, Some, None));\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<V> FindRange(K keyFrom, K keyTo) => Value.FindRange(keyFrom, keyTo);\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of key, values</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K Key, V Value)> FindRangePairs(K keyFrom, K keyTo) => Value.FindRangePairs(keyFrom, keyTo);\n\n    /// <summary>\n    /// Skips 'amount' values and returns a new tree without the \n    /// skipped values.\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>New tree</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K Key, V Value)> Skip(int amount) => Value.Skip(amount);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ContainsKey(K key) => Value.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(K key, V value) => Value.Contains(key, value);\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Clear() => Wrap(Value.Clear());\n\n    /// <summary>\n    /// Atomically adds a range of items to the map\n    /// </summary>\n    /// <param name=\"pairs\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> AddRange(IEnumerable<KeyValuePair<K, V>> pairs) => Wrap(Value.AddRange(pairs));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> SetItems(IEnumerable<KeyValuePair<K, V>> items) => Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> SetItems(IEnumerable<Tuple<K, V>> items) => Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> SetItems(IEnumerable<(K, V)> items) => Wrap(Value.SetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TrySetItems(IEnumerable<KeyValuePair<K, V>> items) => Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TrySetItems(IEnumerable<Tuple<K, V>> items) => Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TrySetItems(IEnumerable<(K, V)> items) => Wrap(Value.TrySetItems(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> TrySetItems(IEnumerable<K> keys, Func<V, V> Some) => Wrap(Value.TrySetItems(keys, Some));\n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New map with the items removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> RemoveRange(IEnumerable<K> keys) => Wrap(Value.RemoveRange(keys));\n\n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(KeyValuePair<K, V> pair) => \n        Value.Contains(pair);\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Fold<(K, V), S> FoldStep<S>(S initialState) =>\n        Value.FoldStep(initialState);\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Fold<(K, V), S> FoldStepBack<S>(S initialState) =>\n        Value.FoldStepBack(initialState);\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Fold<K, S> FoldStepKeys<S>(S initialState) =>\n        Value.FoldStepKeys(initialState);\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Fold<K, S> FoldStepBackKeys<S>(S initialState) =>\n        Value.FoldStepBackKeys(initialState);\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Fold<V, S> FoldStepValues<S>(S initialState) =>\n        Value.FoldStepValues(initialState);\n\n    /// <summary>\n    /// Left/Node/Right traversal in stepped form\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Fold<V, S> FoldStepBackValues<S>(S initialState) =>\n        Value.FoldStepBackValues(initialState);\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.Keys;\n    }\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.Values;\n    }\n\n    /// <summary>\n    /// Map the map the a dictionary\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(Func<(K Key, V Value), KR> keySelector, Func<(K Key, V Value), VR> valueSelector) \n        where KR : notnull => \n        Value.ToDictionary(keySelector, valueSelector);\n\n    /// <summary>\n    /// Enumerable of in-order tuples that make up the map\n    /// </summary>\n    /// <returns>Tuples</returns>\n    [Pure]\n    public Iterable<(K Key, V Value)> Pairs\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.Pairs;\n    }\n\n    /// <summary>\n    /// Enumerable of in-order tuples that make up the map\n    /// </summary>\n    /// <returns>Tuples</returns>\n    [Pure]\n    [Obsolete(\"Use Pairs instead\")]\n    public Iterable<(K Key, V Value)> ValueTuples =>\n        Value.Pairs;\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public MapEnumerator<K, V> GetEnumerator() => \n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<(K Key, V Value)> IEnumerable<(K Key, V Value)>.GetEnumerator() =>\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() => \n        Value.GetEnumerator();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        AsIterable().ToSeq();\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsIterable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<(K Key, V Value)> AsIterable() => \n        Value.AsIterable();\n\n    [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerable<(K Key, V Value)> AsEnumerable() => \n        Value.AsEnumerable();\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal Map<K, V> SetRoot(MapItem<K, V> root) =>\n        new (new MapInternal<OrdDefault<K>, K, V>(root, Value.Rev));\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(ValueTuple<(K, V)> items) =>\n        [items.Item1];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V)) items) =>\n        [items.Item1, items.Item2];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator Map<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15, items.Item16];\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(Map<K, V> lhs, Map<K, V> rhs) =>\n        lhs.Equals(rhs);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(Map<K, V> lhs, Map<K, V> rhs) =>\n        !(lhs == rhs);\n        \n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <(Map<K, V> lhs, Map<K, V> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <=(Map<K, V> lhs, Map<K, V> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >(Map<K, V> lhs, Map<K, V> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >=(Map<K, V> lhs, Map<K, V> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Combine(Map<K, V> y) =>\n        this + y;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Map<K, V> operator +(Map<K, V> lhs, Map<K, V> rhs) =>\n        new(lhs.Value + rhs.Value);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Map<K, V> operator -(Map<K, V> lhs, Map<K, V> rhs) =>\n        new(lhs.Value - rhs.Value);\n    \n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is Map<K, V> m && Equals(m);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(Map<K, V> y) =>\n        Value.Equals<EqDefault<V>>(y.Value);\n\n    /// <summary>\n    /// Equality of keys and values\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals<EqV>(Map<K, V> y) where EqV : Eq<V> =>\n        Value.Equals<EqV>(y.Value);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool EqualsKeys(Map<K, V> y) =>\n        Value.Equals<EqTrue<V>>(y.Value);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(object? obj) =>\n        obj is Map<K, V> t ? CompareTo(t) : 1;\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Do(Action<V> f)\n    {\n        Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, U> Select<U>(Func<V, U> mapper) =>\n        new (AsIterable().Select(kv => (kv.Key, mapper(kv.Value))));\n\n    /// <summary>\n    /// Atomically maps the map to a new map\n    /// </summary>\n    /// <returns>Mapped items in a new map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, U> Select<U>(Func<K, V, U> mapper) =>\n        new (AsIterable().Select(kv => (kv.Key, mapper(kv.Key, kv.Value))));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"valuePred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Where(Func<V, bool> valuePred) =>\n        new(Value.Filter(valuePred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"keyValuePred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Where(Func<K, V, bool> keyValuePred) =>\n        new(Value.Filter(keyValuePred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"valuePred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Filter(Func<V, bool> valuePred) =>\n        new(Value.Filter(valuePred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Filter(Func<K, V, bool> keyValuePred) =>\n        new(Value.Filter(keyValuePred));\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<K, V, bool> pred) =>\n        MapModule.ForAll(Value.Root, pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<Tuple<K, V>, bool> pred) =>\n        MapModule.ForAll(Value.Root, (k, v) => pred(new Tuple<K, V>(k, v)));\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        MapModule.ForAll(Value.Root, (k, v) => pred((k, v)));\n\n    /// <summary>\n    /// Return true if *all* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<KeyValuePair<K, V>, bool> pred) =>\n        MapModule.ForAll(Value.Root, (k, v) => pred(new KeyValuePair<K, V>(k, v)));\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<V, bool> pred) =>\n        MapModule.ForAll(Value.Root, (_, v) => pred(v));\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<K, V, bool> pred) =>\n        MapModule.Exists(Value.Root, pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<Tuple<K, V>, bool> pred) =>\n        MapModule.Exists(Value.Root, (k, v) => pred(new Tuple<K, V>(k, v)));\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<(K, V), bool> pred) =>\n        MapModule.Exists(Value.Root, (k, v) => pred((k, v)));\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<KeyValuePair<K, V>, bool> pred) =>\n        MapModule.Exists(Value.Root, (k, v) => pred(new KeyValuePair<K, V>(k, v)));\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<V, bool> pred) =>\n        MapModule.Exists(Value.Root, (_, v) => pred(v));\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<K, V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Key, item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<Tuple<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new Tuple<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<(K, V)> action)\n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<KeyValuePair<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new KeyValuePair<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, U> Choose<U>(Func<K, V, Option<U>> selector) =>\n        new (Value.Choose(selector));\n\n    /// <summary>\n    /// Equivalent to map and filter but the filtering is done based on whether the returned\n    /// Option is Some or None.  If the item is None then it's filtered out, if not the the\n    /// mapped Some value is used.\n    /// </summary>\n    /// <param name=\"selector\">Predicate</param>\n    /// <returns>Filtered map</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, U> Choose<U>(Func<V, Option<U>> selector) =>\n        new (Value.Choose(selector));\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        MapModule.Fold(Value.Root, state, folder);\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, V, S> folder) =>\n        MapModule.Fold(Value.Root, state, folder);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called when keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Union(Map<K, V> other, WhenMatched<K, V, V, V> Merge) =>\n        Union(other, (_, v) => v, (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called when keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Union<V2>(Map<K, V2> other, WhenMissing<K, V2, V> MapRight, WhenMatched<K, V, V2, V> Merge) =>\n        Union(other, (_, v) => v, MapRight, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called when keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V2> Union<V2>(Map<K, V2> other, WhenMissing<K, V, V2> MapLeft, WhenMatched<K, V, V2, V2> Merge) =>\n        Union(other, MapLeft, (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  The merge function is called when keys are\n    /// present in both map.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, R> Union<V2, R>(Map<K, V2> other, WhenMissing<K, V, R> MapLeft, WhenMissing<K, V2, R> MapRight, WhenMatched<K, V, V2, R> Merge) =>\n        new (Value.Union(other.Value, MapLeft, MapRight, Merge));\n            \n    /// <summary>\n    /// Intersect two maps.  Only keys that are in both maps are\n    /// returned.  The merge function is called for every resulting\n    /// key.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, R> Intersect<V2, R>(Map<K, V2> other, WhenMatched<K, V, V2, R> Merge) =>\n        new (Value.Intersect(other.Value, Merge));\n\n    /// <summary>\n    /// Map differencing based on key.  this - other.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Except(Map<K, V> other) =>\n        Wrap(Value.Except(other.Value));\n\n    /// <summary>\n    /// Keys that are in both maps are dropped and the remaining\n    /// items are merged and returned.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> SymmetricExcept(Map<K, V> other) =>\n        Wrap(Value.SymmetricExcept(other.Value));\n\n    /// <summary>\n    /// Compare keys and values (values use `OrdDefault〈V〉` for ordering)\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(Map<K, V> other) =>\n        Value.CompareTo<OrdDefault<V>>(other.Value);\n\n    /// <summary>\n    /// Compare keys and values (values use `OrdV` for ordering)\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo<OrdV>(Map<K, V> other) where OrdV : Ord<V> =>\n        Value.CompareTo<OrdV>(other.Value);\n\n    /// <summary>\n    /// Compare keys only\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareKeysTo(Map<K, V> other) =>\n        Value.CompareTo<OrdTrue<V>>(other.Value);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Map<K, V>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Creates a new map from a range/slice of this map\n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Map<K, V> Slice(K keyFrom, K keyTo) =>\n        new(FindRangePairs(keyFrom, keyTo));\n\n    /// <summary>\n    /// Find the lowest ordered item in the map\n    /// </summary>\n    [Pure]\n    public Option<(K Key, V Value)> Min =>\n        Value.Min;\n\n    /// <summary>\n    /// Find the highest ordered item in the map\n    /// </summary>\n    [Pure]\n    public Option<(K Key, V Value)> Max =>\n        Value.Max;\n    \n    [Pure]\n    IEnumerable<K> IReadOnlyDictionary<K, V>.Keys => Keys;\n\n    [Pure]\n    IEnumerable<V> IReadOnlyDictionary<K, V>.Values => Values;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool TryGetValue(K key, out V value)\n    {\n        var v = Find(key);\n        if (v.IsSome)\n        {\n            value = (V)v;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() =>\n        AsIterable().Map(p => new KeyValuePair<K, V>(p.Key, p.Value)).GetEnumerator();\n\n    public static Map<K, V> AdditiveIdentity => \n        Empty;\n   \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Prelude.Collections.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing LSeq = LanguageExt.Seq;\n#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Represents an empty sequence\n    /// </summary>\n    public static readonly SeqEmpty Empty = new();\n\n    /// <summary>\n    /// Construct a sequence from any value\n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Seq<A> Cons<A>(this A head) =>\n        LSeq.FromSingleValue(head);\n\n    /// <summary>\n    /// Construct a sequence from any value\n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Seq<A> Cons<A>(this A head, SeqEmpty empty) =>\n        LSeq.FromSingleValue(head);\n\n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Seq<A> Cons<A>(this A head, Seq<A> tail) =>\n        tail.Cons(head);\n\n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Seq<A> Cons<A>(this A head, A[] tail)\n    {\n        if (tail.Length == 0)\n        {\n            return LSeq.FromSingleValue(head);\n        }\n        else\n        {\n            var data = new A[tail.Length + 1];\n            System.Array.Copy(tail, 0, data, 1, tail.Length);\n            data[0] = head;\n            return LSeq.FromArray(data);\n        }\n    }\n\n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Seq<A> Cons<A>(this A head, IEnumerable<A> tail) =>\n        tail is Seq<A> seq \n            ? head.Cons(seq)\n            : new Seq<A>(tail).Cons(head);\n\n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Iterable<A> Cons<A>(this A head, Iterable<A> tail) =>\n        tail.Cons(head);\n    \n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Iterator<A> Cons<A>(this A head, Iterator<A> tail) =>\n        Iterator.Cons(head, tail);\n\n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Iterator<A> Cons<A>(this A head, Func<Iterator<A>> tail) =>\n        Iterator.Cons(head, tail);\n\n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static IteratorAsync<A> Cons<A>(this A head, IteratorAsync<A> tail) =>\n        IteratorAsync.Cons(head, tail);\n\n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static IteratorAsync<A> Cons<A>(this A head, Func<IteratorAsync<A>> tail) =>\n        IteratorAsync.Cons(head, tail);\n\n    /// <summary>\n    /// Construct a list from head and tail; head becomes the first item in \n    /// the list.  \n    /// </summary>\n    /// <typeparam name=\"A\">Type of the items in the sequence</typeparam>\n    /// <param name=\"head\">Head item in the sequence</param>\n    /// <param name=\"tail\">Tail of the sequence</param>\n    /// <returns></returns>\n    [Pure]\n    public static Lst<A> Cons<A>(this A head, Lst<A> tail) =>\n        tail.Insert(0, head);\n\n    /// <summary>\n    /// Provide a sorted enumerable\n    /// </summary>\n    [Pure]\n    public static IEnumerable<A> Sort<OrdA, A>(this IEnumerable<A> xs) where OrdA : Ord<A> =>\n        xs.OrderBy(identity, OrdComparer<OrdA, A>.Default);\n\n    /// <summary>\n    /// Provide a sorted Seq\n    /// </summary>\n    [Pure]\n    public static Seq<A> Sort<OrdA, A>(this Seq<A> xs) where OrdA : Ord<A> =>\n        xs.OrderBy(identity, OrdComparer<OrdA, A>.Default).AsIterable().ToSeq();\n\n    /// <summary>\n    /// Provide a sorted Lst\n    /// </summary>\n    [Pure]\n    public static Lst<A> Sort<OrdA, A>(this Lst<A> xs) where OrdA : Ord<A> =>\n        xs.OrderBy(identity, OrdComparer<OrdA, A>.Default).AsIterable().ToLst();\n\n    /// <summary>\n    /// Provide a sorted Arr\n    /// </summary>\n    [Pure]\n    public static Arr<A> Sort<OrdA, A>(this Arr<A> xs) where OrdA : Ord<A> =>\n        xs.OrderBy(identity, OrdComparer<OrdA, A>.Default).AsIterable().ToArr();\n\n    /// <summary>\n    /// Provide a sorted array\n    /// </summary>\n    [Pure]\n    public static A[] Sort<OrdA, A>(this A[] xs) where OrdA : Ord<A> =>\n        xs.OrderBy(identity, OrdComparer<OrdA, A>.Default).ToArray();\n\n    /// <summary>\n    /// Forever sequence of units\n    /// </summary>\n    [Pure]\n    public static IterableNE<Unit> Units\n    {\n        get\n        {\n            return IterableNE.create(unit, Go().AsIterable());\n            IEnumerable<Unit> Go()\n            {\n                while (true) yield return default;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Lazy sequence of natural numbers up to Int32.MaxValue\n    /// </summary>\n    [Pure]\n    public static Iterable<int> Naturals\n    {\n        get\n        {\n            return Go().AsIterable();\n            IEnumerable<int> Go()\n            {\n                for (var i = 0; i < int.MaxValue; i++)\n                {\n                    yield return i;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Lazy sequence of natural numbers up to Int64.MaxValue\n    /// </summary>\n    [Pure]\n    public static Iterable<long> LongNaturals\n    {\n        get\n        {\n            return Go().AsIterable();\n            IEnumerable<long> Go()\n            {\n                for (var i = 0L; i < long.MaxValue; i++)\n                {\n                    yield return i;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Lazily generate a range of integers.  \n    /// </summary>\n    [Pure]\n    public static Range<long> Range(long from, long count, long step = 1) =>\n        LanguageExt.Range.fromCount(from, count, step);\n\n    /// <summary>\n    /// Lazily generate a range of integers.  \n    /// </summary>\n    [Pure]\n    public static Range<int> Range(int from, int count, int step = 1) =>\n        LanguageExt.Range.fromCount(from, count, step);\n\n    /// <summary>\n    /// Lazily generate a range of chars.  \n    /// \n    ///   Remarks:\n    ///     Can go in a positive direction ('a'..'z') as well as negative ('z'..'a')\n    /// </summary>\n    [Pure]\n    public static Range<char> Range(char from, char to) =>\n        to >= from\n            ? LanguageExt.Range.fromMinMax(from, to, (char)1)\n            : LanguageExt.Range.fromMinMax(to, from, (char)1) switch\n              {\n                  var r => r with { runRange = r.runRange.Reverse() }\n              };\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<K, V> Map<K, V>() =>\n        LanguageExt.Map.empty<K, V>();\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<K, V> Map<K, V>((K, V) head, params (K, V)[] tail) =>\n        LanguageExt.Map.create(head, tail);\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<K, V> toMap<K, V>(IEnumerable<(K, V)> items) =>\n        LanguageExt.Map.createRange(items);\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<K, V> toMap<K, V>(ReadOnlySpan<(K, V)> items) =>\n        LanguageExt.Map.createRange(items);\n\n\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> Map<OrdK, K, V>() where OrdK : Ord<K> =>\n        LanguageExt.Map.empty<OrdK, K, V>();\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> Map<OrdK, K, V>((K, V) head, params (K, V)[] tail) where OrdK : Ord<K> =>\n        LanguageExt.Map.create<OrdK, K, V>(head, tail);\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> toMap<OrdK, K, V>(IEnumerable<(K, V)> items) where OrdK : Ord<K> =>\n        LanguageExt.Map.createRange<OrdK, K, V>(items);\n\n    /// <summary>\n    /// Create an immutable map\n    /// </summary>\n    [Pure]\n    public static Map<OrdK, K, V> toMap<OrdK, K, V>(ReadOnlySpan<(K, V)> items) where OrdK : Ord<K> =>\n        LanguageExt.Map.createRange<OrdK, K, V>(items);\n\n\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static HashMap<K, V> HashMap<K, V>() =>\n        LanguageExt.HashMap.empty<K, V>();\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static HashMap<K, V> HashMap<K, V>((K, V) head, params (K, V)[] tail) =>\n        LanguageExt.HashMap.create(head, tail);\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static HashMap<K, V> toHashMap<K, V>(IEnumerable<(K, V)> items) =>\n        LanguageExt.HashMap.createRange(items);\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static HashMap<K, V> toHashMap<K, V>(ReadOnlySpan<(K, V)> items) =>\n        LanguageExt.HashMap.createRange(items);\n\n\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static HashMap<EqK, K, V> HashMap<EqK, K, V>() where EqK : Eq<K> =>\n        LanguageExt.HashMap.empty<EqK, K, V>();\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static HashMap<EqK, K, V> HashMap<EqK, K, V>((K, V) head, params (K, V)[] tail) where EqK : Eq<K> =>\n        LanguageExt.HashMap.create<EqK, K, V>(head, tail);\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static HashMap<EqK, K, V> toHashMap<EqK, K, V>(IEnumerable<(K, V)> items) where EqK : Eq<K> =>\n        LanguageExt.HashMap.createRange<EqK, K, V>(items);\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static HashMap<EqK, K, V> toHashMap<EqK, K, V>(ReadOnlySpan<(K, V)> items) where EqK : Eq<K> =>\n        LanguageExt.HashMap.createRange<EqK, K, V>(items);\n\n\n        \n\n\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> TrackingHashMap<K, V>() =>\n        LanguageExt.TrackingHashMap.empty<K, V>();\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> TrackingHashMap<K, V>((K, V) head, params (K, V)[] tail) =>\n        LanguageExt.TrackingHashMap.create(head, tail);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> toTrackingHashMap<K, V>(IEnumerable<(K, V)> items) =>\n        LanguageExt.TrackingHashMap.createRange(items);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> toTrackingHashMap<K, V>(ReadOnlySpan<(K, V)> items) =>\n        LanguageExt.TrackingHashMap.createRange(items);\n\n\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> TrackingHashMap<EqK, K, V>() where EqK : Eq<K> =>\n        LanguageExt.TrackingHashMap.empty<EqK, K, V>();\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> TrackingHashMap<EqK, K, V>((K, V) head, params (K, V)[] tail) where EqK : Eq<K> =>\n        LanguageExt.TrackingHashMap.create<EqK, K, V>(head, tail);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> toTrackingHashMap<EqK, K, V>(IEnumerable<(K, V)> items) where EqK : Eq<K> =>\n        LanguageExt.TrackingHashMap.createRange<EqK, K, V>(items);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> toTrackingHashMap<EqK, K, V>(ReadOnlySpan<(K, V)> items) where EqK : Eq<K> =>\n        LanguageExt.TrackingHashMap.createRange<EqK, K, V>(items);\n\n        \n        \n\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<K, V> AtomHashMap<K, V>() =>\n        LanguageExt.AtomHashMap<K, V>.Empty;\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<K, V> AtomHashMap<K, V>((K, V) head, params (K, V)[] tail) =>\n        LanguageExt.HashMap.create(head, tail).ToAtom();\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<K, V> AtomHashMap<K, V>(HashMap<K, V> items) =>\n        new (items);\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<K, V> toAtomHashMap<K, V>(IEnumerable<(K, V)> items) =>\n        LanguageExt.HashMap.createRange(items).ToAtom();\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<K, V> toAtomHashMap<K, V>(ReadOnlySpan<(K, V)> items) =>\n        LanguageExt.HashMap.createRange(items).ToAtom();\n\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<EqK, K, V> AtomHashMap<EqK, K, V>() where EqK : Eq<K> =>\n        LanguageExt.AtomHashMap<EqK, K, V>.Empty;\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<EqK, K, V> AtomHashMap<EqK, K, V>((K, V) head, params (K, V)[] tail) where EqK : Eq<K> =>\n        LanguageExt.HashMap.create<EqK, K, V>(head, tail).ToAtom();\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<EqK, K, V> AtomHashMap<EqK, K, V>(HashMap<EqK, K, V> items) where EqK : Eq<K> =>\n        new (items);\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<EqK, K, V> toAtomHashMap<EqK, K, V>(IEnumerable<(K, V)> items) where EqK : Eq<K> =>\n        LanguageExt.HashMap.createRange<EqK, K, V>(items).ToAtom();\n\n    /// <summary>\n    /// Create an immutable hash-map\n    /// </summary>\n    [Pure]\n    public static AtomHashMap<EqK, K, V> toAtomHashMap<EqK, K, V>(ReadOnlySpan<(K, V)> items) where EqK : Eq<K> =>\n        LanguageExt.HashMap.createRange<EqK, K, V>(items).ToAtom();\n\n    /// <summary>\n    /// Create an immutable list\n    /// </summary>\n    [Pure]\n    public static Lst<T> List<T>() =>\n        Lst<T>.Empty;\n\n    /// <summary>\n    /// Create an immutable list\n    /// </summary>\n    [Pure]\n    public static Lst<T> List<T>(T x, params T[] xs)\n    {\n        return new Lst<T>(Yield());\n\n        IEnumerable<T> Yield()\n        {\n            yield return x;\n            foreach(var item in xs)\n            {\n                yield return item;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Create an immutable list\n    /// </summary>\n    [Pure]\n    public static Lst<T> toList<T>(Arr<T> items) =>\n        new (items.AsSpan());\n\n    /// <summary>\n    /// Create an immutable list\n    /// </summary>\n    [Pure]\n    public static Lst<T> toList<T>(IEnumerable<T> items) =>\n        items is Lst<T> lst\n            ? lst\n            : new Lst<T>(items);\n\n    /// <summary>\n    /// Create an immutable list\n    /// </summary>\n    [Pure]\n    public static Lst<T> toList<T>(ReadOnlySpan<T> items) =>\n        new (items);\n\n\n    /// <summary>\n    /// Create an immutable array\n    /// </summary>\n    [Pure]\n    public static Arr<T> Array<T>() =>\n        Arr<T>.Empty;\n\n    /// <summary>\n    /// Create an immutable array\n    /// </summary>\n    [Pure]\n    public static Arr<T> Array<T>(T x, params T[] xs) =>\n        new (x.Cons(xs).ToArray());\n\n    /// <summary>\n    /// Create an immutable array\n    /// </summary>\n    [Pure]\n    public static Arr<T> toArray<T>(IEnumerable<T> items) =>\n        items is Arr<T> arr\n            ? arr\n            : new Arr<T>(items);\n\n    /// <summary>\n    /// Create an immutable array\n    /// </summary>\n    [Pure]\n    public static Arr<T> toArray<T>(ReadOnlySpan<T> items) =>\n        new (items);\n\n    /// <summary>\n    /// Create an immutable queue\n    /// </summary>\n    [Pure]\n    public static Que<T> Queue<T>() =>\n        Que<T>.Empty;\n\n    /// <summary>\n    /// Create an immutable queue\n    /// </summary>\n    [Pure]\n    public static Que<T> Queue<T>(params T[] items)\n    {\n        var q = new QueInternal<T>();\n        foreach (var item in items)\n        {\n            q = q.Enqueue(item);\n        }\n        return new Que<T>(q);\n    }\n\n    /// <summary>\n    /// Create an immutable queue\n    /// </summary>\n    [Pure]\n    public static Que<T> toQueue<T>(IEnumerable<T> items) =>\n        new (items);\n\n    /// <summary>\n    /// Create an immutable queue\n    /// </summary>\n    [Pure]\n    public static Que<T> toQueue<T>(ReadOnlySpan<T> items) =>\n        new (items);\n\n    /// <summary>\n    /// Create an immutable stack\n    /// </summary>\n    [Pure]\n    public static Stck<T> Stack<T>() =>\n        new ();\n\n    /// <summary>\n    /// Create an immutable stack\n    /// </summary>\n    [Pure]\n    public static Stck<T> Stack<T>(params T[] items) =>\n        new (items.AsSpan());\n\n    /// <summary>\n    /// Create an immutable stack\n    /// </summary>\n    [Pure]\n    public static Stck<T> toStack<T>(IEnumerable<T> items) =>\n        items is Stck<T> s\n            ? s\n            : new Stck<T>(items);\n\n    /// <summary>\n    /// Create an immutable stack\n    /// </summary>\n    [Pure]\n    public static Stck<T> toStackRev<T>(IEnumerable<T> items) =>\n        new (items.Reverse());\n\n    /// <summary>\n    /// Create an immutable map, updating duplicates so that the final value of any key is retained\n    /// </summary>\n    [Pure]\n    public static Map<K, V> toMapUpdate<K, V>(IEnumerable<(K, V)> keyValues) =>\n        new(keyValues, false);\n\n    /// <summary>\n    /// Create an immutable map, updating duplicates so that the final value of any key is retained\n    /// </summary>\n    [Pure]\n    public static Map<K, V> toMapUpdate<K, V>(ReadOnlySpan<(K, V)> keyValues) =>\n        new(keyValues, false);\n\n    /// <summary>\n    /// Create an immutable map, ignoring duplicates so the first value of any key is retained\n    /// </summary>\n    [Pure]\n    public static Map<K, V> toMapTry<K, V>(IEnumerable<(K, V)> keyValues) =>\n        new(keyValues, false);\n\n    /// <summary>\n    /// Create an immutable map, ignoring duplicates so the first value of any key is retained\n    /// </summary>\n    [Pure]\n    public static Map<K, V> toMapTry<K, V>(ReadOnlySpan<(K, V)> keyValues) =>\n        new(keyValues, false);\n\n\n\n    /// <summary>\n    /// Create an immutable set\n    /// </summary>\n    [Pure]\n    public static Set<T> Set<T>() =>\n        LanguageExt.Set.create<T>();\n\n    /// <summary>\n    /// Create an immutable set\n    /// </summary>\n    [Pure]\n    public static Set<T> Set<T>(T head, params T[] tail) =>\n        LanguageExt.Set.createRange(head.Cons(tail));\n\n    /// <summary>\n    /// Create an immutable set\n    /// </summary>\n    [Pure]\n    public static Set<T> toSet<T>(IEnumerable<T> items) =>\n        items is Set<T> s\n            ? s\n            : LanguageExt.Set.createRange(items);\n\n    /// <summary>\n    /// Create an immutable set\n    /// </summary>\n    [Pure]\n    public static Set<T> toSet<T>(ReadOnlySpan<T> items) =>\n        LanguageExt.Set.createRange(items);\n\n\n\n    /// <summary>\n    /// Create an immutable set\n    /// </summary>\n    [Pure]\n    public static Set<OrdT, T> Set<OrdT, T>() where OrdT : Ord<T> =>\n        LanguageExt.Set.create<OrdT, T>();\n\n    /// <summary>\n    /// Create an immutable set\n    /// </summary>\n    [Pure]\n    public static Set<OrdT, T> Set<OrdT, T>(T head, params T[] tail) where OrdT : Ord<T> =>\n        LanguageExt.Set.createRange<OrdT, T>(head.Cons(tail));\n\n    /// <summary>\n    /// Create an immutable set\n    /// </summary>\n    [Pure]\n    public static Set<OrdT, T> toSet<OrdT, T>(IEnumerable<T> items) where OrdT : Ord<T> =>\n        items is Set<OrdT, T> s\n            ? s\n            : LanguageExt.Set.createRange<OrdT, T>(items);\n\n    /// <summary>\n    /// Create an immutable set\n    /// </summary>\n    [Pure]\n    public static Set<OrdT, T> toSet<OrdT, T>(ReadOnlySpan<T> items) where OrdT : Ord<T> =>\n        LanguageExt.Set.createRange<OrdT, T>(items);\n\n\n    /// <summary>\n    /// Create an immutable hash-set\n    /// </summary>\n    [Pure]\n    public static HashSet<T> HashSet<T>() =>\n        LanguageExt.HashSet.create<T>();\n\n    /// <summary>\n    /// Create an immutable hash-set\n    /// </summary>\n    [Pure]\n    public static HashSet<T> HashSet<T>(T head, params T[] tail) =>\n        LanguageExt.HashSet.createRange(head.Cons(tail));\n\n    /// <summary>\n    /// Create an immutable hash-set\n    /// </summary>\n    [Pure]\n    public static HashSet<T> toHashSet<T>(IEnumerable<T> items) =>\n        items is HashSet<T> hs\n            ? hs\n            : LanguageExt.HashSet.createRange(items);\n\n    /// <summary>\n    /// Create an immutable hash-set\n    /// </summary>\n    [Pure]\n    public static HashSet<T> toHashSet<T>(ReadOnlySpan<T> items) =>\n        LanguageExt.HashSet.createRange(items);\n\n\n\n    /// <summary>\n    /// Create an immutable hash-set\n    /// </summary>\n    [Pure]\n    public static HashSet<EqT, T> HashSet<EqT, T>() where EqT : Eq<T> =>\n        LanguageExt.HashSet.create<EqT, T>();\n\n    /// <summary>\n    /// Create an immutable hash-set\n    /// </summary>\n    [Pure]\n    public static HashSet<EqT, T> HashSet<EqT, T>(T head, params T[] tail) where EqT : Eq<T> =>\n        LanguageExt.HashSet.createRange<EqT, T>(head.Cons(tail));\n\n    /// <summary>\n    /// Create an immutable hash-set\n    /// </summary>\n    [Pure]\n    public static HashSet<EqT, T> toHashSet<EqT, T>(IEnumerable<T> items) where EqT : Eq<T> =>\n        items is HashSet<EqT, T> hs\n            ? hs\n            : LanguageExt.HashSet.createRange<EqT, T>(items);\n\n    /// <summary>\n    /// Create an immutable hash-set\n    /// </summary>\n    [Pure]\n    public static HashSet<EqT, T> toHashSet<EqT, T>(ReadOnlySpan<T> items) where EqT : Eq<T> =>\n        LanguageExt.HashSet.createRange<EqT, T>(items);\n\n\n\n\n    /// <summary>\n    /// Create a queryable\n    /// </summary>\n    [Pure]\n    public static IQueryable<T> Query<T>(params T[] items) =>\n        toQuery(items);\n\n    /// <summary>\n    /// Convert to queryable\n    /// </summary>\n    [Pure]\n    public static IQueryable<T> toQuery<T>(IEnumerable<T> items) =>\n        items.AsQueryable();\n\n    /// <summary>\n    /// Match empty list, or multi-item list\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"More\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    public static B match<A, B>(IEnumerable<A> list,\n                                Func<B> Empty,\n                                Func<Seq<A>, B> More) =>\n        toSeq(list).Match(Empty, More);\n\n    /// <summary>\n    /// List pattern matching\n    /// </summary>\n    [Pure]\n    public static B match<A, B>(IEnumerable<A> list,\n                                Func<B> Empty,\n                                Func<A, Seq<A>, B> More) =>\n        toSeq(list).Match(Empty, More);\n\n    /// <summary>\n    /// List pattern matching\n    /// </summary>\n    [Pure]\n    public static R match<T, R>(IEnumerable<T> list,\n                                Func<R> Empty,\n                                Func<T, R> One,\n                                Func<T, Seq<T>, R> More) =>\n        toSeq(list).Match(Empty, One, More);\n\n    [Pure]\n    public static R match<K, V, R>(Map<K, V> map, K key, Func<V, R> Some, Func<R> None) =>\n        match(LanguageExt.Map.find(map, key),\n              Some,\n              None );\n\n    public static Unit match<K, V>(Map<K, V> map, K key, Action<V> Some, Action None) =>\n        match(LanguageExt.Map.find(map, key),\n              Some,\n              None);\n\n    [Pure]\n    public static R match<K, V, R>(HashMap<K, V> map, K key, Func<V, R> Some, Func<R> None) =>\n        match(LanguageExt.HashMap.find(map, key),\n              Some,\n              None);\n\n    public static Unit match<K, V>(HashMap<K, V> map, K key, Action<V> Some, Action None) =>\n        match(LanguageExt.HashMap.find(map, key),\n              Some,\n              None);\n    \n    /// <summary>\n    /// Construct an empty Iterable\n    /// </summary>\n    [Pure]\n    public static Iterable<A> Iterable<A>() =>\n        LanguageExt.Iterable<A>.Empty;\n        \n    /// <summary>\n    /// Construct a sequence from an Enumerable\n    /// </summary>\n    [Pure]\n    public static Iterable<A> Iterable<A>(ReadOnlySpan<A> value) =>\n        LanguageExt.Iterable<A>.FromSpan(value);\n\n    /// <summary>\n    /// Construct a sequence from an Enumerable\n    /// </summary>\n    [Pure]\n    public static Iterable<A> Iterable<A>(A fst, A snd, params A[] rest)\n    {\n        return new IterableEnumerable<A>(IO.pure(Yield()));\n        IEnumerable<A> Yield()\n        {\n            yield return fst;\n            yield return snd;\n            foreach (var value in rest)\n            {\n                yield return value;\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Construct a sequence from an Enumerable\n    /// Deals with `value == null` by returning `[]` and also memoizes the\n    /// items in the enumerable as they're being consumed.\n    /// </summary>\n    [Pure]\n    public static Iterable<A> Iterable<A>(IEnumerable<A>? value) =>\n        value switch\n        {\n            null                => LanguageExt.Iterable<A>.Empty,\n            Iterable<A> iter    => iter, \n            Seq<A> seq          => seq.AsIterable(),\n            Arr<A> arr          => arr.AsIterable(),\n            A[] array           => Iterable(array),\n            _                   => new IterableEnumerable<A>(IO.pure(value))\n        };\n    \n    [Pure]\n    public static Iterable<A> Iterable<A>(IAsyncEnumerable<A>? value) =>\n        value switch\n        {\n            null             => LanguageExt.Iterable<A>.Empty,\n            _                => new IterableAsyncEnumerable<A>(IO.pure(value))\n        };\n\n    /// <summary>\n    /// Construct an empty Seq\n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>() =>\n        Empty;\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq1(124);\n    /// \n    /// </summary>\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiserSeq)]\n    public static Seq<A> Seq1<A>(A value)\n    {\n        var arr = new A[4];\n        arr[2] = value;\n        return new Seq<A>(new SeqStrict<A>(arr, 2, 1, 0, 0));\n    }\n       \n    /// <summary>\n    /// Construct a singleton sequence from any value\n    ///\n    ///     var list = Seq(1);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A value)\n    {\n        var arr = new A[4];\n        arr[2] = value;\n        return new Seq<A>(new SeqStrict<A>(arr, 2, 1, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq(1, 2);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A a, A b)\n    {\n        var arr = new A[4];\n        arr[2] = a;\n        arr[3] = b;\n        return new Seq<A>(new SeqStrict<A>(arr, 2, 2, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq(1, 2, 3);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A a, A b, A c)\n    {\n        var arr = new A[8];\n        arr[2] = a;\n        arr[3] = b;\n        arr[4] = c;\n        return new Seq<A>(new SeqStrict<A>(arr, 2, 3, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq(1, 2, 3, 4);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A a, A b, A c, A d)\n    {\n        var arr = new A[8];\n        arr[2] = a;\n        arr[3] = b;\n        arr[4] = c;\n        arr[5] = d;\n        return new Seq<A>(new SeqStrict<A>(arr, 2, 4, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq(1, 2, 3, 4, 5);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A a, A b, A c, A d, A e)\n    {\n        var arr = new A[8];\n        arr[2] = a;\n        arr[3] = b;\n        arr[4] = c;\n        arr[5] = d;\n        arr[6] = e;\n        return new Seq<A>(new SeqStrict<A>(arr, 2, 5, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq(1, 2, 3, 4, 5, 6);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A a, A b, A c, A d, A e, A f)\n    {\n        var arr = new A[16];\n        arr[4] = a;\n        arr[5] = b;\n        arr[6] = c;\n        arr[7] = d;\n        arr[8] = e;\n        arr[9] = f;\n        return new Seq<A>(new SeqStrict<A>(arr, 4, 6, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq(1, 2, 3, 4, 5, 6, 7);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A a, A b, A c, A d, A e, A f, A g)\n    {\n        var arr = new A[16];\n        arr[4] = a;\n        arr[5] = b;\n        arr[6] = c;\n        arr[7] = d;\n        arr[8] = e;\n        arr[9] = f;\n        arr[10] = g;\n        return new Seq<A>(new SeqStrict<A>(arr, 4, 7, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq(1, 2, 3, 4, 5, 6, 7, 8);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A a, A b, A c, A d, A e, A f, A g, A h)\n    {\n        var arr = new A[16];\n        arr[4]  = a;\n        arr[5]  = b;\n        arr[6]  = c;\n        arr[7]  = d;\n        arr[8]  = e;\n        arr[9]  = f;\n        arr[10] = g;\n        arr[11] = h;\n        return new Seq<A>(new SeqStrict<A>(arr, 4, 8, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from any value\n    ///\n    ///     var list = Seq(1, 2, 3, 4);\n    /// \n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(A a, A b, A c, A d, A e, A f, A g, A h, params A[] tail)\n    {\n        var arr = new A[16 + tail.Length];\n        arr[4]  = a;\n        arr[5]  = b;\n        arr[6]  = c;\n        arr[7]  = d;\n        arr[8]  = e;\n        arr[9]  = f;\n        arr[10] = g;\n        arr[11] = h;\n\n        System.Array.Copy(tail, 0, arr, 12, tail.Length);\n        return new Seq<A>(new SeqStrict<A>(arr, 4, 8 + tail.Length, 0, 0));\n    }\n        \n    /// <summary>\n    /// Construct a sequence from an Enumerable\n    /// Deals with `value == null` by returning `[]` and also memoizes the\n    /// items in the enumerable as they're being consumed.\n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(ReadOnlySpan<A> value) =>\n        new (value);\n        \n    /// <summary>\n    /// Construct a sequence from an Enumerable\n    /// Deals with `value == null` by returning `[]` and also memoizes the\n    /// items in the enumerable as they're being consumed.\n    /// </summary>\n    [Pure]\n    public static Seq<A> Seq<A>(IEnumerable<A>? value) =>\n        value switch\n        {\n            null                => Empty,\n            Seq<A> seq          => seq,\n            Arr<A> arr          => toSeq(arr),\n            A[] array           => toSeq(array),\n            IList<A> list       => toSeq(list),\n            ICollection<A> coll => toSeq(coll),\n            _                   => new Seq<A>(value)\n        };\n\n    /// <summary>\n    /// Construct a sequence from an Enumerable\n    /// Deals with `value == null` by returning `[]` and also memoizes the\n    /// items in the enumerable as they're being consumed.\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(IEnumerable<A>? value) =>\n        value switch\n        {\n            null                => Empty,\n            Seq<A> seq          => seq,\n            Arr<A> arr          => toSeq(arr.ToArray()),\n            A[] array           => toSeq(array),\n            IList<A> list       => toSeq(list),\n            ICollection<A> coll => toSeq(coll),\n            _                   => new Seq<A>(value)\n        };\n        \n    /// <summary>\n    /// Construct a sequence from a nullable\n    ///     HasValue == true  : [x]\n    ///     HasValue == false : []\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(A? value) where A : struct =>\n        value is null \n            ? Empty \n            : LSeq.FromSingleValue(value.Value);\n        \n    /// <summary>\n    /// Construct a sequence from an array\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(A[]? value)\n    {\n        if (value is null || value.Length == 0)\n        {\n            return Empty;\n        }\n        else\n        {\n            var length = value.Length;\n            var data   = new A[length];\n            System.Array.Copy(value, data, length);\n            return LSeq.FromArray(data);\n        }\n    }\n\n    /// <summary>\n    /// Construct a sequence from a list\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(IList<A>? value) =>\n        toSeq(value?.ToArray());\n\n    /// <summary>\n    /// Construct a sequence from a list\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(ICollection<A>? value) =>\n        toSeq(value?.ToArray());\n\n    /// <summary>\n    /// Construct a sequence from an either\n    ///     Right(x) : [x]\n    ///     Left(y)  : []\n    /// </summary>\n    [Pure]\n    public static Seq<R> toSeq<L, R>(Either<L, R> value) =>\n        value.IsRight\n            ? LSeq.FromSingleValue(value.RightValue)\n            : Empty;\n\n    /// <summary>\n    /// Construct a sequence from a tuple\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(ValueTuple<A> tup) =>\n        [tup.Item1];\n\n    /// <summary>\n    /// Construct a sequence from a tuple\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(ValueTuple<A, A> tup) =>\n        [tup.Item1, tup.Item2];\n\n    /// <summary>\n    /// Construct a sequence from a tuple\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(ValueTuple<A, A, A> tup) =>\n        [tup.Item1, tup.Item2, tup.Item3];\n\n    /// <summary>\n    /// Construct a sequence from a tuple\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(ValueTuple<A, A, A, A> tup) =>\n        [tup.Item1, tup.Item2, tup.Item3, tup.Item4];\n\n    /// <summary>\n    /// Construct a sequence from a tuple\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(ValueTuple<A, A, A, A, A> tup) =>\n        [tup.Item1, tup.Item2, tup.Item3, tup.Item4, tup.Item5];\n\n    /// <summary>\n    /// Construct a sequence from a tuple\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(ValueTuple<A, A, A, A, A, A> tup) =>\n        [tup.Item1, tup.Item2, tup.Item3, tup.Item4, tup.Item5, tup.Item6];\n\n    /// <summary>\n    /// Construct a sequence from a tuple\n    /// </summary>\n    [Pure]\n    public static Seq<A> toSeq<A>(ValueTuple<A, A, A, A, A, A, A> tup) =>\n        [tup.Item1, tup.Item2, tup.Item3, tup.Item4, tup.Item5, tup.Item6, tup.Item7];\n\n    /// <summary>\n    /// Construct an empty AtomSeq\n    /// </summary>\n    [Pure]\n    public static AtomSeq<A> AtomSeq<A>() =>\n        new (SeqStrict<A>.Empty);\n\n    /// <summary>\n    /// Construct an AtomSeq\n    /// </summary>\n    [Pure]\n    public static AtomSeq<A> AtomSeq<A>(params A[] items) =>\n        new (LSeq.FromArray(items).Value);\n\n    /// <summary>\n    /// Construct an AtomSeq\n    /// </summary>\n    [Pure]\n    public static AtomSeq<A> AtomSeq<A>(Seq<A> items) =>\n        new (items.Value);\n\n    /// <summary>\n    /// Construct an AtomSeq\n    /// </summary>\n    [Pure]\n    public static AtomSeq<A> AtomSeq<A>(IEnumerable<A> items) =>\n        new (items);\n\n    /// <summary>\n    /// Compute the difference between two documents, using the Wagner-Fischer algorithm. \n    /// O(mn) time and space.\n    /// \n    ///     apply(diff(d,e), d) == e\n    ///     \n    ///     diff(d, d) == Patch.empty\n    ///     \n    ///     apply(diff(d, e), d) == apply(inverse(diff(e, d)), d)\n    ///     \n    ///     apply(append(diff(a, b), diff(b, c), a) == apply(diff(a, c), a)\n    ///     \n    ///     applicable(diff(a, b) a)\n    /// \n    /// </summary>\n    public static Patch<EqA, A> Diff<EqA, A>(this IEnumerable<A> va, IEnumerable<A> vb) where EqA : Eq<A> =>\n        Patch.diff<EqA, A>(va, vb);\n\n    /// <summary>\n    /// Apply the supplied patch to this collection\n    /// </summary>\n    public static IEnumerable<A> Apply<EqA, A>(this IEnumerable<A> va, Patch<EqA, A> patch) where EqA : Eq<A> =>\n        Patch.apply(patch, va);\n\n    /// <summary>\n    /// Apply the supplied patch to this collection\n    /// </summary>\n    public static Lst<A> Apply<EqA, A>(this Lst<A> va, Patch<EqA, A> patch) where EqA : Eq<A> =>\n        Patch.apply(patch, va);\n\n    /// <summary>\n    /// Apply the supplied patch to this collection\n    /// </summary>\n    public static Seq<A> Apply<EqA, A>(this Seq<A> va, Patch<EqA, A> patch) where EqA : Eq<A> =>\n        Patch.apply(patch, va);\n\n    /// <summary>\n    /// Apply the supplied patch to this collection\n    /// </summary>\n    public static SpanArray<A> Apply<EqA, A>(this SpanArray<A> va, Patch<EqA, A> patch) where EqA : Eq<A> =>\n        Patch.apply(patch, va);\n\n    /// <summary>\n    /// Apply the supplied patch to this collection\n    /// </summary>\n    public static A[] Apply<EqA, A>(this A[] va, Patch<EqA, A> patch) where EqA : Eq<A> =>\n        Patch.apply(patch, va);\n\n    /// <summary>\n    /// Apply the supplied patch to this collection\n    /// </summary>\n    public static Arr<A> Apply<EqA, A>(this Arr<A> va, Patch<EqA, A> patch) where EqA : Eq<A> =>\n        Patch.apply(patch, va);\n\n    /// <summary>\n    /// Apply the supplied patch to this collection\n    /// </summary>\n    public static List<A> Apply<EqA, A>(this List<A> va, Patch<EqA, A> patch) where EqA : Eq<A> =>\n        Patch.apply(patch, va);\n\n    /// <summary>\n    /// Returns true if a patch can be safely applied to a document, that is,\n    /// `applicable(p, d)` holds when `d` is a valid source document for the patch `p`.\n    /// </summary>\n    public static bool Applicable<EqA, A>(this IEnumerable<A> va, Patch<EqA, A> patch) where EqA : Eq<A> =>\n        Patch.applicable(patch, va);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Queue/Que.Internal.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n[Serializable]\ninternal class QueInternal<A> : IEnumerable<A>\n{\n    public static readonly QueInternal<A> Empty = new ();\n\n    readonly StckInternal<A> forward;\n    readonly StckInternal<A> backward;\n    StckInternal<A>? backwardRev;\n    int hashCode;\n\n    internal QueInternal()\n    {\n        forward = StckInternal<A>.Empty;\n        backward = StckInternal<A>.Empty;\n    }\n\n    internal QueInternal(IEnumerable<A> items)\n    {\n        var q = new QueInternal<A>();\n        foreach(var item in items)\n        {\n            q = q.Enqueue(item);\n        }\n        forward = q.forward;\n        backward = q.backward;\n        backwardRev = q.backwardRev;\n    }\n\n    internal QueInternal(ReadOnlySpan<A> items)\n    {\n        var q = new QueInternal<A>();\n        foreach(var item in items)\n        {\n            q = q.Enqueue(item);\n        }\n        forward = q.forward;\n        backward = q.backward;\n        backwardRev = q.backwardRev;\n    }\n\n    private QueInternal(StckInternal<A> f, StckInternal<A> b)\n    {\n        forward = f;\n        backward = b;\n    }\n\n    private StckInternal<A> BackwardRev =>\n        backwardRev ??= backward.Reverse();\n\n    [Pure]\n    public int Count =>\n        forward.Count + backward.Count;\n\n    [Pure]\n    public bool IsEmpty =>\n        forward.IsEmpty && backward.IsEmpty;\n\n    [Pure]\n    public QueInternal<A> Clear() =>\n        Empty;\n\n    [Pure]\n    public A Peek() =>\n        forward.Peek();\n\n    [Pure]\n    public QueInternal<A> Dequeue()\n    {\n        var f = forward.Pop();\n        if (!f.IsEmpty)\n        {\n            return new QueInternal<A>(f, backward);\n        }\n        if (backward.IsEmpty)\n        {\n            return Empty;\n        }\n        return new QueInternal<A>(BackwardRev, StckInternal<A>.Empty);\n    }\n\n    [Pure]\n    public QueInternal<A> Dequeue(out A outValue)\n    {\n        outValue = Peek();\n        return Dequeue();\n    }\n\n    [Pure]\n    public (QueInternal<A>, Option<A>) TryDequeue() =>\n        forward.TryPeek().Match(\n            Some: x => (Dequeue(), Some(x)),\n            None: () => (this, Option<A>.None)\n        );\n\n    [Pure]\n    public Option<A> TryPeek() =>\n        forward.TryPeek();\n\n    [Pure]\n    public QueInternal<A> Enqueue(A value) =>\n        IsEmpty\n            ? new QueInternal<A>(StckInternal<A>.Empty.Push(value), StckInternal<A>.Empty)\n            : new QueInternal<A>(forward, backward.Push(value));\n\n    [Pure]\n    public Seq<A> ToSeq() =>\n        toSeq(forward.AsIterable().ConcatFast(BackwardRev));\n\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        forward.AsIterable().ConcatFast(BackwardRev);\n\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        forward.AsIterable().ConcatFast(BackwardRev).GetEnumerator();\n\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        forward.AsIterable().ConcatFast(BackwardRev).GetEnumerator();\n\n    [Pure]\n    public static QueInternal<A> operator +(QueInternal<A> lhs, QueInternal<A> rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure]\n    public QueInternal<A> Combine(QueInternal<A> rhs)\n    {\n        var self = this;\n        foreach (var item in rhs)\n        {\n            self = self.Enqueue(item);\n        }\n        return self;\n    }\n\n    [Pure]\n    public override int GetHashCode() =>\n        hashCode == 0\n            ? hashCode = FNV32.Hash<HashableDefault<A>, A>(this)\n            : hashCode;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Queue/Que.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable queue collection\n/// </summary>\n/// <typeparam name=\"A\">Item value type</typeparam>\n[Serializable]\n[CollectionBuilder(typeof(Queue), nameof(Queue.createRange))]\npublic readonly struct Que<A> : \n    IEnumerable<A>, \n    IEquatable<Que<A>>\n{\n    public static readonly Que<A> Empty = new (QueInternal<A>.Empty);\n\n    readonly QueInternal<A> value;\n    internal QueInternal<A> Value => value ?? QueInternal<A>.Empty;\n\n    internal Que(QueInternal<A> value) =>\n        this.value = value;\n\n    /// <summary>\n    /// Construct from a enumerable of items\n    /// </summary>\n    /// <param name=\"items\">Items to construct the queue from</param>\n    public Que(IEnumerable<A> items) =>\n        value = new QueInternal<A>(items);\n\n    /// <summary>\n    /// Construct from a enumerable of items\n    /// </summary>\n    /// <param name=\"items\">Items to construct the queue from</param>\n    public Que(ReadOnlySpan<A> items) =>\n        value = new QueInternal<A>(items);\n\n    /// <summary>\n    /// Impure iteration of the bound value in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Que<A> Do(Action<A> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = null\n    ///     Singleton collection = A\n    ///     More                 = (A, Seq〈A〉)   -- head and tail\n    ///\n    ///     var res = list.Case switch\n    ///     {\n    ///       \n    ///        (var x, var xs) => ...,\n    ///        A value         => ...,\n    ///        _               => ...\n    ///     }\n    /// \n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty\n            ? null\n            : toSeq(Value).Case;\n\n    /// <summary>\n    /// Is the queue empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the queue\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Returns an empty queue \n    /// </summary>\n    /// <returns>Empty queue</returns>\n    [Pure]\n    public Que<A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Look at the item at the front of the queue\n    /// </summary>\n    /// <exception cref=\"ExpectedException\">Throws if the queue is empty</exception>\n    /// <returns>The item at the front of the queue, or throw an exception if none exists</returns>\n    [Pure]\n    public A Peek() =>\n        Value.Peek();\n\n    /// <summary>\n    /// Removes the item from the front of the queue\n    /// </summary>\n    /// <returns>A new `Que` with the first item removed</returns>\n    [Pure]\n    public Que<A> Dequeue() =>\n        new (Value.Dequeue());\n\n    /// <summary>\n    /// Removes the item from the front of the queue\n    /// </summary>\n    /// <exception cref=\"ExpectedException\">Throws if the queue is empty</exception>\n    /// <returns>A tuple containing the new `Que` with the first item removed and the first item</returns>\n    [Pure]\n    public (Que<A> Queue, A Value) DequeueUnsafe() =>\n        (Dequeue(), Peek());\n\n    /// <summary>\n    /// Removes the item from the front of the queue\n    /// </summary>\n    /// <returns>A tuple containing the new `Que` with the first item removed and optionally the first item</returns>\n    [Pure]\n    public (Que<A> Queue, Option<A> Value) TryDequeue() =>\n        Value.TryDequeue().MapFirst(qi => new Que<A>(qi));\n\n    /// <summary>\n    /// Look at the item at the front of the queue, if it exists.  \n    /// </summary>\n    /// <returns>The item at the front of the queue, if it exists.  `None` otherwise.</returns>\n    [Pure]\n    public Option<A> TryPeek() =>\n        Value.TryPeek();\n\n    /// <summary>\n    /// Add an item to the end of the queue\n    /// </summary>\n    /// <param name=\"value\">Value to add to the queue</param>\n    /// <returns>A new queue with the item added</returns>\n    [Pure]\n    public Que<A> Enqueue(A value) =>\n        new (Value.Enqueue(value));\n\n    /// <summary>\n    /// Convert to a `Seq`\n    /// </summary>\n    /// <returns>`Seq`</returns>\n    [Pure]\n    public Seq<A> ToSeq() =>\n        Value.ToSeq();\n\n    /// <summary>\n    /// Convert to an `IEnumerable`\n    /// </summary>\n    /// <returns>`IEnumerable`</returns>\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        Value.AsIterable();\n\n    /// <summary>\n    /// Get an enumerator of the collection\n    /// </summary>\n    /// <returns>`IEnumerator`</returns>\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        AsIterable().GetEnumerator();\n\n    /// <summary>\n    /// Get an enumerator of the collection\n    /// </summary>\n    /// <returns>`IEnumerator`</returns>\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        AsIterable().GetEnumerator();\n\n    /// <summary>\n    /// Append two queues together\n    /// </summary>\n    /// <param name=\"lhs\">First part of the queue</param>\n    /// <param name=\"rhs\">Second part of the queue</param>\n    /// <returns>Concatenated queue</returns>\n    [Pure]\n    public static Que<A> operator +(Que<A> lhs, Que<A> rhs) =>\n        lhs.Combine(rhs);\n\n    /// <summary>\n    /// Append two queues together\n    /// </summary>\n    /// <param name=\"rhs\">Second part of the queue</param>\n    /// <returns>Concatenated queue</returns>\n    [Pure]\n    public Que<A> Combine(Que<A> rhs) =>\n        new(IterableExtensions.AsIterable(Value).Combine(IterableExtensions.AsIterable(rhs)));\n\n    /// <summary>\n    /// Subtract one queue from another\n    /// </summary>\n    /// <param name=\"lhs\">Starting queue</param>\n    /// <param name=\"rhs\">Items to remove from the queue</param>\n    /// <returns>lhs - rhs</returns>\n    [Pure]\n    public static Que<A> operator -(Que<A> lhs, Que<A> rhs) =>\n        lhs.Subtract(rhs);\n\n    /// <summary>\n    /// Subtract one queue from another\n    /// </summary>\n    /// <param name=\"rhs\">Items to remove from the queue</param>\n    /// <returns>lhs - rhs</returns>\n    [Pure]\n    public Que<A> Subtract(Que<A> rhs) =>\n        new (Enumerable.Except(Value.AsIterable(), rhs.Value.AsIterable()));\n\n    /// <summary>\n    /// Queue equality\n    /// </summary>\n    /// <param name=\"lhs\">First queue</param>\n    /// <param name=\"rhs\">Second queue</param>\n    /// <returns>`true` if the queues are equal</returns>\n    [Pure]\n    public static bool operator ==(Que<A> lhs, Que<A> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Queue inequality\n    /// </summary>\n    /// <param name=\"lhs\">First queue</param>\n    /// <param name=\"rhs\">Second queue</param>\n    /// <returns>`true` if the queues are not-equal</returns>\n    [Pure]\n    public static bool operator !=(Que<A> lhs, Que<A> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Hash code of the items in the queue\n    /// </summary>\n    /// <returns>Hash code</returns>\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    /// <summary>\n    /// Queue equality\n    /// </summary>\n    /// <param name=\"obj\">Value that may be a queue</param>\n    /// <returns>`true` if the queues are equal</returns>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is Que<A> q && Equals(q);\n\n    /// <summary>\n    /// Queue equality\n    /// </summary>\n    /// <param name=\"other\">Second queue</param>\n    /// <returns>`true` if the queues are equal</returns>\n    [Pure]\n    public bool Equals(Que<A> other) =>\n        GetHashCode() == other.GetHashCode() &&\n        EqEnumerable<A>.Equals(Value, other.Value);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    public static implicit operator Que<A>(SeqEmpty _) =>\n        Empty;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Queue/Queue.Module.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class Queue\n{\n    [Pure]\n    public static Que<T> singleton<T>(T item) =>\n        [item];\n    \n    [Pure]\n    public static Que<T> createRange<T>(IEnumerable<T> items) =>\n        new (items);\n    \n    [Pure]\n    public static Que<T> createRange<T>(ReadOnlySpan<T> items) =>\n        items.IsEmpty\n            ? Que<T>.Empty\n            : new (items);\n\n    [Pure]\n    public static Que<T> enq<T>(Que<T> queue, T value) =>\n        queue.Enqueue(value);\n\n    [Pure]\n    public static (Que<T> Queue, T Value) deqUnsafe<T>(Que<T> queue) =>\n        queue.DequeueUnsafe();\n\n    [Pure]\n    public static (Que<T> Queue, Option<T> Value) deq<T>(Que<T> queue) =>\n        queue.TryDequeue();\n\n    [Pure]\n    public static T peekUnsafe<T>(Que<T> queue) =>\n        queue.Peek();\n\n    [Pure]\n    public static Option<T> peek<T>(Que<T> queue) =>\n        queue.TryPeek();\n\n    [Pure]\n    public static Que<T> clear<T>(Que<T> queue) =>\n        queue.Clear();\n\n    [Pure]\n    public static Que<R> map<T, R>(Que<T> queue, Func<int, T, R> map) =>\n        queue.Map(map);\n\n    [Pure]\n    public static Que<T> filter<T>(Que<T> queue, Func<T, bool> predicate) =>\n        queue.Filter(predicate);\n\n    [Pure]\n    public static Que<U> choose<T, U>(Que<T> queue, Func<T, Option<U>> selector) =>\n        queue.Choose(selector);\n\n    [Pure]\n    public static Que<U> choose<T, U>(Que<T> queue, Func<int, T, Option<U>> selector) =>\n        queue.Choose(selector);\n\n    [Pure]\n    public static Que<R> collect<T, R>(Que<T> queue, Func<T, IEnumerable<R>> map) =>\n        queue.Collect(map);\n\n    [Pure]\n    public static Que<T> rev<T>(Que<T> queue) =>\n        queue.Rev();\n\n    [Pure]\n    public static Que<T> append<T>(Que<T> lhs, IEnumerable<T> rhs) =>\n        lhs.Append(rhs);\n\n    /// <summary>\n    /// Folds each value of the QueT into an S.\n    /// [wikipedia.org/wiki/Fold_(higher-order_function)](https://en.wikipedia.org/wiki/Fold_(higher-order_function))\n    /// </summary>\n    /// <param name=\"queue\">Queue to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<S, T>(Que<T> queue, S state, Func<S, T, S> folder) =>\n        List.fold(queue, state, folder);\n\n    /// <summary>\n    /// Folds each value of the QueT into an S, but in reverse order.\n    /// [wikipedia.org/wiki/Fold_(higher-order_function)](https://en.wikipedia.org/wiki/Fold_(higher-order_function))\n    /// </summary>\n    /// <param name=\"queue\">Queue to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S foldBack<S, T>(Que<T> queue, S state, Func<S, T, S> folder) =>\n        List.foldBack(queue, state, folder);\n\n    [Pure]\n    public static T reduce<T>(Que<T> queue, Func<T, T, T> reducer) =>\n        List.reduce(queue, reducer);\n\n    [Pure]\n    public static T reduceBack<T>(Que<T> queue, Func<T, T, T> reducer) =>\n        List.reduceBack(queue, reducer);\n\n    [Pure]\n    public static IEnumerable<S> scan<S, T>(Que<T> queue, S state, Func<S, T, S> folder) =>\n        List.scan(queue, state, folder);\n\n    [Pure]\n    public static IEnumerable<S> scanBack<S, T>(Que<T> queue, S state, Func<S, T, S> folder) =>\n        List.scanBack(queue, state, folder);\n\n    [Pure]\n    public static Option<T> find<T>(Que<T> queue, Func<T, bool> pred) =>\n        List.find(queue, pred);\n\n    [Pure]\n    public static Que<V> zip<T, U, V>(Que<T> queue, IEnumerable<U> other, Func<T, U, V> zipper) =>\n        toQueue(List.zip(queue, other, zipper));\n\n    [Pure]\n    public static int length<T>(Que<T> queue) =>\n        List.length(queue);\n\n    public static Unit iter<T>(Que<T> queue, Action<T> action) =>\n        List.iter(queue, action);\n\n    public static Unit iter<T>(Que<T> queue, Action<int, T> action) =>\n        List.iter(queue, action);\n\n    [Pure]\n    public static bool forall<T>(Que<T> queue, Func<T, bool> pred) =>\n        List.forall(queue, pred);\n\n    [Pure]\n    public static Que<T> distinct<T>(Que<T> queue) =>\n        queue.Distinct();\n\n    [Pure]\n    public static Que<T> distinct<EQ, T>(Que<T> queue) where EQ : Eq<T> =>\n        queue.Distinct<EQ, T>();\n\n    [Pure]\n    public static IEnumerable<T> take<T>(Que<T> queue, int count) =>\n        List.take(queue, count);\n\n    [Pure]\n    public static IEnumerable<T> takeWhile<T>(Que<T> queue, Func<T, bool> pred) =>\n        List.takeWhile(queue, pred);\n\n    [Pure]\n    public static IEnumerable<T> takeWhile<T>(Que<T> queue, Func<T, int, bool> pred) =>\n        List.takeWhile(queue, pred);\n\n    [Pure]\n    public static bool exists<T>(Que<T> queue, Func<T, bool> pred) =>\n        List.exists(queue, pred);\n}\n\npublic static class QueueExtensions\n{\n    [Pure]\n    public static (Que<T>, T) PopUnsafe<T>(this Que<T> queue) =>\n        Queue.deqUnsafe(queue);\n\n    [Pure]\n    public static (Que<T>, Option<T>) Pop<T>(this Que<T> queue) =>\n        Queue.deq(queue);\n\n    [Pure]\n    public static T PeekUnsafe<T>(this Que<T> queue) =>\n        Queue.peekUnsafe(queue);\n\n    [Pure]\n    public static Option<T> Peek<T>(this Que<T> queue) =>\n        Queue.peek(queue);\n\n    [Pure]\n    public static Que<R> Map<T, R>(this Que<T> queue, Func<T, R> map) =>\n        toQueue(List.map(queue, map));\n\n    [Pure]\n    public static Que<R> Map<T, R>(this Que<T> queue, Func<int, T, R> map) =>\n        toQueue(List.map(queue, map));\n\n    [Pure]\n    public static Que<T> Filter<T>(this Que<T> queue, Func<T, bool> predicate) =>\n        toQueue(List.filter(queue, predicate));\n\n    [Pure]\n    public static Que<U> Choose<T, U>(this Que<T> queue, Func<T, Option<U>> selector) =>\n        toQueue(List.choose(queue, selector));\n\n    [Pure]\n    public static Que<U> Choose<T, U>(this Que<T> queue, Func<int, T, Option<U>> selector) =>\n        toQueue(List.choose(queue, selector));\n\n    [Pure]\n    public static Que<R> Collect<T, R>(this Que<T> queue, Func<T, IEnumerable<R>> map) =>\n        toQueue(List.collect(queue, map));\n\n    [Pure]\n    public static Que<T> Rev<T>(this Que<T> queue) =>\n        toQueue(List.rev(queue));\n\n    [Pure]\n    public static Que<T> Append<T>(this Que<T> lhs, IEnumerable<T> rhs) =>\n        toQueue(List.append(lhs, rhs));\n\n    [Pure]\n    public static S Fold<S, T>(this Que<T> queue, S state, Func<S, T, S> folder) =>\n        List.fold(queue, state, folder);\n\n    [Pure]\n    public static S FoldBack<S, T>(this Que<T> queue, S state, Func<S, T, S> folder) =>\n        List.foldBack(queue, state, folder);\n\n    [Pure]\n    public static T ReduceBack<T>(this Que<T> queue, Func<T, T, T> reducer) =>\n        List.reduceBack(queue, reducer);\n\n    [Pure]\n    public static T Reduce<T>(this Que<T> queue, Func<T, T, T> reducer) =>\n        List.reduce(queue, reducer);\n\n    [Pure]\n    public static Que<S> Scan<S, T>(this Que<T> queue, S state, Func<S, T, S> folder) =>\n        toQueue(List.scan(queue, state, folder));\n\n    [Pure]\n    public static IEnumerable<S> ScanBack<S, T>(this Que<T> queue, S state, Func<S, T, S> folder) =>\n        toQueue(List.scanBack(queue, state, folder));\n\n    [Pure]\n    public static Option<T> Find<T>(this Que<T> queue, Func<T, bool> pred) =>\n        List.find(queue, pred);\n\n    [Pure]\n    public static int Length<T>(this Que<T> queue) =>\n        List.length(queue);\n\n    public static Unit Iter<T>(this Que<T> queue, Action<T> action) =>\n        List.iter(queue, action);\n\n    public static Unit Iter<T>(this Que<T> queue, Action<int, T> action) =>\n        List.iter(queue, action);\n\n    [Pure]\n    public static bool ForAll<T>(this Que<T> queue, Func<T, bool> pred) =>\n        List.forall(queue, pred);\n\n    [Pure]\n    public static Que<T> Distinct<T>(this Que<T> queue) =>\n        toQueue(List.distinct(queue));\n\n    [Pure]\n    public static Que<T> Distinct<EQ, T>(this Que<T> list) where EQ : Eq<T> =>\n        toQueue(List.distinct<EQ, T>(list));\n\n    [Pure]\n    public static bool Exists<T>(this Que<T> queue, Func<T, bool> pred) =>\n        List.exists(queue, pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/README.md",
    "content": "This a suite of [very high-performance immutable-collections](https://github.com/louthy/language-ext/blob/main/Performance.md).\n\n* For lists you should always prefer to use `Seq<A>` - it is about 10x faster than `Lst<A>`.  The only reason you'd pick \n  `Lst<A>` is if you needed to do inserts into the middle of the list: `Seq<A>` doesn't allow this (it only allows prepending or \n  appending), as it would be a performance hit.\n  `Seq<A>` is backed by an array, and so it has exceptional memory locality, `Lst<A>` is an AVL tree to allow for efficient  \n  insertion, but suffers from poorer memory locality.\n* For 'dictionaries' or maps as we prefer to call them, then `HashMap` is the fastest implemention you'll find in .NET-land.  It is \n  unsorted.  If you need a sorted dictionary, use `Map`.  `HashMap` uses the CHAMP data-structure, `Map` uses an AVL tree.\n* The same goes for sets, prefer `HashSet` over `Set`, unless you need the set to be sorted.\n\nYou can construct the collection types using the constrctor functions in the `Prelude`:\n\n    HashMap<string, int> hashSet = HashMap((\"a\", 1), (\"b\", 2), (\"c\", 3));\n    HashSet<int> hashMap         = HashSet(1, 2, 3);\n    Map<string, int> hashSet     = Map((\"a\", 1), (\"b\", 2), (\"c\", 3));\n    Set<int> hashMap             = Set(1, 2, 3);\n    Seq<int> list                = Seq(1, 2, 3);\n    Lst<int> list                = List(1, 2, 3);\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/DSL/Enum.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Enumerates an IEnumerable at most once and caches\n/// the values in a List.  Seq uses this to iterate an\n/// enumerable by index, which allows this type to be\n/// shared.\n/// </summary>\n[method: MethodImpl(MethodImplOptions.AggressiveInlining)]\ninternal class Enum<A>(IEnumerable<A> ma) : IDisposable\n{\n    const int DefaultCapacity = 32;\n    A[] data = new A[DefaultCapacity];\n    int count;\n    int ncount = -1;\n    \n    IEnumerator<A>? iter = ma.GetEnumerator();\n\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count;\n    }\n\n    public A[] Data\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => data;\n    }\n\n    public (bool Success, A? Value) Get(int index)\n    {\n        while (true)\n        {\n            // Early out if the data has already been streamed\n            if (index < count)\n            {\n                return (true, data[index]);\n            }\n\n            // If there's nothing left to stream, we must be done\n            var liter = iter;\n            var lcount = index - 1;\n\n            // lindex is a lagging counter that gets moved on by 1 here.  It's the \n            // gatekeeper to moving along the iterator.  \n            if (Interlocked.CompareExchange(ref ncount, index, lcount) == lcount)\n            {\n                if (liter != null && liter.MoveNext())\n                {\n                    // Get the next value\n                    var value = liter.Current;\n\n                    // If we've run out of space, double it and copy.  \n                    // Note, this operation is atomic \n                    if (index >= data.Length)\n                    {\n                        var ndata = new A[data.Length << 1];\n                        Array.Copy(data, ndata, data.Length);\n                        data = ndata;\n                    }\n\n                    // Store the value \n                    data[index] = value;\n\n                    // Now, by updating the actual `count` we have essentially done an \n                    // atomic operation to get the value from the iterator and store it\n                    // in our internal memory.\n                    count = index + 1;\n\n                    return (true, value);\n                }\n                else\n                {\n                    // End of the iterator, so let's dispose\n                    liter?.Dispose();\n                    iter = null;\n                    ncount = count - 1;\n                    return (false, default);\n                }\n            }\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        FNV32.Hash<HashableDefault<A>, A>(data, 0, count);\n\n    public void Dispose() => \n        iter?.Dispose();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/DSL/ISeqInternal.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace LanguageExt;\n\ninternal enum SeqType\n{\n    Empty,\n    Lazy,\n    Strict,\n    Concat\n}\n\ninternal interface ISeqInternal<A> : IEnumerable<A>\n{\n    SeqType Type { get; }\n    A this[int index] { get; }\n    Option<A> At(int index);\n    ISeqInternal<A> Add(A value);\n    ISeqInternal<A> Cons(A value);\n    A Head { get; }\n    ISeqInternal<A> Tail { get; }\n    bool IsEmpty { get; }\n    ISeqInternal<A> Init { get; }\n    A Last { get; }\n    int Count { get; }\n    S Fold<S>(S state, Func<S, A, S> f);\n    S FoldBack<S>(S state, Func<S, A, S> f);\n    ISeqInternal<A> Skip(int amount);\n    ISeqInternal<A> Take(int amount);\n    ISeqInternal<A> Strict();\n    Unit Iter(Action<A> f);\n    bool Exists(Func<A, bool> f);\n    bool ForAll(Func<A, bool> f);\n    int GetHashCode(int offsetBasis);\n    ReadOnlySpan<A> AsSpan();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/DSL/SeqConcat.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.UnsafeValueAccess;\n\nnamespace LanguageExt;\n\ninternal class SeqConcat<A>(Seq<ISeqInternal<A>> ms) : ISeqInternal<A>\n{\n    internal readonly Seq<ISeqInternal<A>> ms = ms;\n    \n    int selfHash;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan() =>\n        Strict().AsSpan();\n\n    public A this[int index]\n    {\n        get\n        {\n            var r = At(index);\n            if (r.IsSome) return r.Value!;\n            throw new IndexOutOfRangeException();\n        }\n    }\n\n    public Option<A> At(int index)\n    {\n        if (index < 0) return default;\n        var ms1 = ms;\n        while (!ms1.IsEmpty)\n        {\n            var head = ms1.Head.ValueUnsafe() ?? throw new InvalidOperationException();\n            var r    = head.At(index);\n            if (r.IsSome) return r;\n            index -= head.Count;\n            ms1 = ms1.Tail;\n        }\n        return default;\n    }\n\n    public SeqType Type =>\n        SeqType.Concat;\n\n    public A Head \n    {\n        get \n        {\n            foreach (var s in ms)\n            {\n                foreach (var a in s)\n                {\n                    return a;\n                }\n            } \n            throw Exceptions.SequenceEmpty;\n        }\n    }\n\n    public ISeqInternal<A> Tail =>\n        new SeqLazy<A>(Skip(1));\n\n    public bool IsEmpty => \n        ms.ForAll(s => s.IsEmpty);\n\n    public ISeqInternal<A> Init\n    {\n        get\n        {\n            var take = Count - 1;\n            return take <= 0\n                       ? SeqEmptyInternal<A>.Default\n                       : Take(take);\n        }\n    }\n\n    public A Last\n    {\n        get \n        {\n            foreach (var s in ms.Reverse())\n            {\n                foreach (var a in s.Reverse())\n                {\n                    return a;\n                }\n            } \n            throw Exceptions.SequenceEmpty;\n        }\n    }\n\n    public int Count => \n        ms.Sum(s => s.Count);\n\n    public SeqConcat<A> AddSeq(ISeqInternal<A> ma) =>\n        new (ms.Add(ma));\n\n    public SeqConcat<A> AddSeqRange(Seq<ISeqInternal<A>> ma) =>\n        new (ms.Concat(ma));\n\n    public SeqConcat<A> ConsSeq(ISeqInternal<A> ma) =>\n        new (ma.Cons(ms));\n\n    public ISeqInternal<A> Add(A value)\n    {\n        var last = ms.Last.ValueUnsafe()?.Add(value) ?? throw new NotSupportedException();\n        return new SeqConcat<A>(ms.Take(ms.Count - 1).Add(last));\n    }\n\n    public ISeqInternal<A> Cons(A value)\n    {\n        var head = ms.Head.ValueUnsafe()?.Cons(value) ?? throw new NotSupportedException();\n        return new SeqConcat<A>(head.Cons(ms.Skip(1)));\n    }\n\n    public bool Exists(Func<A, bool> f) =>\n        ms.Exists(s => s.Exists(f));\n        \n    public S Fold<S>(S state, Func<S, A, S> f) =>\n        ms.Fold(state, (s, x) => x.Fold(s, f));\n\n    public S FoldBack<S>(S state, Func<S, A, S> f) =>\n        ms.FoldBack(state, (s, x) => x.FoldBack(s, f));\n\n    public bool ForAll(Func<A, bool> f) =>\n        ms.ForAll(s => s.ForAll(f));\n\n    public IEnumerator<A> GetEnumerator()\n    {\n        foreach(var s in ms)\n        {\n            foreach(var a in s)\n            {\n                yield return a;\n            }\n        }\n    }\n\n    public Unit Iter(Action<A> f)\n    {\n        foreach (var s in ms)\n        {\n            foreach (var a in s)\n            {\n                f(a);\n            }\n        }\n        return default;\n    }\n\n    public ISeqInternal<A> Skip(int amount) =>\n        new SeqLazy<A>(((IEnumerable<A>)this).Skip(amount));\n\n    public ISeqInternal<A> Strict()\n    {\n        foreach(var s in ms)\n        {\n            s.Strict();\n        }\n        return this;\n    }\n\n    public ISeqInternal<A> Take(int amount)\n    {\n        IEnumerable<A> Yield()\n        {\n            using var iter = GetEnumerator();\n            for(; amount > 0 && iter.MoveNext(); amount--)\n            {\n                yield return iter.Current;\n            }\n        }\n        return new SeqLazy<A>(Yield());\n    }\n\n    IEnumerator IEnumerable.GetEnumerator()\n    {\n        foreach (var s in ms)\n        {\n            foreach (var a in s)\n            {\n                yield return a;\n            }\n        }\n    }\n\n    ISeqInternal<A> Flatten()\n    {\n        var total = 0;\n        foreach (var s in ms)\n        {\n            s.Strict();\n            total = s.Count;\n        }\n\n        var cap = 8;\n        while(cap < total)\n        {\n            cap <<= 1;\n        }\n\n        var data    = new A[cap];\n        var start   = (cap - total) >> 1;\n        var current = start;\n\n        foreach(var s in ms)\n        {\n            var strict = (SeqStrict<A>)s;\n            Array.Copy(strict.data, strict.start, data, current, strict.count);\n            current += strict.count;\n        }\n        return new SeqStrict<A>(data, start, total, 0, 0);\n    }\n        \n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        selfHash == 0\n            ? selfHash = GetHashCode(FNV32.OffsetBasis)\n            : selfHash;        \n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int GetHashCode(int hash)\n    {\n        foreach (var seq in ms)\n        {\n            hash = seq.GetHashCode(hash);\n        }\n        return hash;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/DSL/SeqEmptyInternal.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\ninternal class SeqEmptyInternal<A> : ISeqInternal<A>\n{\n    public static ISeqInternal<A> Default = new SeqEmptyInternal<A>();\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan() =>\n        ReadOnlySpan<A>.Empty;\n\n    public A this[int index] => \n        throw new IndexOutOfRangeException();\n\n    public Option<A> At(int index) => \n        default;\n\n    public A Head =>\n        throw Exceptions.SequenceEmpty;\n\n    public ISeqInternal<A> Tail =>\n        this;\n\n    public bool IsEmpty => \n        true;\n\n    public ISeqInternal<A> Init =>\n        this;\n\n    public A Last =>\n        throw Exceptions.SequenceEmpty;\n\n    public int Count => \n        0;\n\n    public ISeqInternal<A> Add(A value) =>\n        SeqStrict<A>.FromSingleValue(value);\n\n    public ISeqInternal<A> Cons(A value) =>\n        SeqStrict<A>.FromSingleValue(value);\n\n    public S Fold<S>(S state, Func<S, A, S> f) =>\n        state;\n\n    public S FoldBack<S>(S state, Func<S, A, S> f) =>\n        state;\n\n    public ISeqInternal<A> Skip(int amount) =>\n        this;\n\n    public ISeqInternal<A> Strict() =>\n        this;\n\n    public ISeqInternal<A> Take(int amount) =>\n        this;\n        \n    public IEnumerator<A> GetEnumerator()\n    {\n        yield break;\n    }\n            \n    IEnumerator IEnumerable.GetEnumerator()\n    {\n        yield break;\n    }\n\n    public Unit Iter(Action<A> f) =>\n        default;\n\n    public bool Exists(Func<A, bool> f) => \n        false;\n\n    public bool ForAll(Func<A, bool> f) =>\n        true;\n\n    public SeqType Type => SeqType.Empty;\n\n    public override int GetHashCode() =>\n        FNV32.OffsetBasis;\n\n    public int GetHashCode(int offsetBasis) =>\n        offsetBasis;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/DSL/SeqLazy.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\ninternal class SeqLazy<A> : ISeqInternal<A>\n{\n    const int DefaultCapacity = 8;\n    const int NoCons = 1;\n\n    /// <summary>\n    /// Backing data\n    /// </summary>\n    readonly A[] data;\n\n    /// <summary>\n    /// Index into data where the Head is\n    /// </summary>\n    readonly int start;\n\n    /// <summary>\n    /// Known size of the sequence - 0 means unknown\n    /// </summary>\n    readonly int count;\n\n    /// <summary>\n    /// 1 if no more consing is allowed\n    /// </summary>\n    int consDisallowed;\n\n    /// <summary>\n    /// Lazy sequence\n    /// </summary>\n    readonly Enum<A> seq;\n\n    /// <summary>\n    /// Start position in sequence\n    /// </summary>\n    readonly int seqStart;\n\n    /// <summary>\n    /// Cached hash code\n    /// </summary>\n    int selfHash;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan() =>\n        Strict().AsSpan();\n    \n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal SeqLazy(IEnumerable<A> ma) : this(new A[DefaultCapacity], DefaultCapacity, 0, 0, new Enum<A>(ma), 0)\n    { }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    SeqLazy(A[] data, int start, int count, int noCons, Enum<A> seq, int seqStart)\n    {\n        this.data = data;\n        this.start = start;\n        this.count = count;\n        this.seq = seq;\n        this.seqStart = seqStart;\n        consDisallowed = noCons;\n    }\n\n    public A this[int index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            var r = At(index);\n            if (r.IsSome) return r.Value!;\n            throw new IndexOutOfRangeException();\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<A> At(int index)\n    {\n        if (index < 0) return default;\n        if (index < count) return data[^count];\n        var lazyIndex = index                      - count + seqStart;\n        var (succ, val) = StreamTo(lazyIndex);\n        return succ\n                   ? val\n                   : default(Option<A>);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    (bool Success, A? Value) StreamTo(int index)\n    {\n        if(index < seq.Count) return seq.Get(index);\n        while (seq.Count <= index && seq.Get(seq.Count).Success)\n        {\n            // this is empty intentionally\n        }\n        return index < seq.Count\n                   ? (true, seq.Data[index])\n                   : (false, default);\n    }\n\n\n    public A Head\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            if(count > 0)\n            {\n                return data[^count];\n            }\n            else if(seq.Count > seqStart)\n            {\n                return seq.Data[seqStart];\n            }\n            else\n            {\n                var (succ, val) = seq.Get(seqStart);\n                return succ\n                           ? val!\n                           : throw Exceptions.SequenceEmpty;\n\n            }\n        }\n    }\n\n    public ISeqInternal<A> Tail\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            if(count > 0)\n            {\n                return new SeqLazy<A>(data, start + 1, count - 1, NoCons, seq, seqStart);\n            }\n            else if(seq.Count > seqStart)\n            {\n                return new SeqLazy<A>(data, start, count, NoCons, seq, seqStart + 1);\n            }\n            else\n            {\n                var (succ, _) = StreamTo(seq.Count);\n                if(succ)\n                {\n                    return new SeqLazy<A>(data, start, count, NoCons, seq, seqStart + 1);\n                }\n                else\n                {\n                    return SeqEmptyInternal<A>.Default;\n                }\n            }\n        }\n    }\n\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => !(count > 0 || seq.Count - seqStart > 0 || seq.Get(seqStart).Success);\n    }\n\n    public A Last\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            InternalStrict();\n            return seq.Count > seqStart ? seq.Data[seq.Count - 1]\n                   : count   > 0        ? data[^1]\n                   : throw Exceptions.SequenceEmpty;\n        }\n    }\n\n    public ISeqInternal<A> Init\n    {\n        get\n        {\n            var take = Count - 1;\n            return take <= 0\n                       ? SeqEmptyInternal<A>.Default\n                       : Take(take);\n        }\n    }\n\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            InternalStrict();\n            return count + seq.Count - seqStart;\n        }\n    }\n\n    public ISeqInternal<A> Add(A value)\n    {\n        InternalStrict();\n        var seqCount = seq.Count - seqStart;\n        var total    = count     + seqCount + 1;\n        var len      = DefaultCapacity;\n        while (len < total) len <<= 1;\n\n        var ndata = new A[len];\n\n        if (count > 0)\n        {\n            Array.Copy(data, data.Length - count, ndata, 0, count);\n        }\n        if (seqCount > 0)\n        {\n            Array.Copy(seq.Data, seqStart, ndata, count, seqCount);\n        }\n        ndata[count + seqCount] = value;\n\n        return new SeqStrict<A>(ndata, 0, total, 0, 0);\n    }\n\n    public ISeqInternal<A> Cons(A value)\n    {\n        if (1 == Interlocked.Exchange(ref consDisallowed, 1) || start == 0)\n        {\n            return CloneCons(value);\n        }\n        else\n        {\n            var nstart = start - 1;\n            data[nstart] = value;\n            return new SeqLazy<A>(data, start - 1, count + 1, 0, seq, seqStart);\n        }\n    }\n\n    SeqLazy<A> CloneCons(A value)\n    {\n        if (start == 0)\n        {\n            // Find the new size of the data array\n            var nlength = Math.Max(data.Length << 1, 1);\n\n            // Allocate it\n            var ndata = new A[nlength];\n\n            // Copy the old data block to the second half of the new one\n            // so we have space on the left-hand-side to put the cons'd\n            // value\n            Array.Copy(data, 0, ndata, data.Length, data.Length);\n\n            // The new head position will be 1 cell to to left of the \n            // middle of the newly allocated block.\n            var nstart = data.Length - 1;\n\n            // We have one more item\n            var ncount = count + 1;\n\n            // Set the value in the new data block\n            ndata[nstart] = value;\n\n            // Return everything \n            return new SeqLazy<A>(ndata, nstart, ncount, 0, seq, seqStart);\n        }\n        else\n        {\n            // We're cloning because there are multiple cons operations\n            // from the same Seq.  We can't keep walking along the same \n            // array, so we clone with the exact same settings and insert\n\n            var ndata  = new A[data.Length];\n            var nstart = start - 1;\n\n            Array.Copy(data, start, ndata, start, count);\n\n            ndata[nstart] = value;\n\n            return new SeqLazy<A>(ndata, nstart, count + 1, 0, seq, seqStart);\n        }\n    }\n\n    public S Fold<S>(S state, Func<S, A, S> f)\n    {\n        InternalStrict();\n        if (count > 0)\n        {\n            for (var i = data.Length - count; i < data.Length; i++)\n            {\n                state = f(state, data[i]);\n            }\n        }\n        if (seq.Count - seqStart > 0)\n        {\n            var scount = seq.Count;\n            var sdata  = seq.Data;\n            for (var i = seqStart; i < scount; i++)\n            {\n                state = f(state, sdata[i]);\n            }\n        }\n        return state;\n    }\n\n    public S FoldBack<S>(S state, Func<S, A, S> f)\n    {\n        InternalStrict();\n        if (seq.Count - seqStart > 0)\n        {\n            var sdata = seq.Data;\n            for (var i = seq.Count - 1; i >= seqStart; i--)\n            {\n                state = f(state, sdata[i]);\n            }\n        }\n        if (count > 0)\n        {\n            var nstart = data.Length - count;\n            for (var i = data.Length - 1; i >= nstart; i--)\n            {\n                state = f(state, data[i]);\n            }\n        }\n        return state;\n    }\n\n    public ISeqInternal<A> Skip(int amount)\n    {\n        if(amount < count)\n        {\n            return new SeqLazy<A>(data, start + amount, count - amount, NoCons, seq, seqStart);\n        }\n        else if (amount == count)\n        {\n            return new SeqLazy<A>(new A[DefaultCapacity], DefaultCapacity, 0, 0, seq, seqStart);\n        }\n        else\n        {\n            var namount = amount   - count;\n            var end     = seqStart + namount;\n            if (end > seq.Count)\n            {\n                for (var i = seqStart; i < end && seq.Get(i).Success; i++)\n                {\n                    // this is empty intentionally\n                }\n            }\n\n            if(seq.Count >= end)\n            {\n                return new SeqLazy<A>(new A[DefaultCapacity], DefaultCapacity, 0, 0, seq, end);\n            }\n            else\n            {\n                return SeqEmptyInternal<A>.Default;\n            }\n        }\n    }\n\n    void InternalStrict()\n    {\n        while (seq.Get(seq.Count).Success)\n        {\n            // this is empty intentionally\n        }\n    }\n\n    public ISeqInternal<A> Strict()\n    {\n        InternalStrict();\n\n        var len    = DefaultCapacity;\n        var ncount = count + seq.Count - seqStart;\n        while (len < ncount) len <<= 1;\n\n        var nstart = (len - ncount) >> 1;\n\n        var ndata = new A[len];\n        if (count > 0)\n        {\n            Array.Copy(data, data.Length - count, ndata, nstart, count);\n        }\n        if (seq.Count > 0)\n        {\n            Array.Copy(seq.Data, seqStart, ndata, nstart + count, seq.Count - seqStart);\n        }\n        return new SeqStrict<A>(ndata, nstart, ncount, 0, 0);\n    }\n\n    public ISeqInternal<A> Take(int amount)\n    {\n        if(amount <= count)\n        {\n            var ndata  = new A[data.Length];\n            var nstart = data.Length - count;\n            Array.Copy(data, nstart, ndata, nstart, data.Length);\n            return new SeqStrict<A>(ndata, start, amount, 0, 0);\n        }\n        else\n        {\n            var namount = amount   - count;\n            var end     = seqStart + namount;\n            for (var i = seqStart; i < end && seq.Get(i).Success; i++)\n            {\n                // this is empty intentionally\n            }\n            var seqLen = seq.Count - seqStart;\n\n            amount = Math.Min(seqLen + count, amount);\n\n            if (amount == 0)\n            {\n                // Empty\n                var edata = new A[DefaultCapacity];\n                return new SeqStrict<A>(edata, DefaultCapacity >> 1, 0, 0, 0);\n            }\n            else\n            {\n                var len = DefaultCapacity;\n                while (len < amount) len <<= 1;\n\n                var ndata  = new A[len];\n                var nstart = (len - amount) >> 1;\n                if (count > 0)\n                {\n                    Array.Copy(data, data.Length - count, ndata, nstart, count);\n                }\n\n                if (seq.Count - seqStart > 0)\n                {\n                    Array.Copy(seq.Data, seqStart, ndata, nstart + count, amount - count);\n                }\n\n                return new SeqStrict<A>(ndata, nstart, amount, 0, 0);\n            }\n        }\n    }\n\n    public IEnumerator<A> GetEnumerator()\n    {\n        var nstart = data.Length - count;\n        var nend   = data.Length;\n\n        for (var i = nstart; i < nend; i++)\n        {\n            yield return data[i];\n        }\n        for(var i = seqStart; ; i++)\n        {\n            var (succ, val) = seq.Get(i);\n            if(succ)\n            {\n                yield return val!;\n            }\n            else\n            {\n                yield break;\n            }\n        }\n    }\n\n    IEnumerator IEnumerable.GetEnumerator()\n    {\n        var nstart = data.Length - count;\n        var nend   = data.Length;\n\n        for (var i = nstart; i < nend; i++)\n        {\n            yield return data[i];\n        }\n        for (var i = seqStart; ; i++)\n        {\n            var (succ, val) = seq.Get(i);\n            if (succ)\n            {\n                yield return val!;\n            }\n            else\n            {\n                yield break;\n            }\n        }\n    }\n\n    public Unit Iter(Action<A> f)\n    {\n        foreach(var item in this)\n        {\n            f(item);\n        }\n        return default;\n    }\n\n    public bool Exists(Func<A, bool> f)\n    {\n        foreach(var item in this)\n        {\n            if (f(item))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public bool ForAll(Func<A, bool> f)\n    {\n        foreach (var item in this)\n        {\n            if (!f(item))\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    public SeqType Type => \n        SeqType.Lazy;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        selfHash == 0\n            ? selfHash = GetHashCode(FNV32.OffsetBasis)\n            : selfHash;\n\n    public int GetHashCode(int hash)\n    {\n        InternalStrict();\n        if (count > 0)\n        {\n            hash = FNV32.Hash<HashableDefault<A>, A>(data, start, count, hash);\n        }\n        if (seq.Count - seqStart > 0)\n        {\n            hash = FNV32.Hash<HashableDefault<A>, A>(seq.Data, seqStart, seq.Count - seqStart, hash);\n        }\n        return hash;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/DSL/SeqStrict.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\ninternal class SeqStrict<A> : ISeqInternal<A>\n{\n    public const int DefaultCapacity = 8;\n    /*\n    const int HalfDefaultCapacity = DefaultCapacity >> 1;\n    */\n\n    const int NoCons = 1;\n    const int NoAdd = 1;\n\n    /// <summary>\n    /// Backing data\n    /// </summary>\n    internal readonly A[] data;\n\n    /// <summary>\n    /// Index into data where the Head is\n    /// </summary>\n    internal readonly int start;\n\n    /// <summary>\n    /// Known size of the sequence\n    /// </summary>\n    internal readonly int count;\n\n    /// <summary>\n    /// 1 if no more consing is allowed\n    /// </summary>\n    int consDisallowed;\n\n    /// <summary>\n    /// 1 if no more adding is allowed\n    /// </summary>\n    int addDisallowed;\n\n    /// <summary>\n    /// Cached hash code\n    /// </summary>\n    int selfHash;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan() =>\n        new(data, start, count);\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public SeqStrict(A[] data, int start, int count, int consDisallowed, int addDisallowed)\n    {\n        this.data = data;\n        this.start = start;\n        this.count = count;\n        this.consDisallowed = consDisallowed;\n        this.addDisallowed = addDisallowed;\n    }\n\n    public static SeqStrict<A> Empty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new (new A[DefaultCapacity], 4, 0, 0, 0);\n    }\n\n    /// <summary>\n    /// Add constructor (called in the Add function only)\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public SeqStrict(A[] data, int start, int count)\n    {\n        this.data = data;\n        this.start = start;\n        this.count = count;\n        consDisallowed = NoCons;\n    }\n\n    /// <summary>\n    /// Indexer\n    /// </summary>\n    public A this[int index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => index < 0 || index >= count\n                   ? throw new IndexOutOfRangeException()\n                   : data[start + index];\n    }\n\n    /// <summary>\n    /// Indexer\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<A> At(int index) =>\n        index < 0 || index >= count\n            ? default(Option<A>)\n            : data[start + index];\n\n    /// <summary>\n    /// Add an item to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the item \n    /// can be appended\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ISeqInternal<A> Add(A value)\n    {\n        var end = start + count;\n        if (1 == Interlocked.Exchange(ref addDisallowed, 1) || end == data.Length)\n        {\n            return CloneAdd(value);\n        }\n        else\n        {\n            data[end] = value;\n            return new SeqStrict<A>(data, start, count + 1);\n        }\n    }\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    SeqStrict<A> Concat(A[] items, int itemsStart, int itemsCount)\n    {\n        var end = start + count;\n        if (1 == Interlocked.Exchange(ref addDisallowed, 1) || end + itemsCount >= data.Length)\n        {\n            return CloneAddRange(items, itemsStart, itemsCount);\n        }\n        else\n        {\n            Array.Copy(items, itemsStart, data, end, itemsCount);\n            return new SeqStrict<A>(data, start, count + itemsCount, NoCons, 0);\n        }\n    }\n\n    /// <summary>\n    /// Prepend an item to the sequence\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ISeqInternal<A> Cons(A value)\n    {\n        if (1 == Interlocked.Exchange(ref consDisallowed, 1) || start == 0)\n        {\n            return CloneCons(value);\n        }\n        else\n        {\n            var nstart = start - 1;\n            data[nstart] = value;\n            return new SeqStrict<A>(data, start - 1, count + 1, 0, NoAdd);\n        }\n    }\n\n    SeqStrict<A> CloneCons(A value)\n    {\n        if (start == 0)\n        {\n            // Find the new size of the data array\n            var nlength = Math.Max(data.Length << 1, 1);\n\n            // Allocate it\n            var ndata = new A[nlength];\n\n            // Copy the old data block to the second half of the new one\n            // so we have space on the left-hand-side to put the cons'd\n            // value\n            Array.Copy(data, 0, ndata, data.Length, data.Length);\n\n            // The new head position will be 1 cell to to left of the \n            // middle of the newly allocated block.\n            var nstart = data.Length == 0\n                             ? 0\n                             : data.Length - 1;\n\n            // We have one more item\n            var ncount = count + 1;\n\n            // Set the value in the new data block\n            ndata[nstart] = value;\n\n            // Return everything \n            return new SeqStrict<A>(ndata, nstart, ncount, 0, 0);\n        }\n        else\n        {\n            // We're cloning because there are multiple cons operations\n            // from the same Seq.  We can't keep walking along the same \n            // array, so we clone with the exact same settings and insert\n\n            var ndata  = new A[data.Length];\n            var nstart = start - 1;\n\n            Array.Copy(data, start, ndata, start, count);\n\n            ndata[nstart] = value;\n\n            return new SeqStrict<A>(ndata, nstart, count + 1, 0, 0);\n        }\n    }\n\n    SeqStrict<A> CloneAdd(A value)\n    {\n        var end = start + count;\n\n        // Find the new size of the data array\n        var nlength = data.Length == end\n                          ? Math.Max(data.Length << 1, 1)\n                          : data.Length;\n\n        // Allocate it\n        var ndata = new A[nlength];\n\n        // Copy the old data block to the first half of the new one\n        // so we have space on the right-hand-side to put the added\n        // value\n        Array.Copy(data, 0, ndata, 0, data.Length);\n\n        // Set the value in the new data block\n        ndata[end] = value;\n\n        // Return everything \n        return new SeqStrict<A>(ndata, start, count + 1, 0, 0);\n    }\n\n    SeqStrict<A> CloneAddRange(A[] values, int valuesStart, int valuesCount)\n    {\n        var end = start + count;\n\n        // Find the new size of the data array\n        var nlength = Math.Max(Math.Max(data.Length << 1, 1), end + valuesCount);\n\n        // Allocate it\n        var ndata = new A[nlength];\n\n        // Copy the old data block to the first half of the new one\n        // so we have space on the right-hand-side to put the added\n        // value\n        Array.Copy(data, 0, ndata, 0, end);\n\n        // Set the value in the new data block\n        Array.Copy(values, valuesStart, ndata, end, valuesCount);\n\n        // Return everything \n        return new SeqStrict<A>(ndata, start, count + valuesCount, 0, 0);\n    }\n\n    /// <summary>\n    /// Head item in the sequence.  NOTE:  If `IsEmpty` is true then Head\n    /// is undefined.  Call HeadOrNone() if for maximum safety.\n    /// </summary>\n    public A Head\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count == 0\n                   ? throw Exceptions.SequenceEmpty\n                   : data[start];\n    }\n\n    /// <summary>\n    /// Tail of the sequence\n    /// </summary>\n    public ISeqInternal<A> Tail\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count < 1\n                   ? SeqEmptyInternal<A>.Default\n                   : new SeqStrict<A>(data, start + 1, count - 1, NoCons, NoAdd);\n    }\n\n    public ISeqInternal<A> Init\n    {\n        get\n        {\n            var take = count - 1;\n\n            return take <= 0\n                       ? SeqEmptyInternal<A>.Default\n                       : new SeqStrict<A>(data, start, take, NoCons, NoAdd);\n        }\n    }\n\n    /// <summary>\n    /// Returns true if the sequence is empty\n    /// </summary>\n    /// <remarks>\n    /// For lazy streams this will have to peek at the first \n    /// item.  So, the first item will be consumed.\n    /// </remarks>\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count == 0;\n    }\n\n    /// <summary>\n    /// Last item in sequence.  Throws if no items in sequence\n    /// </summary>\n    public A Last\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get =>\n            IsEmpty\n                ? throw Exceptions.SequenceEmpty\n\n                : data[start + count - 1];\n    }\n\n    /// <summary>\n    /// Returns the number of items in the sequence\n    /// </summary>\n    /// <returns>Number of items in the sequence</returns>\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count;\n    }\n\n    /// <summary>\n    /// Fold the sequence from the first item to the last\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"f\">Fold function</param>\n    /// <returns>Aggregated state</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, A, S> f)\n    {\n        var end = start + count;\n        for(var i = start; i < end; i++)\n        {\n            state = f(state, data[i]);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence from the last item to the first.  For \n    /// sequences that are not lazy and are less than 5000 items\n    /// long, FoldBackRec is called instead, because it is faster.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"f\">Fold function</param>\n    /// <returns>Aggregated state</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S FoldBack<S>(S state, Func<S, A, S> f)\n    {\n        for (var i = start + count - 1; i >= start; i--)\n        {\n            state = f(state, data[i]);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Skip count items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ISeqInternal<A> Skip(int amount)\n    {\n        if (amount < 1)\n        {\n            return this;\n        }\n\n        var end      = start + count;\n        var newStart = start + amount;\n        return newStart < end\n                   ? new SeqStrict<A>(data, newStart, count - amount, NoCons, NoAdd)\n                   : SeqEmptyInternal<A>.Default;\n    }\n\n    /// <summary>\n    /// Take count items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ISeqInternal<A> Take(int amount) =>\n        amount < count\n            ? new SeqStrict<A>(data, start, amount, NoCons, NoAdd)\n            : this;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ISeqInternal<A> Strict() =>\n        this;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static SeqStrict<A> FromSingleValue(A value) =>\n        new ([default!, default!, default!, default!, value, default!, default!, default!], 4, 1, 0, 0);\n\n    public IEnumerator<A> GetEnumerator()\n    {\n        var end = start + count;\n        for (var i = start; i < end; i++)\n        {\n            yield return data[i];\n        }\n    }\n\n    IEnumerator IEnumerable.GetEnumerator()\n    {\n        var end = start + count;\n        for (var i = start; i < end; i++)\n        {\n            yield return data[i];\n        }\n    }\n\n    public SeqStrict<A> SetItem(int index, A value)\n    {\n        var ndata = new A[data.Length];\n        Array.Copy(data, start, ndata, start, count);\n        ndata[index] = value;\n        return new SeqStrict<A>(data, start, count);\n    }\n\n    public Unit Iter(Action<A> f)\n    {\n        var end = start + count;\n        for (var i = start; i < end; i++)\n        {\n            f(data[i]);\n        }\n        return default;\n    }\n\n    public bool Exists(Func<A, bool> f)\n    {\n        var end = start + count;\n        for (var i = start; i < end; i++)\n        {\n            if(f(data[i]))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public bool ForAll(Func<A, bool> f)\n    {\n        var end = start + count;\n        for (var i = start; i < end; i++)\n        {\n            if (!f(data[i]))\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    public SeqType Type => SeqType.Strict;\n\n    public SeqStrict<A> Append(SeqStrict<A> right)\n    {\n        var end = start + count + right.count;\n        if (end > data.Length || 1 == Interlocked.Exchange(ref addDisallowed, 1))\n        {\n            // Clone\n            var nsize = 8;\n            while(nsize < end)\n            {\n                nsize <<= 1;\n            }\n\n            var ndata = new A[nsize];\n            Array.Copy(data, start, ndata, start, count);\n            Array.Copy(right.data, right.start, ndata, start + count, right.count);\n            return new SeqStrict<A>(ndata, start, count      + right.count, 0, 0);\n        }\n        else\n        {\n            Array.Copy(right.data, right.start, data, start + count, right.count);\n            return new SeqStrict<A>(data, start, count      + right.count, NoCons, 0);\n        }\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        selfHash == 0\n            ? selfHash = GetHashCode(FNV32.OffsetBasis)\n            : selfHash;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int GetHashCode(int offsetBasis) =>\n        FNV32.Hash<HashableDefault<A>, A>(data, start, count, offsetBasis);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static SeqStrict<A> FromEnumerable(IEnumerable<A> ma)\n    {\n        var arr = ma.ToArray();\n        return new SeqStrict<A>(arr, 0, arr.Length, 0, 0);\n    }\n\n    public SeqStrict<A> Rev()\n    {\n        var ndata = new A[data.Length];\n        var i     = start;\n        var j     = data.Length - start;\n        var end   = start + count;\n        for (; i < end; i++, j--)\n        {\n            ndata[j] = data[i];\n        }\n        return new SeqStrict<A>(ndata, data.Length - start, count, 0, 0);\n    }\n    \n    public SeqStrict<B> Map<B>(Func<A, B> f)\n    {\n        var ndata = new B[data.Length];\n        var end   = start + count;\n        for (var i = start; i < end; i++)\n        {\n            ndata[i] = f(data[i]);\n        }\n        return new SeqStrict<B>(ndata, start, count, 0, 0);\n    }\n    \n    public SeqStrict<B> Map<B>(Func<A, int, B> f)\n    {\n        var ndata = new B[data.Length];\n        var end   = start + count;\n        for (var i = start; i < end; i++)\n        {\n            ndata[i] = f(data[i], i - start);\n        }\n        return new SeqStrict<B>(ndata, start, count, 0, 0);\n    }\n    \n    public SeqStrict<A> Filter(Func<A, bool> f)\n    {\n        var ndata  = new A[data.Length];\n        var end    = start + count;\n        var ncount = 0;\n        for (var i = start; i < end; i++)\n        {\n            var d = data[i];\n            if (f(d))\n            {\n                ndata[start + ncount] = d;\n                ncount++;\n            }\n        }\n        return new SeqStrict<A>(ndata, start, ncount, 0, 0);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/Extensions/Seq.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SeqExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Seq<B> Map<A, B>(this Func<A, B> f, K<Seq, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Seq<B> Map<A, B>(this Func<A, B> f, Seq<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Seq<B> Action<A, B>(this Seq<A> ma, K<Seq, B> mb) =>\n        Applicative.action(ma, mb).As();    \n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Seq<B> Action<A, B>(this K<Seq, A> ma, K<Seq, B> mb) =>\n        Applicative.action(ma, mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Seq<B> Apply<A, B>(this Seq<Func<A, B>> mf, K<Seq, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Seq<B> Apply<A, B>(this K<Seq, Func<A, B>> mf, K<Seq, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/Extensions/Seq.Extensions.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class SeqExtensions\n{\n    public static Seq<A> As<A>(this K<Seq, A> xs) =>\n        (Seq<A>)xs;\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Seq<A> Flatten<A>(this Seq<Seq<A>> ma) =>\n        ma.Bind(identity);\n    \n    /// <summary>\n    /// Applies the given function 'selector' to each element of the sequence. Returns the sequence \n    /// comprised of the results for each element where the function returns Some(f(x)).\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered sequence</returns>\n    [Pure]\n    public static Seq<B> Choose<A, B>(this Seq<A> list, Func<A, Option<B>> selector) =>\n        Seq.choose(list, selector);\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the sequence. Returns the \n    /// sequence comprised of the results for each element where the function returns Some(f(x)).\n    /// An index value is passed through to the selector function also.\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered sequence</returns>\n    [Pure]\n    public static Seq<B> Choose<A, B>(this Seq<A> list, Func<int, A, Option<B>> selector) =>\n        Seq.choose(list, selector);\n\n    /// <summary>\n    /// Reverses the sequence (Reverse in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence to reverse</param>\n    /// <returns>Reversed sequence</returns>\n    [Pure]\n    public static Seq<T> Rev<T>(this Seq<T> list) =>\n        Seq.rev(list);\n\n    /// <summary>\n    /// Concatenate two sequences (Concat in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"lhs\">First sequence</param>\n    /// <param name=\"rhs\">Second sequence</param>\n    /// <returns>Concatenated sequence</returns>\n    [Pure]\n    public static Seq<T> Append<T>(this Seq<T> lhs, Seq<T> rhs) =>\n        Seq.append(lhs, rhs);\n\n    /// <summary>\n    /// Concatenate a sequence and a sequence of sequences\n    /// </summary>\n    /// <typeparam name=\"T\">List item type</typeparam>\n    /// <param name=\"lhs\">First list</param>\n    /// <param name=\"rhs\">Second list</param>\n    /// <returns>Concatenated list</returns>\n    [Pure]\n    public static Seq<T> Append<T>(this Seq<T> x, Seq<Seq<T>> xs) =>\n        Seq.append(x, xs);\n\n    /// <summary>\n    /// Applies a function to each element of the sequence, threading an accumulator argument \n    /// through the computation. This function takes the state argument, and applies the function \n    /// to it and the first element of the sequence. Then, it passes this result into the function \n    /// along with the second element, and so on. Finally, it returns the list of intermediate \n    /// results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static Seq<S> Scan<S, T>(this Seq<T> list, S state, Func<S, T, S> folder) =>\n        Seq.scan(list, state, folder);\n\n    /// <summary>\n    /// Applies a function to each element of the sequence (from last element to first), \n    /// threading an accumulator argument through the computation. This function takes the state \n    /// argument, and applies the function to it and the first element of the sequence. Then, it \n    /// passes this result into the function along with the second element, and so on. Finally, \n    /// it returns the list of intermediate results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static Seq<S> ScanBack<S, T>(this Seq<T> list, S state, Func<S, T, S> folder) =>\n        Seq.scanBack(list, state, folder);\n\n    /// <summary>\n    /// Joins two sequences together either into a single sequence using the join \n    /// function provided\n    /// </summary>\n    /// <param name=\"list\">First sequence to join</param>\n    /// <param name=\"other\">Second sequence to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined sequence</returns>\n    [Pure]\n    public static Seq<V> Zip<T, U, V>(this Seq<T> list, Seq<U> other, Func<T, U, V> zipper) =>\n        toSeq(Enumerable.Zip(list, other, zipper));\n\n    /// <summary>\n    /// Joins two sequences together either into an sequence of tuples\n    /// </summary>\n    /// <param name=\"list\">First sequence to join</param>\n    /// <param name=\"other\">Second sequence to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined sequence of tuples</returns>\n    [Pure]\n    public static Seq<(T First, U Second)> Zip<T, U>(this Seq<T> list, Seq<U> other) =>\n        toSeq(Enumerable.Zip(list, other, (t, u) => (t, u)));\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    public static Seq<T> Distinct<T>(this Seq<T> list) =>\n        toSeq(Enumerable.Distinct(list));\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    public static Seq<T> Distinct<EQ, T>(this Seq<T> list) where EQ : Eq<T> =>\n        toSeq(Enumerable.Distinct(list, new EqCompare<T>(static (x, y) => EQ.Equals(x, y), static x => EQ.GetHashCode(x))));\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    public static Seq<T> Distinct<T, K>(this Seq<T> list, Func<T, K> keySelector, Option<Func<K, K, bool>> compare = default) =>\n        toSeq(Enumerable.Distinct(list, \n            new EqCompare<T>(\n                (a, b) => compare.IfNone(EqDefault<K>.Equals)(keySelector(a), keySelector(b)), \n                a => compare.Match(Some: _  => 0, None: () => EqDefault<K>.GetHashCode(keySelector(a))))));\n\n    /// <summary>\n    /// The tails function returns all final segments of the argument, longest first. For example:\n    /// \n    ///     tails(['a','b','c']) == [['a','b','c'], ['b','c'], ['c'],[]]\n    /// </summary>\n    /// <typeparam name=\"A\">Seq item type</typeparam>\n    /// <param name=\"self\">Seq</param>\n    /// <returns>Seq of Seq of A</returns>\n    [Pure]\n    public static Seq<Seq<A>> Tails<A>(this Seq<A> self) =>\n        Seq.tails(self);\n\n    /// <summary>\n    /// Span, applied to a predicate 'pred' and a list, returns a tuple where first element is \n    /// longest prefix (possibly empty) of elements that satisfy 'pred' and second element is the \n    /// remainder of the list:\n    /// </summary>\n    /// <example>\n    /// Seq.span(List(1,2,3,4,1,2,3,4), x => x 〈 3) == (List(1,2),List(3,4,1,2,3,4))\n    /// </example>\n    /// <example>\n    /// Seq.span(List(1,2,3), x => x 〈 9) == (List(1,2,3),List())\n    /// </example>\n    /// <example>\n    /// Seq.span(List(1,2,3), x => x 〈 0) == (List(),List(1,2,3))\n    /// </example>\n    /// <typeparam name=\"T\">List element type</typeparam>\n    /// <param name=\"self\">List</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Split list</returns>\n    [Pure]\n    public static (Seq<T>, Seq<T>) Span<T>(this Seq<T> self, Func<T, bool> pred) =>\n        Seq.span(self, pred);\n \n    /// <summary>\n    /// Convert to a queryable \n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public static IQueryable<A> AsQueryable<A>(this Seq<A> source) =>\n        // NOTE TO FUTURE ME: Don't delete this thinking it's not needed!\n        source.Value.AsQueryable();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/Operators/Seq.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SeqExtensions\n{\n    extension<A>(K<Seq, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Seq<A> operator +(K<Seq, A> ma) =>\n            (Seq<A>)ma;\n        \n        public static Seq<A> operator >> (K<Seq, A> ma, Lower lower) =>\n            (Seq<A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/Prelude/Seq.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Seq<B> map<A, B>(Func<A, B> f, K<Seq, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Seq<B> action<A, B>(K<Seq, A> ma, K<Seq, B> mb) =>\n        Applicative.action(ma, mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Seq<B> apply<A, B>(K<Seq, Func<A, B>> mf, K<Seq, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/Seq.Module.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing System;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing LanguageExt.Traits;\nusing LanguageExt.ClassInstances;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `Seq` module\n/// </summary>\npublic partial class Seq\n{\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> flatten<A>(Seq<Seq<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Create an empty sequence\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> empty<A>() =>\n        Seq<A>.Empty;\n\n    /// <summary>\n    /// Construct a sequence from a single item and a tail sequence\n    /// </summary>\n    /// <param name=\"head\">Head item</param>\n    /// <param name=\"tail\">Tail sequence</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> cons<A>(A head, Seq<A> tail) =>\n        head.Cons(tail);\n    \n    /// <summary>\n    /// Create an empty sequence\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> singleton<A>(A value) =>\n        [value];\n\n    /// <summary>\n    /// Create a new empty sequence\n    /// </summary>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> create<A>() =>\n        Seq<A>.Empty;\n\n    /// <summary>\n    /// Create a sequence from a initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    public static Seq<A> create<A>(params A[] items)\n    {\n        if (items.Length == 0) return Seq<A>.Empty;\n        var nitems = new A[items.Length];\n        System.Array.Copy(items, nitems, items.Length);\n        return FromArray(items);\n    }\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> createRange<A>(ReadOnlySpan<A> items) =>\n        items.Length == 0 ? Seq<A>.Empty : new (items);\n\n    /// <summary>\n    /// Create a sequence from an initial set of items\n    /// </summary>\n    /// <param name=\"items\">Items</param>\n    /// <returns>sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> createRange<A>(IEnumerable<A> items) =>\n        new (items);\n\n    /// <summary>\n    /// Generates a sequence of A using the provided delegate to initialise\n    /// each item.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> generate<A>(int count, Func<int, A> generator) =>\n        IterableExtensions.AsIterable(Range(0, count)).Map(generator).ToSeq();\n\n    /// <summary>\n    /// Generates a sequence that contains one repeated value.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> repeat<A>(A item, int count) =>\n        IterableExtensions.AsIterable(Range(0, count)).Map(_ => item).ToSeq();\n\n    /// <summary>\n    /// Get the item at the head (first) of the sequence\n    /// </summary>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>Head item</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> head<A>(Seq<A> list) => \n        list.Head;\n\n    /// <summary>\n    /// Get the last item of the sequence\n    /// </summary>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>Last item</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> last<A>(Seq<A> list) =>\n        list.Last;\n\n    /// <summary>\n    /// Get all items in the list except the last one\n    /// </summary>\n    /// <remarks>\n    /// Must evaluate the last item to know it's the last, but won't return it\n    /// </remarks>\n    /// <param name=\"list\">List</param>\n    /// <returns>The initial items (all but the last)</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> init<A>(Seq<A> list) =>\n        list.Init;\n\n    /// <summary>\n    /// Get the tail of the sequence (skips the head item)\n    /// </summary>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>Tail sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> tail<A>(Seq<A> list) =>\n        list.Tail;\n\n    /// <summary>\n    /// Projects the values in the sequence using a map function into a new sequence (Select in LINQ).\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <typeparam name=\"B\">Return sequence item type</typeparam>\n    /// <param name=\"list\">sequence to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<B> map<A, B>(Seq<A> list, Func<A, B> map) =>\n        list.Select(map);\n\n    /// <summary>\n    /// Projects the values in the sequence into a new sequence using a map function, which is also given an index value\n    /// (Select in LINQ - note that the order of the arguments of the map function are the other way around, here the index\n    /// is the first argument).\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <typeparam name=\"B\">Return sequence item type</typeparam>\n    /// <param name=\"list\">sequence to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<B> map<A, B>(Seq<A> list, Func<int, A, B> map) =>\n        toSeq(zip(list, toSeq(Range(0, int.MaxValue)), (t, i) => map(i, t)));\n\n    /// <summary>\n    /// Removes items from the sequence that do not match the given predicate (Where in LINQ)\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence to filter</param>\n    /// <param name=\"predicate\">Predicate function</param>\n    /// <returns>Filtered sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> filter<A>(Seq<A> list, Func<A, bool> predicate) =>\n        list.Where(predicate);\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the sequence. Returns the sequence \n    /// comprised of the results for each element where the function returns Some(f(x)).\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<B> choose<A, B>(Seq<A> list, Func<A, Option<B>> selector) =>\n        map(filter(map(list, selector), t => t.IsSome), t => t.Value!);\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the sequence. Returns the \n    /// sequence comprised of the results for each element where the function returns Some(f(x)).\n    /// An index value is passed through to the selector function also.\n    /// </summary>\n    /// <typeparam name=\"A\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<B> choose<A, B>(Seq<A> list, Func<int, A, Option<B>> selector) =>\n        map(filter(map(list, selector), t => t.IsSome), t => t.Value!);\n\n    /// <summary>\n    /// Reverses the sequence (Reverse in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence to reverse</param>\n    /// <returns>Reversed sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<T> rev<T>(Seq<T> list) =>\n        toSeq(list.Reverse());\n\n    /// <summary>\n    /// Concatenate two sequences (Concat in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"lhs\">First sequence</param>\n    /// <param name=\"rhs\">Second sequence</param>\n    /// <returns>Concatenated sequence</returns>\n    [Pure]\n    public static Seq<T> append<T>(Seq<T> lhs, Seq<T> rhs) =>\n        lhs.Concat(rhs);\n\n    /// <summary>\n    /// Concatenate a sequence and a sequence of sequences\n    /// </summary>\n    /// <typeparam name=\"T\">List item type</typeparam>\n    /// <param name=\"lhs\">First list</param>\n    /// <param name=\"rhs\">Second list</param>\n    /// <returns>Concatenated list</returns>\n    [Pure]\n    public static Seq<T> append<T>(Seq<T> x, Seq<Seq<T>> xs) =>\n        head(xs).IsNone\n            ? x\n            : append(x, append((Seq<T>)xs.Head, xs.Skip(1)));\n\n    /// <summary>\n    /// Concatenate N sequences\n    /// </summary>\n    /// <typeparam name=\"T\">sequence type</typeparam>\n    /// <param name=\"lists\">sequences to concatenate</param>\n    /// <returns>A single sequence with all of the items concatenated</returns>\n    [Pure]\n    public static Seq<T> append<T>(params Seq<T>[] lists) =>\n        lists.Length switch\n        {\n            0 => Seq<T>.Empty,\n            1 => lists[0],\n            _ => append(lists[0], toSeq(lists).Skip(1))\n        };\n\n    /// <summary>\n    /// Applies a function to each element of the sequence, threading an accumulator argument \n    /// through the computation. This function takes the state argument, and applies the function \n    /// to it and the first element of the sequence. Then, it passes this result into the function \n    /// along with the second element, and so on. Finally, it returns the list of intermediate \n    /// results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static Seq<S> scan<S, T>(Seq<T> list, S state, Func<S, T, S> folder)\n    {\n        IEnumerable<S> Yield()\n        {\n            yield return state;\n            foreach (var item in list)\n            {\n                state = folder(state, item);\n                yield return state;\n            }\n        }\n        return toSeq(Yield());\n    }\n\n    /// <summary>\n    /// Applies a function to each element of the sequence (from last element to first), \n    /// threading an accumulator argument through the computation. This function takes the state \n    /// argument, and applies the function to it and the first element of the sequence. Then, it \n    /// passes this result into the function along with the second element, and so on. Finally, \n    /// it returns the list of intermediate results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Enumerable item type</typeparam>\n    /// <param name=\"list\">Enumerable to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<S> scanBack<S, T>(Seq<T> list, S state, Func<S, T, S> folder) =>\n        scan(rev(list), state, folder);\n\n    /// <summary>\n    /// Joins two sequences together either into a single sequence using the join \n    /// function provided\n    /// </summary>\n    /// <param name=\"list\">First sequence to join</param>\n    /// <param name=\"other\">Second sequence to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<V> zip<T, U, V>(Seq<T> list, Seq<U> other, Func<T, U, V> zipper) =>\n        toSeq(list.Zip(other, zipper));\n\n    /// <summary>\n    /// Joins two sequences together either into an sequence of tuples\n    /// </summary>\n    /// <param name=\"list\">First sequence to join</param>\n    /// <param name=\"other\">Second sequence to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined sequence of tuples</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<(T First, U Second)> zip<T, U>(Seq<T> list, Seq<U> other) =>\n        toSeq(list.Zip(other, (t, u) => (t, u)));\n\n\n    /// <summary>\n    /// Returns true if all items in the sequence match a predicate (Any in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence to test</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the sequence match the predicate</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool forall<T>(Seq<T> list, Func<T, bool> pred) =>\n        list.ForAll(pred);\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<T> distinct<T>(Seq<T> list) =>\n        toSeq(list.Distinct());\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<T> distinct<EQ, T>(Seq<T> list) where EQ : Eq<T> =>\n        toSeq(list.Distinct(new EqCompare<T>(static (x, y) => EQ.Equals(x, y), static x => EQ.GetHashCode(x))));\n\n    /// <summary>\n    /// Return a new sequence with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <returns>A new sequence with all duplicate values removed</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<T> distinct<T, K>(Seq<T> list, Func<T, K> keySelector, Option<Func<K, K, bool>> compare = default) =>\n        toSeq(list.Distinct(new EqCompare<T>(\n                                (a, b) => compare.IfNone(EqDefault<K>.Equals)(keySelector(a), keySelector(b)), \n                                a => compare.Match(Some: _  => 0, None: () => EqDefault<K>.GetHashCode(keySelector(a))))));\n\n    /// <summary>\n    /// Returns a new sequence with the first 'count' items from the sequence provided\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first 'count' items from the sequence provided</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<T> take<T>(Seq<T> list, int count) =>\n        list.Take(count);\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first items that match the predicate</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<T> takeWhile<T>(Seq<T> list, Func<T, bool> pred) =>\n        list.TakeWhile(pred);\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't.  An index value is also provided to the predicate function.\n    /// </summary>\n    /// <typeparam name=\"T\">sequence item type</typeparam>\n    /// <param name=\"list\">sequence</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new sequence with the first items that match the predicate</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<T> takeWhile<T>(Seq<T> list, Func<T, int, bool> pred) =>\n        list.TakeWhile(pred);\n\n    /// <summary>\n    /// The tails function returns all final segments of the argument, longest first. For example:\n    /// \n    ///     tails(['a','b','c']) == [['a','b','c'], ['b','c'], ['c'],[]]\n    /// </summary>\n    /// <typeparam name=\"A\">Seq item type</typeparam>\n    /// <param name=\"self\">Seq</param>\n    /// <returns>Seq of Seq of A</returns>\n    [Pure]\n    public static Seq<Seq<A>> tails<A>(Seq<A> self)\n    {\n        var res = Seq<Seq<A>>.Empty;\n        while (!self.IsEmpty)\n        {\n            res = self.Cons(res);\n            self = self.Tail;\n        }\n        return rev(res);\n    }\n\n    /// <summary>\n    /// The tailsr function returns all final segments of the argument, longest first. For example:\n    /// \n    ///     tails(['a','b','c']) == [['a','b','c'], ['b','c'], ['c'],[]]\n    /// </summary>\n    /// <remarks>Differs from `tails` in implementation only.  The `tailsr` uses recursive processing\n    /// whereas `tails` uses a while loop aggregation followed by a reverse.  For small sequences \n    /// `tailsr` is probably more efficient. </remarks>\n    /// <typeparam name=\"A\">Seq item type</typeparam>\n    /// <param name=\"self\">Seq</param>\n    /// <returns>Seq of Seq of A</returns>\n    [Pure]\n    public static Seq<Seq<A>> tailsr<A>(Seq<A> self) =>\n        self.Match(\n            () => Seq<Seq<A>>.Empty,\n            xs => xs.Cons(tailsr(xs.Tail)));\n\n    /// <summary>\n    /// Span, applied to a predicate 'pred' and a list, returns a tuple where first element is \n    /// longest prefix (possibly empty) of elements that satisfy 'pred' and second element is the \n    /// remainder of the list:\n    /// </summary>\n    /// <example>\n    /// Seq.span(Seq(1,2,3,4,1,2,3,4), x => x 〈 3) == (Seq(1,2), Seq(3,4,1,2,3,4))\n    /// </example>\n    /// <example>\n    /// Seq.span(Seq(1,2,3), x => x 〈 9) == (Seq(1,2,3), Seq())\n    /// </example>\n    /// <example>\n    /// Seq.span(Seq(1,2,3), x => x 〈 0) == (Seq(), Seq(1,2,3))\n    /// </example>\n    /// <typeparam name=\"T\">List element type</typeparam>\n    /// <param name=\"self\">List</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Split list</returns>\n    [Pure]\n    public static (Seq<T>, Seq<T>) span<T>(Seq<T> self, Func<T, bool> pred)\n    {\n        int index = 0;\n        foreach (var item in self)\n        {\n            if (!pred(item))\n            {\n                break;\n            }\n            index++;\n        }\n        return (self.Take(index), self.Skip(index));\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static Seq<A> FromSingleValue<A>(A value) =>\n        new (SeqStrict<A>.FromSingleValue(value));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static Seq<A> FromArray<A>(A[] value) =>\n        new (new SeqStrict<A>(value, 0, value.Length, 0, 0));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static Seq<A> FromArray<A>(A[] value, int length) =>\n        new (new SeqStrict<A>(value, 0, length, 0, 0));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/Seq.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Cons sequence\n/// Represents a sequence of values in a similar way to IEnumerable, but without the\n/// issues of multiple evaluation for key LINQ operators like Skip, Count, etc.\n/// </summary>\n/// <typeparam name=\"A\">Type of the values in the sequence</typeparam>\n[CollectionBuilder(typeof(Seq), nameof(Seq.createRange))]\npublic readonly struct Seq<A> :\n    IEnumerable<A>,\n    IComparable<Seq<A>>, \n    IEquatable<Seq<A>>, \n    IComparable,\n    IComparisonOperators<Seq<A>, Seq<A>, bool>,\n    IAdditionOperators<Seq<A>, Seq<A>, Seq<A>>,\n    IAdditiveIdentity<Seq<A>, Seq<A>>,\n    Monoid<Seq<A>>,\n    K<Seq, A>\n{\n    /// <summary>\n    /// Empty sequence\n    /// </summary>\n    public static Seq<A> Empty { get; } = new(SeqEmptyInternal<A>.Default);\n\n    /// <summary>\n    /// Internal representation of the sequence (SeqStrict|SeqLazy|SeqEmptyInternal)\n    /// </summary>\n    readonly ISeqInternal<A> value;\n\n    /// <summary>\n    /// Internal value accessor - protects against `default`\n    /// </summary>\n    internal ISeqInternal<A> Value\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value ?? SeqEmptyInternal<A>.Default;\n    }\n\n    /// <summary>\n    /// Constructor from lazy sequence\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq(IEnumerable<A> ma) : this(new SeqLazy<A>(ma)) { }\n\n    /// <summary>\n    /// Constructor from lazy sequence\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq(ReadOnlySpan<A> ma) : this(Seq.FromArray(ma.ToArray())) { }\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal Seq(ISeqInternal<A> value) =>\n        this.value = value;\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    [Pure]\n    public object? Case =>\n        IsEmpty \n            ? null\n            : Tail.IsEmpty \n                ? Head.Value\n                : (Head.Value, Tail);\n\n    public void Deconstruct(out A head, out Seq<A> tail)\n    {\n        head = Head.IfNone(() => throw Exceptions.SequenceEmpty);\n        tail = Tail;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan() =>\n        Value.AsSpan();\n\n    /// <summary>\n    /// Head lens\n    /// </summary>\n    public static Lens<Seq<A>, A> head => Lens<Seq<A>, A>.New(\n        Get: la => la.IsEmpty ? throw new IndexOutOfRangeException() : la[0],\n        Set: a => la => la.IsEmpty ? throw new IndexOutOfRangeException() : a.Cons(la.Tail)\n    );\n\n    /// <summary>\n    /// Head or none lens\n    /// </summary>\n    public static Lens<Seq<A>, Option<A>> headOrNone => Lens<Seq<A>, Option<A>>.New(\n        Get: la => la.Head,\n        Set: a => la => la.IsEmpty || a.IsNone ? la : a.Value.Cons(la.Tail!)!\n    );\n\n    /// <summary>\n    /// Tail lens\n    /// </summary>\n    public static Lens<Seq<A>, Seq<A>> tail => Lens<Seq<A>, Seq<A>>.New(\n        Get: la => la.IsEmpty ? Empty : la.Tail,\n        Set: a => la => la.IsEmpty ? a : ((A)la.Head).Cons(a)\n    );\n\n    /// <summary>\n    /// Last lens\n    /// </summary>\n    public static Lens<Seq<A>, A> last => Lens<Seq<A>, A>.New(\n        Get: la => la.IsEmpty ? throw new IndexOutOfRangeException() : (A)la.Last,\n        Set: a => la => la.IsEmpty ? throw new IndexOutOfRangeException() : la.Take(la.Count - 1).Add(a)\n    );\n\n    /// <summary>\n    /// Last or none lens\n    /// </summary>\n    public static Lens<Seq<A>, Option<A>> lastOrNone => Lens<Seq<A>, Option<A>>.New(\n        Get: la => la.Last,\n        Set: a => la => la.IsEmpty || a.IsNone ? la : la.Take(la.Count - 1).Add(a.Value!));\n\n    /// <summary>\n    /// Lens map\n    /// </summary>\n    [Pure]\n    public static Lens<Seq<A>, Seq<B>> map<B>(Lens<A, B> lens) => Lens<Seq<A>, Seq<B>>.New(\n        Get: la => la.Map(lens.Get),\n        Set: lb => la => la.Zip(lb).Map(ab => lens.Set(ab.Item2, ab.Item1))\n    );\n\n    /// <summary>\n    /// Indexer\n    /// </summary>\n    /// <exception cref=\"IndexOutOfRangeException\"></exception>\n    public A this[Index index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value[index.IsFromEnd ? index.GetOffset(Count) : index.Value];\n    }\n\n    /// <summary>\n    /// Add an item to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the item \n    /// can be appended\n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Add(A value) =>\n        new (Value.Add(value));\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Concat(IEnumerable<A> items) =>\n        items switch\n        {\n            Lst<A> lst              => Concat(lst),\n            Set<A> set              => Concat(set),\n            HashSet<A> hset         => Concat(hset),\n            Arr<A> arr              => Concat(arr),\n            Stck<A> stck            => Concat(stck),\n            IReadOnlyList<A> rolist => Concat(rolist),\n            _                       => new Seq<A>(EnumerableOptimal.ConcatFast(this, items))\n        };\n                           \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Concat(in Lst<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return this;\n        }\n        var arr = items.Value.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n                           \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Concat(in ReadOnlySpan<A> items)\n    {\n        if (items.Length == 0)\n        {\n            return this;\n        }\n        var arr = items.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n        \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Concat(in Set<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return this;\n        }\n        var arr = items.Value.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n                \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Concat(in HashSet<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return this;\n        }\n        var arr = items.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n        \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Concat(in Stck<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return this;\n        }\n        var arr = items.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n\n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Concat(IReadOnlyCollection<A> items)\n    {\n        if (items.Count == 0)\n        {\n            return this;\n        }\n\n        var arr = items.ToArray();\n        return Concat(Seq.FromArray(arr));\n    }\n        \n    /// <summary>\n    /// Add a range of items to the end of the sequence\n    /// </summary>\n    /// <remarks>\n    /// Forces evaluation of the entire lazy sequence so the items\n    /// can be appended.  \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Concat(in Seq<A> rhs)\n    {\n        switch(Value.Type)\n        {\n            case SeqType.Empty:\n                // lhs is empty, so just return rhs\n                return rhs;\n\n            case SeqType.Lazy:\n\n                switch (rhs.Value.Type)\n                {\n                    // lhs lazy, rhs empty\n                    // return lhs\n                    case SeqType.Empty:\n                        return this;\n\n                    // lhs lazy, rhs lazy\n                    // return SeqConcat\n                    case SeqType.Lazy:\n                        return new Seq<A>(new SeqConcat<A>(Seq(value, rhs.value)));\n\n                    // lhs lazy, rhs strict\n                    // force lhs to be strict and concat the two \n                    case SeqType.Strict:\n                        return new Seq<A>(((SeqStrict<A>)value.Strict()).Append((SeqStrict<A>)rhs.value));\n\n                    // lhs lazy, rhs concat\n                    // prepend rhs with lhs\n                    case SeqType.Concat:\n                        return new Seq<A>(((SeqConcat<A>)rhs.value).ConsSeq(value));\n                }\n                break;\n\n            case SeqType.Strict:\n\n                switch (rhs.Value.Type)\n                {\n                    // lhs strict, rhs empty\n                    // return lhs\n                    case SeqType.Empty:\n                        return this;\n\n                    // lhs strict, rhs lazy\n                    // return SeqConcat\n                    case SeqType.Lazy:\n                        return new Seq<A>(new SeqConcat<A>(Seq(value, rhs.value)));\n\n                    // lhs strict, rhs strict\n                    // append the two\n                    case SeqType.Strict:\n                        return new Seq<A>(((SeqStrict<A>)value).Append((SeqStrict<A>)rhs.value));\n\n                    // lhs strict, rhs concat\n                    // prepend rhs with lhs\n                    case SeqType.Concat:\n                        return new Seq<A>(((SeqConcat<A>)rhs.value).ConsSeq(value));\n                }\n                break;\n\n            case SeqType.Concat:\n\n                switch (rhs.Value.Type)\n                {\n                    // lhs concat, rhs empty\n                    // return lhs\n                    case SeqType.Empty:\n                        return this;\n\n                    // lhs concat, rhs lazy || lhs concat, rhs strict\n                    // add rhs to concat\n                    case SeqType.Lazy:\n                    case SeqType.Strict:\n                        return new Seq<A>(((SeqConcat<A>)value).AddSeq(rhs.value));\n\n                    // lhs concat, rhs concat\n                    // add rhs to concat\n                    case SeqType.Concat:\n                        return new Seq<A>(((SeqConcat<A>)value).AddSeqRange(((SeqConcat<A>)rhs.value).ms));\n                }\n                break;\n        }\n        throw new NotSupportedException();\n    }\n\n    /// <summary>\n    /// Prepend an item to the sequence\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal Seq<A> Cons(A value) =>\n        new (Value.Cons(value));\n\n    /// <summary>\n    /// Head item in the sequence.\n    /// </summary>\n    /// <remarks>\n    /// If `IsEmpty` is `true` then Head is undefined and therefore returns `None`\n    /// </remarks>\n    public Option<A> Head\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.IsEmpty \n                   ? None\n                   : Value.Head;\n    }\n\n    /// <summary>\n    /// Tail of the sequence\n    /// </summary>\n    public Seq<A> Tail\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new (Value.Tail);\n    }\n\n    /// <summary>\n    /// Get all items except the last one\n    /// </summary>\n    public Seq<A> Init\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => new (Value.Init);\n    }\n\n    /// <summary>\n    /// Last item in sequence\n    /// </summary>\n    public Option<A> Last\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => Value.IsEmpty\n                   ? None\n                   : Some(Value.Last);\n    }\n\n    /// <summary>\n    /// Returns true if the sequence is empty\n    /// </summary>\n    /// <remarks>\n    /// For lazy streams this will have to peek at the first \n    /// item.  So, the first item will be consumed.\n    /// </remarks>\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Returns the number of items in the sequence\n    /// </summary>\n    /// <returns>Number of items in the sequence</returns>\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n        \n    /// <summary>\n    /// Alias of `Count`\n    /// </summary>\n    /// <returns>Number of items in the sequence</returns>\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerable<A> AsEnumerable() => \n        this;\n\n    /*\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public StreamT<M, A> AsStream<M>()\n        where M : Monad<M> =>\n        StreamT<M, A>.Lift(AsEnumerable());\n        */\n\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> AsIterable() => \n       Iterable.createRange(AsEnumerable());\n\n    /// <summary>\n    /// Match empty sequence, or multi-item sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"Tail\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(\n        Func<B> Empty,\n        Func<A, Seq<A>, B> Tail) =>\n        IsEmpty\n            ? Empty()\n            : Tail((A)Head, this.Tail);\n\n    /// <summary>\n    /// Match empty sequence, or one item sequence, or multi-item sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"Tail\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(\n        Func<B> Empty,\n        Func<A, B> Head,\n        Func<A, Seq<A>, B> Tail) =>\n        IsEmpty\n            ? Empty()\n            : this.Tail.IsEmpty\n                ? Head((A)this.Head)\n                : Tail((A)this.Head, this.Tail);\n\n    /// <summary>\n    /// Match empty sequence, or multi-item sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"Sequence\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(\n        Func<B> Empty,\n        Func<Seq<A>, B> Seq) =>\n        IsEmpty\n            ? Empty()\n            : Seq(this);\n\n    /// <summary>\n    /// Match empty sequence, or one item sequence, or multi-item sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Return value type</typeparam>\n    /// <param name=\"Empty\">Match for an empty list</param>\n    /// <param name=\"Tail\">Match for a non-empty</param>\n    /// <returns>Result of match function invoked</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(\n        Func<B> Empty,\n        Func<A, B> Head,\n        Func<Seq<A>, B> Tail) =>\n        IsEmpty\n            ? Empty()\n            : this.Tail.IsEmpty\n                ? Head((A)this.Head)\n                : Tail(this.Tail);\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Do(Action<A> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Seq<B>> Traverse<F, B>(Func<A, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, Seq<B>> TraverseM<M, B>(Func<A, K<M, B>> f) \n        where M : Monad<M> =>\n        M.Map(x => x.As(), Traversable.traverseM(f, this));\n    \n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public Seq<B> Map<B>(Func<A, B> f)\n    {\n        return new Seq<B>(new SeqLazy<B>(Yield(this)));\n        IEnumerable<B> Yield(Seq<A> items)\n        {\n            foreach (var item in items)\n            {\n                yield return f(item);\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <remarks>\n    /// Exposes an index for each map \n    /// </remarks>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    public Seq<B> Map<B>(Func<A, int, B> f)\n    {\n        return new Seq<B>(new SeqLazy<B>(Yield(this)));\n        IEnumerable<B> Yield(Seq<A> items)\n        {\n            var ix = 0;\n            foreach (var item in items)\n            {\n                yield return f(item, ix);\n                ix++;\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Map the sequence using the function provided\n    /// </summary>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Seq<B> Bind<B>(Func<A, Seq<B>> f)\n    {\n        static IEnumerable<B> Yield(Seq<A> ma, Func<A, Seq<B>> bnd)\n        {\n            foreach (var a in ma)\n            {\n                foreach (var b in bnd(a))\n                {\n                    yield return b;\n                }\n            }\n        }\n        return new Seq<B>(Yield(this, f));\n    }\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Seq<B> Bind<B>(Func<A, K<Seq, B>> f)\n    {\n        static IEnumerable<B> Yield(K<Seq, A> ma, Func<A, K<Seq, B>> bnd)\n        {\n            foreach (var a in ma.As())\n            {\n                foreach (var b in bnd(a).As())\n                {\n                    yield return b;\n                }\n            }\n        }\n        return new Seq<B>(Yield(this, f));\n    }\n\n    /// <summary>\n    /// Monadic bind (flatmap) of the sequence\n    /// </summary>\n    /// <typeparam name=\"B\">Bound return value type</typeparam>\n    /// <param name=\"bind\">Bind function</param>\n    /// <returns>Flat-mapped sequence</returns>\n    [Pure]\n    public Seq<C> SelectMany<B, C>(Func<A, Seq<B>> bind, Func<A, B, C> project)\n    {\n        static IEnumerable<C> Yield(Seq<A> ma, Func<A, Seq<B>> bnd, Func<A, B, C> prj)\n        {\n            foreach (var a in ma)\n            {\n                foreach (var b in bnd(a))\n                {\n                    yield return prj(a, b);\n                }\n            }\n        }\n        return new Seq<C>(Yield(this, bind, project));\n    }\n\n    /// <summary>\n    /// Filter the items in the sequence\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply to the items</param>\n    /// <returns>Filtered sequence</returns>\n    [Pure]\n    public Seq<A> Filter(Func<A, bool> f)\n    {\n        return new Seq<A>(new SeqLazy<A>(Yield(this, f)));\n        static IEnumerable<A> Yield(Seq<A> items, Func<A, bool> f)\n        {\n            foreach (var item in items)\n            {\n                if (f(item))\n                {\n                    yield return item;\n                }\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Filter the items in the sequence\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply to the items</param>\n    /// <returns>Filtered sequence</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Where(Func<A, bool> f) =>\n        Filter(f);\n\n    /// <summary>\n    /// Returns true if the supplied predicate returns true for any\n    /// item in the sequence.  False otherwise.\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply</param>\n    /// <returns>True if the supplied predicate returns true for any\n    /// item in the sequence.  False otherwise.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<A, bool> f) =>\n        Value.Exists(f);\n\n    /// <summary>\n    /// Returns true if the supplied predicate returns true for all\n    /// items in the sequence.  False otherwise.  If there is an \n    /// empty sequence then true is returned.\n    /// </summary>\n    /// <param name=\"f\">Predicate to apply</param>\n    /// <returns>True if the supplied predicate returns true for all\n    /// items in the sequence.  False otherwise.  If there is an \n    /// empty sequence then true is returned.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<A, bool> f) =>\n        Value.ForAll(f);\n\n    /// <summary>\n    /// Returns true if the sequence has items in it\n    /// </summary>\n    /// <returns>True if the sequence has items in it</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Any() =>\n        !IsEmpty;\n\n    /// <summary>\n    /// Inject a value in between each item in the sequence \n    /// </summary>\n    /// <param name=\"ma\">Sequence to inject values into</param>\n    /// <param name=\"value\">Item to inject</param>\n    /// <typeparam name=\"A\">Bound type</typeparam>\n    /// <returns>A sequence with the values injected</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Intersperse(A value) =>\n        toSeq(Value.Intersperse(value));\n\n    /// <summary>\n    /// Get the hash code for all of the items in the sequence, or 0 if empty\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            Seq<A> s         => CompareTo(s),\n            IEnumerable<A> e => CompareTo(toSeq(e)),\n            _                => 1\n        };\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        Value is SeqLazy<A>\n            ? CollectionFormat.ToShortArrayString(this)\n            : CollectionFormat.ToShortArrayString(this, Count);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(this, separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(this, separator);\n\n    [Pure]\n    public Seq<A> Combine(Seq<A> y) =>\n        this + y;\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> operator +(Seq<A> x, Seq<A> y) =>\n        x.Concat(y);\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> operator +(A x, Seq<A> y) =>\n        x.Cons(y);\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> operator +(Seq<A> x, A y) =>\n        x.Add(y);\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> operator +(Seq<A> x, K<Seq, A> y) =>\n        x.Concat(y.As());\n\n    /// <summary>\n    /// Append operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> operator +(K<Seq, A> x, Seq<A> y) =>\n        x.As().Concat(y);\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> operator |(Seq<A> x, K<Seq, A> y) =>\n        x.Choose(y).As();\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> operator |(K<Seq, A> x, Seq<A> y) =>\n        x.Choose(y).As();\n\n    /// <summary>\n    /// Ordering operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >(Seq<A> x, Seq<A> y) =>\n        x.CompareTo(y) > 0;\n\n    /// <summary>\n    /// Ordering operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >=(Seq<A> x, Seq<A> y) =>\n        x.CompareTo(y) >= 0;\n\n    /// <summary>\n    /// Ordering  operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <(Seq<A> x, Seq<A> y) =>\n        x.CompareTo(y) < 0;\n\n    /// <summary>\n    /// Ordering  operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <=(Seq<A> x, Seq<A> y) =>\n        x.CompareTo(y) <= 0;\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(Seq<A> x, Seq<A> y) =>\n        x.Equals(y);\n\n    /// <summary>\n    /// Non-equality operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(Seq<A> x, Seq<A> y) =>\n        !(x == y);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj switch\n        {\n            Seq<A> s         => Equals(s),\n            IEnumerable<A> e => Equals(toSeq(e)),\n            _                => false\n        };\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(Seq<A> rhs) =>\n        Equals<EqDefault<A>>(rhs);\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    [Pure]\n    public bool Equals<EqA>(Seq<A> rhs) where EqA : Eq<A>\n    {\n        // Differing lengths?\n        if(Count != rhs.Count) return false;\n\n        // If the hash code has been calculated on both sides then \n        // check for differences\n        if (GetHashCode() != rhs.GetHashCode())\n        {\n            return false;\n        }\n\n        // Iterate through both sides\n        using var iterA = GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            if (!EqA.Equals(iterA.Current, iterB.Current))\n            {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /// <summary>\n    /// Skip count items\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Skip(int amount) =>\n        amount < 1\n            ? this\n            : new Seq<A>(Value.Skip(amount));\n\n    /// <summary>\n    /// Take count items\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Take(int amount) =>\n        amount < 1\n            ? Empty\n            : new Seq<A>(Value.Take(amount));\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate \n    /// provided, and stopping as soon as one doesn't\n    /// </summary>\n    /// <returns>A new sequence with the first items that match the \n    /// predicate</returns>\n    [Pure]\n    public Seq<A> TakeWhile(Func<A, bool> pred)\n    {\n        return new Seq<A>(new SeqLazy<A>(Yield(Value, pred)));\n        IEnumerable<A> Yield(IEnumerable<A> xs, Func<A, bool> f)\n        {\n            foreach (var x in xs)\n            {\n                if (!f(x)) break;\n                yield return x;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Iterate the sequence, yielding items if they match the predicate \n    /// provided, and stopping as soon as one doesn't.  An index value is \n    /// also provided to the predicate function.\n    /// </summary>\n    /// <returns>A new sequence with the first items that match the \n    /// predicate</returns>\n    [Pure]\n    public Seq<A> TakeWhile(Func<A, int, bool> pred)\n    {\n        return new Seq<A>(new SeqLazy<A>(Yield(Value, pred)));\n        IEnumerable<A> Yield(IEnumerable<A> xs, Func<A, int, bool> f)\n        {\n            var i = 0;\n            foreach (var x in xs)\n            {\n                if (!f(x, i)) break;\n                yield return x;\n                i++;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Returns all initial segments of the sequence, shortest first\n    /// </summary>\n    /// <remarks>\n    /// Including the empty sequence\n    /// </remarks>\n    /// <example>\n    ///\n    ///      Seq(\"a\", \"b\", \"c\").Inits\n    ///\n    ///      > Seq(Seq(), Seq(\"a\"), Seq(\"a\", \"b\"), Seq(\"a\", \"b\", \"c\"))  \n    ///     \n    /// </example>\n    /// <returns>Initial segments of the sequence</returns>\n    public Seq<Seq<A>> Inits =>\n        [Seq<A>()] + NonEmptyInits;\n\n    /// <summary>\n    /// Returns all initial segments of the sequence, shortest first.\n    /// </summary>\n    /// <remarks>\n    /// Not including the empty sequence\n    /// </remarks>\n    /// <example>\n    ///\n    ///      Seq(\"a\", \"b\", \"c\").Inits\n    ///\n    ///      > Seq(Seq(\"a\"), Seq(\"a\", \"b\"), Seq(\"a\", \"b\", \"c\"))  \n    ///     \n    /// </example>\n    /// <returns>Initial segments of the sequence</returns>\n    public Seq<Seq<A>> NonEmptyInits\n    {\n        get\n        {\n            var mma = Seq<Seq<A>>();\n            for (var i = 1; i <= Count; i++)\n            {\n                mma = mma.Add(Take(i));\n            }\n            return mma;\n        }\n    }\n        \n    /// <summary>\n    /// Returns all final segments of the argument, longest first.\n    /// </summary>\n    /// <remarks>\n    /// Including the empty sequence\n    /// </remarks>\n    /// <example>\n    ///\n    ///      Seq(\"a\", \"b\", \"c\").Tails\n    ///\n    ///      > Seq(Seq(\"a\", \"b\", \"c\"), Seq(\"a\", \"b\"), Seq(\"a\"), Seq())  \n    ///     \n    /// </example>\n    /// <returns>Initial segments of the sequence</returns>\n    public Seq<Seq<A>> Tails\n    {\n        get\n        {\n            return new Seq<Seq<A>>(go(this)); \n            static IEnumerable<Seq<A>> go(Seq<A> ma)\n            {\n                while (!ma.IsEmpty)\n                {\n                    yield return ma;\n                    ma = ma.Tail;\n                }\n                yield return Empty;\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Returns all final segments of the argument, longest first.\n    /// </summary>\n    /// <remarks>\n    /// Not including the empty sequence\n    /// </remarks>\n    /// <example>\n    ///\n    ///      Seq(\"a\", \"b\", \"c\").Tails\n    ///\n    ///      > Seq(Seq(\"a\", \"b\", \"c\"), Seq(\"a\", \"b\"), Seq(\"a\"))  \n    ///     \n    /// </example>\n    /// <returns>Initial segments of the sequence</returns>\n    public Seq<Seq<A>> NonEmptyTails\n    {\n        get\n        {\n            return new Seq<Seq<A>>(go(this)); \n            static IEnumerable<Seq<A>> go(Seq<A> ma)\n            {\n                while (!ma.IsEmpty)\n                {\n                    yield return ma;\n                    ma = ma.Tail;\n                }\n            }\n        }\n    }\n        \n    /// <summary>\n    /// Partition a list into two based on  a predicate\n    /// </summary>\n    /// <param name=\"predicate\">True if the item goes in the first list, false for the second list</param>\n    /// <returns>Pair of lists</returns>\n    public (Seq<A> First, Seq<A> Second) Partition(Func<A, bool> predicate)\n    {\n        var f = Seq<A>();\n        var s = Seq<A>();\n        foreach (var item in this)\n        {\n            if (predicate(item))\n            {\n                f = f.Add(item);\n            }\n            else\n            {\n                s = s.Add(item);\n            }\n        }\n        return (f, s);\n    }\n\n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public int CompareTo(Seq<A> rhs) =>\n        CompareTo<OrdDefault<A>>(rhs);\n\n    /// <summary>\n    /// Compare to another sequence\n    /// </summary>\n    [Pure]\n    public int CompareTo<OrdA>(Seq<A> rhs) where OrdA : Ord<A>\n    {\n        // Differing lengths?\n        var cmp = Count.CompareTo(rhs.Count);\n        if (cmp != 0) return cmp;\n\n        // Iterate through both sides\n        using var iterA = GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            cmp = OrdA.Compare(iterA.Current, iterB.Current);\n            if (cmp != 0) return cmp;\n        }\n\n        return 0;\n    }\n\n    /// <summary>\n    /// Force all items lazy to stream\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Strict() => \n        new (Value.Strict());\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerator<A> GetEnumerator() =>\n        Value.GetEnumerator();\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Seq<A>(SeqEmpty _) =>\n        Empty;\n\n    [Pure]\n    public Seq<B> Cast<B>()\n    {\n        IEnumerable<B> Yield(Seq<A> ma)\n        {\n            foreach (object? item in ma)\n            {\n                if( item is B b) yield return b;\n            }\n        }\n\n        return Value is IEnumerable<B> mb\n                   ? new Seq<B>(mb)\n                   : new Seq<B>(Yield(this));\n    }\n\n    public static Seq<A> AdditiveIdentity => \n        Empty;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/SeqEmpty.cs",
    "content": "﻿namespace LanguageExt;\n\n/// <summary>\n/// A unit type that represents `Seq.Empty`.  This type can be implicitly\n/// converted to `Seq〈A〉`.\n/// </summary>\npublic readonly struct SeqEmpty\n{\n    public static SeqEmpty Default = new();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/SeqLoan.cs",
    "content": "﻿using System;\nusing System.Buffers;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing System.Threading;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents a sequence on loan from an `ArrayPool`\n/// </summary>\n/// <remarks>\n/// This supports rapid reading of data for use in streaming situations.  As soon as any transformations are made \n/// the backing data is baked into a Seq of A.  This involves cloning the original array (because obviously the rented\n/// array will be returned to the pool eventually).\n///\n/// You can manually call Dispose() to release the Array, however it also supports a finaliser to return the backing\n/// array back to its pool of origin.\n///\n/// NOTE: If you call Dispose() whilst using this structure on another thread, behaviour is undefined.\n/// </remarks>\n/// <typeparam name=\"A\">Bound value</typeparam>\npublic class SeqLoan<A> : IDisposable\n{\n    /// <summary>\n    /// Backing data\n    /// </summary>\n    internal readonly A[] data;\n\n    /// <summary>\n    /// The pool the date came from\n    /// </summary>\n    internal readonly ArrayPool<A> pool;\n\n    /// <summary>\n    /// Start of the sequence\n    /// </summary>\n    internal readonly int start;\n        \n    /// <summary>\n    /// Known size of the sequence\n    /// </summary>\n    internal readonly int count;\n\n    /// <summary>\n    /// Flags whether the rented array has been freed\n    /// </summary>\n    internal int freed;\n\n    /// <summary>\n    /// Cached hash code\n    /// </summary>\n    int selfHash;\n    \n    /// <summary>\n    /// Constructor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal SeqLoan(A[] data, ArrayPool<A> pool, int start, int count)\n    {\n        this.data  = data;\n        this.pool  = pool;\n        this.start = start;\n        this.count = count;\n    }\n\n    /// <summary>\n    /// Create a newly rented array\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static SeqLoan<A> Rent(ArrayPool<A> pool, int size) =>\n        new (pool.Rent(size), pool, 0, size);\n\n    /// <summary>\n    /// Create a newly rented array\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static SeqLoan<A> Rent(int size) =>\n        Rent(ArrayPool<A>.Shared, size);\n        \n    /// <summary>\n    /// Indexer\n    /// </summary>\n    public A this[int index]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => freed == 1 || index < 0 || index >= count\n                   ? throw new IndexOutOfRangeException()\n                   : data[start + index];\n    }\n\n    /// <summary>\n    /// Head item in the sequence.  NOTE:  If `IsEmpty` is true then Head\n    /// is undefined.  Call HeadOrNone() if for maximum safety.\n    /// </summary>\n    [Pure]\n    public A Head\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => freed == 1 || count == 0\n                   ? throw Exceptions.SequenceEmpty\n                   : data[start];\n    }\n\n    /// <summary>\n    /// Clone to a Seq\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> ToSeq()\n    {\n        if(freed == 1) return Seq<A>.Empty;\n        var ndata = new A[data.Length];\n        Array.Copy(data, start, ndata, start, count);\n        return new Seq<A>(new SeqStrict<A>(ndata, start, count, 0, 0));\n    }\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> ToReadOnlySpan() =>\n        freed == 1 \n            ? new ReadOnlySpan<A>(Array.Empty<A>(), 0, 0)\n            : new ReadOnlySpan<A>(data, start, count);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Span<A> ToSpan() =>\n        freed == 1 \n            ? new Span<A>(Array.Empty<A>(), 0, 0)\n            : new Span<A>(data, start, count);\n\n    /// <summary>\n    /// Tail of the sequence\n    /// </summary>\n    [Pure]\n    public Seq<A> Tail\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => freed == 1 \n                   ? Seq<A>.Empty\n                   : ToSeq().Tail;\n    }\n\n    [Pure]\n    public Seq<A> Init\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => freed == 1 \n                   ? Seq<A>.Empty\n                   : ToSeq().Tail;\n    }\n\n    /// <summary>\n    /// Returns true if the sequence is empty\n    /// </summary>\n    /// <remarks>\n    /// For lazy streams this will have to peek at the first \n    /// item.  So, the first item will be consumed.\n    /// </remarks>\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => freed == 1 || count == 0;\n    }\n\n    /// <summary>\n    /// Last item in sequence.  Throws if no items in sequence\n    /// </summary>\n    public A Last\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get =>\n            freed == 1 || IsEmpty\n                ? throw Exceptions.SequenceEmpty\n                : data[start + count - 1];\n    }\n\n    /// <summary>\n    /// Returns the number of items in the sequence\n    /// </summary>\n    /// <returns>Number of items in the sequence</returns>\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => freed == 1 ? 0 : count;\n    }\n\n    /// <summary>\n    /// Fold the sequence from the first item to the last\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"f\">Fold function</param>\n    /// <returns>Aggregated state</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, A, S> f)\n    {\n        if (freed == 1) return state;\n        var end = start + count;\n        for(var i = start; i < end; i++)\n        {\n            state = f(state, data[i]);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Fold the sequence from the last item to the first.  For \n    /// sequences that are not lazy and are less than 5000 items\n    /// long, FoldBackRec is called instead, because it is faster.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"f\">Fold function</param>\n    /// <returns>Aggregated state</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S FoldBack<S>(S state, Func<S, A, S> f)\n    {\n        if (freed == 1) return state;\n        for (var i = start + count - 1; i >= start; i--)\n        {\n            state = f(state, data[i]);\n        }\n        return state;\n    }\n\n    /// <summary>\n    /// Skip count items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Skip(int amount) =>\n        freed == 1\n            ? Seq<A>.Empty\n            : ToSeq().Skip(amount);\n        \n    /// <summary>\n    /// Take count items\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> Take(int amount) =>\n        freed == 1\n            ? Seq<A>.Empty\n            : ToSeq().Take(amount);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Enumerator GetEnumerator() =>\n        freed == 1 \n            ? new Enumerator(Array.Empty<A>(), 0, 0)\n            : new Enumerator(data, start, count);\n\n    public Unit Iter(Action<A> f)\n    {\n        var end = start + count;\n        for (var i = start; i < end; i++)\n        {\n            f(data[i]);\n        }\n        return default;\n    }\n\n    public bool Exists(Func<A, bool> f)\n    {\n        if (freed == 1) return false;\n        var end = start + count;\n        for (var i = start; i < end; i++)\n        {\n            if(f(data[i]))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public bool ForAll(Func<A, bool> f)\n    {\n        if (freed == 1) return false;\n        var end = start + count;\n        for (var i = start; i < end; i++)\n        {\n            if (!f(data[i]))\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    public Seq<A> Append(Seq<A> right) =>\n        freed == 1\n            ? right\n            : ToSeq() + right;\n\n    public Seq<A> Append(SeqLoan<A> right) =>\n        freed == 1\n            ? right.ToSeq()\n            : ToSeq() + right.ToSeq();\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        freed == 1\n            ? 0\n            : selfHash == 0\n                ? selfHash = GetHashCode(FNV32.OffsetBasis)\n                : selfHash;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    int GetHashCode(int offsetBasis) =>\n        FNV32.Hash<HashableDefault<A>, A>(data, start, count, offsetBasis);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public void Dispose() =>\n        Free();\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    ~SeqLoan() =>\n        Free();\n        \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    void Free()\n    {\n        if (Interlocked.CompareExchange(ref freed, 1, 0) == 0)\n        {\n            pool.Return(data, ClearArray);\n        }\n    }\n\n    static readonly bool ClearArray = \n        !typeof(A).IsValueType;\n        \n    public ref struct Enumerator\n    {\n        readonly A[] data;\n        readonly int count;\n        int index;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        internal Enumerator(A[] data, int index, int count)\n        {\n            this.data  = data;\n            this.count = count;\n            this.index = index;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool MoveNext()\n        {\n            var nindex = index + 1;\n            if (nindex < count)\n            {\n                index = nindex;\n                return true;\n            }\n            else\n            {\n                return false;\n            }\n        }\n\n        public ref A Current\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => ref data[index];\n        }\n    }        \n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Seq/Trait/Seq.TraitImpl.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class Seq : \n    Monad<Seq>, \n    MonoidK<Seq>,\n    Alternative<Seq>, \n    Traversable<Seq>\n{\n    static K<Seq, B> Monad<Seq>.Recur<A, B>(A value, Func<A, K<Seq, Next<A, B>>> f)\n    {\n        return toSeq(go());\n        IEnumerable<B> go()\n        {\n            List<A> values = [value];\n            List<A> next   = [];\n\n            while (true)\n            {\n                foreach (var x in values)\n                {\n                    foreach (var mb in +f(x))\n                    {\n                        if (mb.IsDone)\n                        {\n                            yield return mb.Done;\n                        }\n                        else\n                        {\n                            next.Add(mb.Loop);\n                        }\n                    }\n                }\n\n                if (next.Count == 0)\n                {\n                    break;\n                }\n                else\n                {\n                    (values, next) = (next, values);\n                    next.Clear();\n                }\n            }\n        }\n    }\n    \n    static K<Seq, B> Monad<Seq>.Bind<A, B>(K<Seq, A> ma, Func<A, K<Seq, B>> f)\n    {\n        return new Seq<B>(go());\n        IEnumerable<B> go()\n        {\n            foreach (var x in ma.As())\n            {\n                foreach (var y in f(x).As())\n                {\n                    yield return y;\n                }\n            }\n        }\n    }\n\n    static K<Seq, B> Functor<Seq>.Map<A, B>(Func<A, B> f, K<Seq, A> ma) \n    {\n        return new Seq<B>(go());\n        IEnumerable<B> go()\n        {\n            foreach (var x in ma.As())\n            {\n                yield return f(x);\n            }\n        }\n    }\n\n    static K<Seq, A> Applicative<Seq>.Pure<A>(A value) =>\n        singleton(value);\n\n    static K<Seq, B> Applicative<Seq>.Apply<A, B>(K<Seq, Func<A, B>> mf, K<Seq, A> ma) \n    {\n        return new Seq<B>(go());\n        IEnumerable<B> go()\n        {\n            foreach (var f in mf.As())\n            {\n                foreach (var a in ma.As())\n                {\n                    yield return f(a);\n                }\n            }\n        }\n    }\n\n    static K<Seq, B> Applicative<Seq>.Apply<A, B>(K<Seq, Func<A, B>> mf, Memo<Seq, A> ma) \n    {\n        return new Seq<B>(go());\n        IEnumerable<B> go()\n        {\n            foreach (var f in mf.As())\n            {\n                foreach (var a in ma.Value.As())\n                {\n                    yield return f(a);\n                }\n            }\n        }\n    }\n\n    static K<Seq, A> MonoidK<Seq>.Empty<A>() =>\n        Seq<A>.Empty;\n\n    static K<Seq, A> Alternative<Seq>.Empty<A>() =>\n        Seq<A>.Empty;\n\n    static K<Seq, A> Choice<Seq>.Choose<A>(K<Seq, A> ma, K<Seq, A> mb) => \n        ma.As().IsEmpty ? mb : ma;\n\n    static K<Seq, A> Choice<Seq>.Choose<A>(K<Seq, A> ma, Memo<Seq, A> mb) => \n        ma.As().IsEmpty ? ~mb : ma;\n\n    static K<Seq, A> SemigroupK<Seq>.Combine<A>(K<Seq, A> ma, K<Seq, A> mb) =>\n        ma.As() + mb.As();\n\n    static int Foldable<Seq>.Count<A>(K<Seq, A> ta) =>\n        ta.As().Count;\n\n    static bool Foldable<Seq>.IsEmpty<A>(K<Seq, A> ta) =>\n        ta.As().IsEmpty;\n\n    static Option<A> Foldable<Seq>.At<A>(K<Seq, A> ta, Index index)\n    {\n        var list = ta.As();\n        return index.Value >= 0 && index.Value < list.Count\n                   ? Some(list[index])\n                   : Option<A>.None;\n    }\n\n    static Option<A> Foldable<Seq>.Head<A>(K<Seq, A> ta) =>\n        ta.As().Head;\n\n    static Option<A> Foldable<Seq>.Last<A>(K<Seq, A> ta) =>\n        ta.As().Last;\n    \n    static S Foldable<Seq>.FoldWhile<A, S>(Func<A, Func<S, S>> f, Func<(S State, A Value), bool> predicate, S state, K<Seq, A> ta)\n    {\n        foreach (var x in ta.As())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(x)(state);\n        }\n        return state;\n    }\n\n    static S Foldable<Seq>.FoldBackWhile<A, S>(Func<S, Func<A, S>> f, Func<(S State, A  Value), bool> predicate, S state, K<Seq, A> ta) \n    {\n        foreach (var x in ta.As().Rev())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(state)(x);\n        }\n        return state;\n    }\n    \n    static K<F, K<Seq, B>> Traversable<Seq>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Seq, A> ta)\n    {\n        return Foldable.fold(add, F.Pure(Seq<B>.Empty), ta)\n                       .Map(bs => bs.Kind());\n\n        Func<K<F, Seq<B>>, K<F, Seq<B>>> add(A value) =>\n            state =>\n                Applicative.lift((bs, b) => bs.Add(b), state, f(value));                                            \n    }\n\n    static K<F, K<Seq, B>> Traversable<Seq>.TraverseM<F, A, B>(Func<A, K<F, B>> f, K<Seq, A> ta) \n    {\n        return Foldable.fold(add, F.Pure(Seq<B>.Empty), ta)\n                       .Map(bs => bs.Kind());\n\n        Func<K<F, Seq<B>>, K<F, Seq<B>>> add(A value) =>\n            state =>\n                state.Bind(\n                    bs => f(value).Bind(\n                        b => F.Pure(bs.Add(b)))); \n    }\n    \n    static Fold<A, S> Foldable<Seq>.FoldStep<A, S>(K<Seq, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }   \n        \n    static Fold<A, S> Foldable<Seq>.FoldStepBack<A, S>(K<Seq, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().Reverse().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Extensions/Set.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SetExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Set<B> Map<A, B>(this Func<A, B> f, K<Set, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Set<B> Map<A, B>(this Func<A, B> f, Set<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Set<B> Action<A, B>(this Set<A> ma, Set<B> mb) =>\n        Applicative.action(ma, mb).As();    \n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Set<B> Action<A, B>(this K<Set, A> ma, K<Set, B> mb) =>\n        Applicative.action(ma, mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Set<B> Apply<A, B>(this Set<Func<A, B>> mf, K<Set, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Set<B> Apply<A, B>(this K<Set, Func<A, B>> mf, K<Set, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Extensions/Set.Extensions.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SetExtensions\n{\n    public static Set<A> As<A>(this K<Set, A> ma) =>\n        (Set<A>)ma;\n    \n    /// <summary>\n    /// Convert to a queryable \n    /// </summary>\n    [Pure]\n    public static IQueryable<A> AsQueryable<A>(this Set<A> source) =>\n        // NOTE TO FUTURE ME: Don't delete this thinking it's not needed!\n        source.Value.AsQueryable();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Internal/Set.Internal.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Collections;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable set\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// [wikipedia.org/wiki/AVL_tree](http://en.wikipedia.org/wiki/AVL_tree)\n/// </summary>\n/// <typeparam name=\"A\">List item type</typeparam>\n[Serializable]\ninternal class SetInternal<OrdA, A> :\n    IEnumerable<A>,\n    IEquatable<SetInternal<OrdA, A>>\n    where OrdA : Ord<A>\n{\n    public static readonly SetInternal<OrdA, A> Empty = new ();\n    readonly SetItem<A> set;\n    int hashCode;\n\n    /// <summary>\n    /// Default ctor\n    /// </summary>\n    internal SetInternal() => set = SetItem<A>.Empty;\n\n    /// <summary>\n    /// Ctor that takes a root element\n    /// </summary>\n    /// <param name=\"root\"></param>\n    internal SetInternal(SetItem<A> root)\n    {\n        set = root;\n    }\n\n    /// <summary>\n    /// Ctor from an enumerable \n    /// </summary>\n    public SetInternal(IEnumerable<A> items) : this(items, SetModuleM.AddOpt.TryAdd)\n    {\n    }\n\n    public override int GetHashCode() =>\n        hashCode == 0\n            ? hashCode = FNV32.Hash<OrdA, A>(AsIterable())\n            : hashCode;\n\n    public Iterable<A> AsIterable()\n    {\n        IEnumerable<A> Yield()\n        {\n            using var iter = GetEnumerator();\n            while (iter.MoveNext())\n            {\n                yield return iter.Current;\n            }\n        }\n        return Iterable.createRange(Yield());\n    }\n\n    public Iterable<A> Skip(int amount)\n    {\n        return Iterable.createRange(Go());\n        IEnumerable<A> Go()\n        {\n            using var iter = new SetModule.SetEnumerator<A>(set, false, amount);\n            while (iter.MoveNext())\n            {\n                yield return iter.Current;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    internal SetInternal(IEnumerable<A> items, SetModuleM.AddOpt option)\n    {\n        set = SetItem<A>.Empty;\n\n        foreach (var item in items)\n        {\n            set = SetModuleM.Add<OrdA, A>(set, item, option);\n        }\n    }\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    internal SetInternal(ReadOnlySpan<A> items, SetModuleM.AddOpt option)\n    {\n        set = SetItem<A>.Empty;\n\n        foreach (var item in items)\n        {\n            set = SetModuleM.Add<OrdA, A>(set, item, option);\n        }\n    }\n\n    /// <summary>\n    /// Number of items in the set\n    /// </summary>\n    [Pure]\n    public int Count =>\n        set.Count;\n\n    [Pure]\n    public Option<A> Min => \n        set.IsEmpty\n            ? None\n            : SetModule.Min(set);\n\n    [Pure]\n    public Option<A> Max =>\n        set.IsEmpty\n            ? None\n            : SetModule.Max(set);\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public SetInternal<OrdA, A> Add(A value) =>\n        new (SetModule.Add<OrdA, A>(set,value));\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public SetInternal<OrdA, A> TryAdd(A value) =>\n        Contains(value)\n            ? this\n            : Add(value);\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public SetInternal<OrdA, A> AddOrUpdate(A value) =>\n        new (SetModule.AddOrUpdate<OrdA, A>(set, value));\n\n    [Pure]\n    public SetInternal<OrdA, A> AddRange(IEnumerable<A> xs)\n    {\n        if(Count == 0)\n        {\n            return new SetInternal<OrdA, A>(xs, SetModuleM.AddOpt.ThrowOnDuplicate);\n        }\n\n        var set = this;\n        foreach(var x in xs)\n        {\n            set = set.Add(x);\n        }\n        return set;\n    }\n\n    [Pure]\n    public SetInternal<OrdA, A> TryAddRange(IEnumerable<A> xs)\n    {\n        if (Count == 0)\n        {\n            return new SetInternal<OrdA, A>(xs, SetModuleM.AddOpt.TryAdd);\n        }\n\n        var set = this;\n        foreach (var x in xs)\n        {\n            set = set.TryAdd(x);\n        }\n        return set;\n    }\n\n    [Pure]\n    public SetInternal<OrdA, A> AddOrUpdateRange(IEnumerable<A> xs)\n    {\n        if (Count == 0)\n        {\n            return new SetInternal<OrdA, A>(xs, SetModuleM.AddOpt.TryUpdate);\n        }\n\n        var set = this;\n        foreach (var x in xs)\n        {\n            set = set.AddOrUpdate(x);\n        }\n        return set;\n    }\n\n    /// <summary>\n    /// Get the number of elements in the set\n    /// </summary>\n    /// <returns>Number of elements</returns>\n    [Pure]\n    public int Length() =>\n        Count;\n\n    /// <summary>\n    /// Attempts to find an item in the set.  \n    /// </summary>\n    /// <param name=\"value\">Value to find</param>\n    /// <returns>Some(T) if found, None otherwise</returns>\n    [Pure]\n    public Option<A> Find(A value) =>\n        SetModule.TryFind<OrdA, A>(set, value);\n\n    /// <summary>\n    /// Retrieve the value from predecessor item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindPredecessor(A key) => SetModule.TryFindPredecessor<OrdA, A>(set, key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the predecessor item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindOrPredecessor(A key) => SetModule.TryFindOrPredecessor<OrdA, A>(set, key);\n\n    /// <summary>\n    /// Retrieve the value from next item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindSuccessor(A key) => SetModule.TryFindSuccessor<OrdA, A>(set, key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the next item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindOrSuccessor(A key) => SetModule.TryFindOrSuccessor<OrdA, A>(set, key);\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    public Iterable<A> FindRange(A keyFrom, A keyTo)\n    {\n        if (isnull(keyFrom)) throw new ArgumentNullException(nameof(keyFrom));\n        if (isnull(keyTo)) throw new ArgumentNullException(nameof(keyTo));\n        return OrdA.Compare(keyFrom, keyTo) > 0\n                   ? SetModule.FindRange<OrdA, A>(set, keyTo, keyFrom).AsIterable()\n                   : SetModule.FindRange<OrdA, A>(set, keyFrom, keyTo).AsIterable();\n    }\n\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public SetInternal<OrdA, A> Intersect(IEnumerable<A> other)\n    {\n        var root = SetItem<A>.Empty;\n        foreach (var item in other)\n        {\n            if (Contains(item))\n            {\n                root = SetModuleM.Add<OrdA, A>(root, item, SetModuleM.AddOpt.TryAdd);\n            }\n        }\n        return new SetInternal<OrdA, A>(root);\n    }\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public SetInternal<OrdA, A> Except(SetInternal<OrdA, A> rhs)\n    {\n        var root = SetItem<A>.Empty;\n        foreach (var item in this)\n        {\n            if (!rhs.Contains(item))\n            {\n                root = SetModuleM.Add<OrdA, A>(root, item, SetModuleM.AddOpt.TryAdd);\n            }\n        }\n        return new SetInternal<OrdA, A>(root);\n    }\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public SetInternal<OrdA, A> Except(IEnumerable<A> other) =>\n        Except(new SetInternal<OrdA, A>(other));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public SetInternal<OrdA, A> SymmetricExcept(SetInternal<OrdA, A> rhs)\n    {\n        var root = SetItem<A>.Empty;\n\n        foreach (var item in this)\n        {\n            if (!rhs.Contains(item))\n            {\n                root = SetModuleM.Add<OrdA, A>(root, item, SetModuleM.AddOpt.TryAdd);\n            }\n        }\n\n        foreach (var item in rhs)\n        {\n            if (!Contains(item))\n            {\n                root = SetModuleM.Add<OrdA, A>(root, item, SetModuleM.AddOpt.TryAdd);\n            }\n        }\n\n        return new SetInternal<OrdA, A>(root);\n    }\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public SetInternal<OrdA, A> SymmetricExcept(IEnumerable<A> other) =>\n        SymmetricExcept(new SetInternal<OrdA, A>(other));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public SetInternal<OrdA, A> Union(IEnumerable<A> other)\n    {\n        var root = SetItem<A>.Empty;\n\n        foreach(var item in this)\n        {\n            root = SetModuleM.Add<OrdA, A>(root, item, SetModuleM.AddOpt.TryAdd);\n        }\n\n        foreach (var item in other)\n        {\n            root = SetModuleM.Add<OrdA, A>(root, item, SetModuleM.AddOpt.TryAdd);\n        }\n\n        return new SetInternal<OrdA, A>(root);\n    }\n\n    /// <summary>\n    /// Clears the set\n    /// </summary>\n    /// <returns>An empty set</returns>\n    [Pure]\n    public SetInternal<OrdA, A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns>IEnumerator T</returns>\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        new SetModule.SetEnumerator<A>(set, false, 0);\n\n    /// <summary>\n    /// Removes an item from the set (if it exists)\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>New set with item removed</returns>\n    [Pure]\n    public SetInternal<OrdA, A> Remove(A value) =>\n        new (SetModule.Remove<OrdA, A>(set, value));\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the set. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, A, S> folder) =>\n        SetModule.Fold(set,state,folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the set. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public S FoldBack<S>(S state, Func<S, A, S> folder) =>\n        SetModule.FoldBack(set, state, folder);\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped Set</returns>\n    [Pure]\n    public SetInternal<OrdB, B> Map<OrdB, B>(Func<A, B> f) where OrdB : Ord<B> =>\n        new (AsIterable().Map(f));\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped Set</returns>\n    [Pure]\n    public SetInternal<OrdA, A> Map(Func<A, A> f) =>\n        new (AsIterable().Map(f));\n\n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public SetInternal<OrdA, A> Filter(Func<A, bool> pred) =>\n        new (AsIterable().Filter(pred), SetModuleM.AddOpt.TryAdd);\n\n    /// <summary>\n    /// Check the existence of an item in the set using a \n    /// predicate.\n    /// </summary>\n    /// <remarks>Note this scans the entire set.</remarks>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if predicate returns true for any item</returns>\n    [Pure]\n    public bool Exists(Func<A, bool> pred) =>\n        SetModule.Exists(set, pred);\n\n    /// <summary>\n    /// Returns True if the value is in the set\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if the item 'value' is in the Set 'set'</returns>\n    [Pure]\n    public bool Contains(A value) =>\n        SetModule.Contains<OrdA, A>(set, value);\n\n    /// <summary>\n    /// Returns true if both sets contain the same elements\n    /// </summary>\n    /// <param name=\"other\">Other distinct set to compare</param>\n    /// <returns>True if the sets are equal</returns>\n    [Pure]\n    public bool SetEquals(IEnumerable<A> other)\n    {\n        var rhs = new SetInternal<OrdA, A>(other);\n        if (rhs.Count != Count) return false;\n        foreach (var item in rhs)\n        {\n            if (!Contains(item)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// True if the set has no elements\n    /// </summary>\n    [Pure]\n    public bool IsEmpty => \n        Count == 0;\n\n    /// <summary>\n    /// IsReadOnly - Always true\n    /// </summary>\n    [Pure]\n    public bool IsReadOnly\n    {\n        get\n        {\n            return true;\n        }\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<A> other)\n    {\n        if (IsEmpty)\n        {\n            return other.Any();\n        }\n\n        var otherSet = new Set<A>(other);\n        if (Count >= otherSet.Count)\n        {\n            return false;\n        }\n\n        int  matches    = 0;\n        bool extraFound = false;\n        foreach (A item in otherSet)\n        {\n            if (Contains(item))\n            {\n                matches++;\n            }\n            else\n            {\n                extraFound = true;\n            }\n\n            if (matches == Count && extraFound)\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<A> other)\n    {\n        if (IsEmpty)\n        {\n            return false;\n        }\n\n        int matchCount = 0;\n        foreach (A item in other)\n        {\n            matchCount++;\n            if (!Contains(item))\n            {\n                return false;\n            }\n        }\n\n        return Count > matchCount;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<A> other)\n    {\n        if (IsEmpty)\n        {\n            return true;\n        }\n\n        var otherSet = new SetInternal<OrdA, A>(other);\n        int matches  = 0;\n        foreach (A item in otherSet)\n        {\n            if (Contains(item))\n            {\n                matches++;\n            }\n        }\n        return matches == Count;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<A> other)\n    {\n        foreach (A item in other)\n        {\n            if (!Contains(item))\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True if other overlaps this set</returns>\n    [Pure]\n    public bool Overlaps(IEnumerable<A> other)\n    {\n        if (IsEmpty)\n        {\n            return false;\n        }\n\n        foreach (A item in other)\n        {\n            if (Contains(item))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public void CopyTo(A[] array, int index)\n    {\n        if (array == null) throw new ArgumentNullException(nameof(array));\n        if (index < 0 || index > array.Length) throw new IndexOutOfRangeException();\n        if (index + Count > array.Length) throw new IndexOutOfRangeException();\n\n        foreach (var element in this)\n        {\n            array[index++] = element;\n        }\n    }\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public void CopyTo(Array array, int index)\n    {\n        if (array == null) throw new ArgumentNullException(nameof(array));\n        if (index < 0 || index > array.Length) throw new IndexOutOfRangeException();\n        if (index + Count > array.Length) throw new IndexOutOfRangeException();\n\n        foreach (var element in this)\n        {\n            array.SetValue(element, index++);\n        }\n    }\n\n    /// <summary>\n    /// Add operator + performs a union of the two sets\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Unioned set</returns>\n    [Pure]\n    public static SetInternal<OrdA, A> operator +(SetInternal<OrdA, A> lhs, SetInternal<OrdA, A> rhs) =>\n        lhs.Append(rhs);\n\n    /// <summary>\n    /// Append performs a union of the two sets\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Unioned set</returns>\n    [Pure]\n    public SetInternal<OrdA, A> Append(SetInternal<OrdA, A> rhs) =>\n        Union(rhs.AsIterable());\n\n    /// <summary>\n    /// Subtract operator - performs a subtract of the two sets\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Subtractd set</returns>\n    [Pure]\n    public static SetInternal<OrdA, A> operator -(SetInternal<OrdA, A> lhs, SetInternal<OrdA, A> rhs) =>\n        lhs.Subtract(rhs);\n\n    /// <summary>\n    /// Subtract operator - performs a subtract of the two sets\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Subtractd set</returns>\n    [Pure]\n    public SetInternal<OrdA, A> Subtract(SetInternal<OrdA, A> rhs)\n    {\n        if (Count     == 0) return Empty;\n        if (rhs.Count == 0) return this;\n\n        if (rhs.Count < Count)\n        {\n            var self = this;\n            foreach (var item in rhs)\n            {\n                self = self.Remove(item);\n            }\n            return self;\n        }\n        else\n        {\n            var root = SetItem<A>.Empty;\n            foreach (var item in this)\n            {\n                if (!rhs.Contains(item))\n                {\n                    root = SetModuleM.Add<OrdA, A>(root, item, SetModuleM.AddOpt.TryAdd);\n                }\n            }\n            return new SetInternal<OrdA, A>(root);\n        }\n    }\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"other\">Other set to test</param>\n    /// <returns>True if sets are equal</returns>\n    [Pure]\n    public bool Equals(SetInternal<OrdA, A>? other) =>\n        other is not null && SetEquals(other.AsIterable());\n\n    [Pure]\n    public int CompareTo(SetInternal<OrdA, A> other)\n    {\n        var cmp = Count.CompareTo(other.Count);\n        if (cmp != 0) return cmp;\n        using var iterA = GetEnumerator();\n        using var iterB = other.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            cmp = OrdA.Compare(iterA.Current, iterB.Current);\n            if (cmp != 0) return cmp;\n        }\n        return 0;\n    }\n\n    [Pure]\n    public int CompareTo<OrdAlt>(SetInternal<OrdA, A> other) where OrdAlt : Ord<A>\n    {\n        var cmp = Count.CompareTo(other.Count);\n        if (cmp != 0) return cmp;\n        using var iterA = GetEnumerator();\n        using var iterB = other.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            cmp = OrdAlt.Compare(iterA.Current, iterB.Current);\n            if (cmp != 0) return cmp;\n        }\n        return 0;\n    }\n\n    IEnumerator IEnumerable.GetEnumerator() =>\n        new SetModule.SetEnumerator<A>(set, false, 0);\n}\n\ninternal class SetItem<K>\n{\n    public static readonly SetItem<K> Empty = new (0, 0, default!, default!, default!);\n\n    public bool IsEmpty => Count == 0;\n    public int Count;\n    public byte Height;\n    public SetItem<K> Left;\n    public SetItem<K> Right;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    internal SetItem(byte height, int count, K key, SetItem<K> left, SetItem<K> right)\n    {\n        Count = count;\n        Height = height;\n        Key = key;\n        Left = left;\n        Right = right;\n    }\n\n    [Pure]\n    internal int BalanceFactor =>\n        Count == 0\n            ? 0\n            : Right.Height - Left.Height;\n\n    [Pure]\n    public K Key\n    {\n        get;\n        internal set;\n    }\n}\n\ninternal static class SetModuleM\n{\n    public enum AddOpt\n    {\n        ThrowOnDuplicate,\n        TryAdd,\n        TryUpdate\n    }\n\n    public static SetItem<K> Add<OrdK, K>(SetItem<K> node, K key, AddOpt option)\n        where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return new SetItem<K>(1, 1, key, SetItem<K>.Empty, SetItem<K>.Empty);\n        }\n        var cmp = OrdK.Compare(key, node.Key);\n        if (cmp < 0)\n        {\n            node.Left = Add<OrdK, K>(node.Left, key, option);\n            return Balance(node);\n        }\n        else if (cmp > 0)\n        {\n            node.Right = Add<OrdK, K>(node.Right, key, option);\n            return Balance(node);\n        }\n        else if (option == AddOpt.TryAdd)\n        {\n            // Already exists, but we don't care\n            return node;\n        }\n        else if (option == AddOpt.TryUpdate)\n        {\n            // Already exists, and we want to update the content\n            node.Key = key;\n            return node;\n        }\n        else\n        {\n            throw new ArgumentException(\"An element with the same key already exists in the Map\");\n        }\n    }\n\n    public static SetItem<K> Balance<K>(SetItem<K> node)\n    {\n        node.Height = (byte)(1 + Math.Max(node.Left.Height, node.Right.Height));\n        node.Count = 1 + node.Left.Count + node.Right.Count;\n\n        return node.BalanceFactor >= 2\n                   ? node.Right.BalanceFactor < 0\n                         ? DblRotLeft(node)\n                         : RotLeft(node)\n                   : node.BalanceFactor <= -2\n                       ? node.Left.BalanceFactor > 0\n                             ? DblRotRight(node)\n                             : RotRight(node)\n                       : node;\n    }\n\n    public static SetItem<K> DblRotRight<K>(SetItem<K> node)\n    {\n        node.Left = RotLeft(node.Left);\n        return RotRight(node);\n    }\n\n    public static SetItem<K> DblRotLeft<K>(SetItem<K> node)\n    {\n        node.Right = RotRight(node.Right);\n        return RotLeft(node);\n    }\n\n    public static SetItem<K> RotRight<K>(SetItem<K> node)\n    {\n        if (node.IsEmpty || node.Left.IsEmpty) return node;\n\n        var y  = node;\n        var x  = y.Left;\n        var t2 = x.Right;\n        x.Right = y;\n        y.Left = t2;\n        y.Height = (byte)(1 + Math.Max(y.Left.Height, y.Right.Height));\n        x.Height = (byte)(1 + Math.Max(x.Left.Height, x.Right.Height));\n        y.Count = 1 + y.Left.Count + y.Right.Count;\n        x.Count = 1 + x.Left.Count + x.Right.Count;\n\n        return x;\n    }\n\n    public static SetItem<K> RotLeft<K>(SetItem<K> node)\n    {\n        if (node.IsEmpty || node.Right.IsEmpty) return node;\n\n        var x  = node;\n        var y  = x.Right;\n        var t2 = y.Left;\n        y.Left = x;\n        x.Right = t2;\n        x.Height = (byte)(1 + Math.Max(x.Left.Height, x.Right.Height));\n        y.Height = (byte)(1 + Math.Max(y.Left.Height, y.Right.Height));\n        x.Count = 1 + x.Left.Count + x.Right.Count;\n        y.Count = 1 + y.Left.Count + y.Right.Count;\n\n        return y;\n    }\n}\n\ninternal static class SetModule\n{\n    [Pure]\n    public static S Fold<S, K>(SetItem<K> node, S state, Func<S, K, S> folder)\n    {\n        if (node.IsEmpty)\n        {\n            return state;\n        }\n        state = Fold(node.Left, state, folder);\n        state = folder(state, node.Key);\n        state = Fold(node.Right, state, folder);\n        return state;\n    }\n\n    [Pure]\n    public static S FoldBack<S, K>(SetItem<K> node, S state, Func<S, K, S> folder)\n    {\n        if (node.IsEmpty)\n        {\n            return state;\n        }\n        state = FoldBack(node.Right, state, folder);\n        state = folder(state, node.Key);\n        state = FoldBack(node.Left, state, folder);\n        return state;\n    }\n\n    [Pure]\n    public static bool ForAll<K>(SetItem<K> node, Func<K, bool> pred) =>\n        node.IsEmpty || pred(node.Key) && ForAll(node.Left, pred) && ForAll(node.Right, pred);\n\n    [Pure]\n    public static bool Exists<K>(SetItem<K> node, Func<K, bool> pred) =>\n        !node.IsEmpty && (pred(node.Key) || Exists(node.Left, pred) || Exists(node.Right, pred));\n\n    [Pure]\n    public static SetItem<K> Add<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return new SetItem<K>(1, 1, key, SetItem<K>.Empty, SetItem<K>.Empty);\n        }\n        var cmp = OrdK.Compare(key, node.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.Key, Add<OrdK, K>(node.Left, key), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.Key, node.Left, Add<OrdK, K>(node.Right, key)));\n        }\n        else\n        {\n            throw new ArgumentException(\"An element with the same key already exists in the set\");\n        }\n    }\n\n    [Pure]\n    public static SetItem<K> TryAdd<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return new SetItem<K>(1, 1, key, SetItem<K>.Empty, SetItem<K>.Empty);\n        }\n        var cmp = OrdK.Compare(key, node.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.Key, TryAdd<OrdK, K>(node.Left, key), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.Key, node.Left, TryAdd<OrdK, K>(node.Right, key)));\n        }\n        else\n        {\n            return node;\n        }\n    }\n\n    [Pure]\n    public static SetItem<K> AddOrUpdate<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return new SetItem<K>(1, 1, key, SetItem<K>.Empty, SetItem<K>.Empty);\n        }\n        var cmp = OrdK.Compare(key, node.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.Key, TryAdd<OrdK, K>(node.Left, key), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.Key, node.Left, TryAdd<OrdK, K>(node.Right, key)));\n        }\n        else\n        {\n            return new SetItem<K>(node.Height, node.Count, key, node.Left, node.Right);\n        }\n    }\n\n    [Pure]\n    public static SetItem<K> AddTreeToRight<K>(SetItem<K> node, SetItem<K> toAdd) =>\n        node.IsEmpty\n            ? toAdd\n            : Balance(Make(node.Key, node.Left, AddTreeToRight(node.Right, toAdd)));\n\n    [Pure]\n    public static SetItem<K> Remove<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return node;\n        }\n        var cmp = OrdK.Compare(key, node.Key);\n        if (cmp < 0)\n        {\n            return Balance(Make(node.Key, Remove<OrdK, K>(node.Left, key), node.Right));\n        }\n        else if (cmp > 0)\n        {\n            return Balance(Make(node.Key, node.Left, Remove<OrdK, K>(node.Right, key)));\n        }\n        else\n        {\n            return Balance(AddTreeToRight(node.Left, node.Right));\n        }\n    }\n\n    [Pure]\n    public static bool Contains<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return false;\n        }\n        var cmp = OrdK.Compare(key, node.Key);\n        if (cmp < 0)\n        {\n            return Contains<OrdK, K>(node.Left, key);\n        }\n        else if (cmp > 0)\n        {\n            return Contains<OrdK, K>(node.Right, key);\n        }\n        else\n        {\n            return true;\n        }\n    }\n\n    [Pure]\n    public static K Find<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            throw new ArgumentException(\"Key not found in set\");\n        }\n        var cmp = OrdK.Compare(key, node.Key);\n        if (cmp < 0)\n        {\n            return Find<OrdK, K>(node.Left, key);\n        }\n        else if (cmp > 0)\n        {\n            return Find<OrdK, K>(node.Right, key);\n        }\n        else\n        {\n            return node.Key;\n        }\n    }\n\n    /// <summary>\n    /// TODO: I suspect this is suboptimal, it would be better with a custom Enumerator \n    /// that maintains a stack of nodes to retrace.\n    /// </summary>\n    [Pure]\n    public static IEnumerable<K> FindRange<OrdK, K>(SetItem<K> node, K a, K b) where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            yield break;\n        }\n        if (OrdK.Compare(node.Key, a) < 0)\n        {\n            foreach (var item in FindRange<OrdK, K>(node.Right, a, b))\n            {\n                yield return item;\n            }\n        }\n        else if (OrdK.Compare(node.Key, b) > 0)\n        {\n            foreach (var item in FindRange<OrdK, K>(node.Left, a, b))\n            {\n                yield return item;\n            }\n        }\n        else\n        {\n            foreach (var item in FindRange<OrdK, K>(node.Left, a, b))\n            {\n                yield return item;\n            }\n            yield return node.Key;\n            foreach (var item in FindRange<OrdK, K>(node.Right, a, b))\n            {\n                yield return item;\n            }\n        }\n    }\n\n    [Pure]\n    public static Option<K> TryFind<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>\n    {\n        if (node.IsEmpty)\n        {\n            return None;\n        }\n        var cmp = OrdK.Compare(key, node.Key);\n        if (cmp < 0)\n        {\n            return TryFind<OrdK, K>(node.Left, key);\n        }\n        else if (cmp > 0)\n        {\n            return TryFind<OrdK, K>(node.Right, key);\n        }\n        else\n        {\n            return Some(node.Key);\n        }\n    }\n\n    [Pure]\n    public static SetItem<K> Skip<K>(SetItem<K> node, int amount)\n    {\n        if (amount == 0 || node.IsEmpty)\n        {\n            return node;\n        }\n        if (amount >= node.Count)\n        {\n            return SetItem<K>.Empty;\n        }\n        if (!node.Left.IsEmpty && node.Left.Count == amount)\n        {\n            return Balance(Make(node.Key, SetItem<K>.Empty, node.Right));\n        }\n        if (!node.Left.IsEmpty && node.Left.Count == amount - 1)\n        {\n            return node.Right;\n        }\n        if (node.Left.IsEmpty)\n        {\n            return Skip(node.Right, amount - 1);\n        }\n\n        var newleft   = Skip(node.Left, amount);\n        var remaining = amount - node.Left.Count - newleft.Count;\n        if (remaining > 0)\n        {\n            return Skip(Balance(Make(node.Key, newleft, node.Right)), remaining);\n        }\n        else\n        {\n            return Balance(Make(node.Key, newleft, node.Right));\n        }\n    }\n\n    [Pure]\n    public static SetItem<K> Make<K>(K k, SetItem<K> l, SetItem<K> r) =>\n        new ((byte)(1 + Math.Max(l.Height, r.Height)), l.Count + r.Count + 1, k, l, r);\n\n    [Pure]\n    public static SetItem<K> Balance<K>(SetItem<K> node) =>\n        node.BalanceFactor >= 2\n            ? node.Right.BalanceFactor < 0\n                  ? DblRotLeft(node)\n                  : RotLeft(node)\n            : node.BalanceFactor <= -2\n                ? node.Left.BalanceFactor > 0\n                      ? DblRotRight(node)\n                      : RotRight(node)\n                : node;\n\n    [Pure]\n    public static SetItem<K> RotRight<K>(SetItem<K> node) =>\n        node.IsEmpty || node.Left.IsEmpty\n            ? node\n            : Make(node.Left.Key, node.Left.Left, Make(node.Key, node.Left.Right, node.Right));\n\n    [Pure]\n    public static SetItem<K> RotLeft<K>(SetItem<K> node) =>\n        node.IsEmpty || node.Right.IsEmpty\n            ? node\n            : Make(node.Right.Key, Make(node.Key, node.Left, node.Right.Left), node.Right.Right);\n\n    [Pure]\n    public static SetItem<K> DblRotRight<K>(SetItem<K> node) =>\n        node.IsEmpty\n            ? node\n            : RotRight(Make(node.Key, RotLeft(node.Left), node.Right));\n\n    [Pure]\n    public static SetItem<K> DblRotLeft<K>(SetItem<K> node) =>\n        node.IsEmpty\n            ? node\n            : RotLeft(Make(node.Key, node.Left, RotRight(node.Right)));\n\n    internal static Option<A> Max<A>(SetItem<A> node) =>\n        node.Right.IsEmpty\n            ? node.Key\n            : Max(node.Right);\n\n    internal static Option<A> Min<A>(SetItem<A> node) =>\n        node.Left.IsEmpty\n            ? node.Key\n            : Min(node.Left);\n\n    internal static Option<A> TryFindPredecessor<OrdA, A>(SetItem<A> root, A key) where OrdA : Ord<A>\n    {\n        Option<A> predecessor = None;\n        var       current     = root;\n\n        if (root.IsEmpty)\n        {\n            return None;\n        }\n\n        do\n        {\n            var cmp = OrdA.Compare(key, current.Key);\n            if (cmp < 0)\n            {\n                current = current.Left;\n            }\n            else if (cmp > 0)\n            {\n                predecessor = current.Key;\n                current = current.Right;\n            }\n            else\n            {\n                break;\n            }\n        }\n        while (!current.IsEmpty);\n\n        if(!current.IsEmpty && !current.Left.IsEmpty)\n        {\n            predecessor = Max(current.Left);\n        }\n\n        return predecessor;\n    }\n\n    internal static Option<A> TryFindOrPredecessor<OrdA, A>(SetItem<A> root, A key) where OrdA : Ord<A>\n    {\n        Option<A> predecessor = None;\n        var       current     = root;\n\n        if (root.IsEmpty)\n        {\n            return None;\n        }\n\n        do\n        {\n            var cmp = OrdA.Compare(key, current.Key);\n            if (cmp < 0)\n            {\n                current = current.Left;\n            }\n            else if (cmp > 0)\n            {\n                predecessor = current.Key;\n                current = current.Right;\n            }\n            else\n            {\n                return current.Key;\n            }\n        }\n        while (!current.IsEmpty);\n\n        if (!current.IsEmpty && !current.Left.IsEmpty)\n        {\n            predecessor = Max(current.Left);\n        }\n\n        return predecessor;\n    }\n\n    internal static Option<A> TryFindSuccessor<OrdA, A>(SetItem<A> root, A key) where OrdA : Ord<A>\n    {\n        Option<A> successor = None;\n        var       current   = root;\n\n        if (root.IsEmpty)\n        {\n            return None;\n        }\n\n        do\n        {\n            var cmp = OrdA.Compare(key, current.Key);\n            if (cmp < 0)\n            {\n                successor = current.Key;\n                current = current.Left;\n            }\n            else if (cmp > 0)\n            {\n                current = current.Right;\n            }\n            else\n            {\n                break;\n            }\n        }\n        while (!current.IsEmpty);\n\n        if (!current.IsEmpty && !current.Right.IsEmpty)\n        {\n            successor = Min(current.Right);\n        }\n\n        return successor;\n    }\n\n    internal static Option<A> TryFindOrSuccessor<OrdA, A>(SetItem<A> root, A key) where OrdA : Ord<A>\n    {\n        Option<A> successor = None;\n        var       current   = root;\n\n        if (root.IsEmpty)\n        {\n            return None;\n        }\n\n        do\n        {\n            var cmp = OrdA.Compare(key, current.Key);\n            if (cmp < 0)\n            {\n                successor = current.Key;\n                current = current.Left;\n            }\n            else if (cmp > 0)\n            {\n                current = current.Right;\n            }\n            else\n            {\n                return current.Key;\n            }\n        }\n        while (!current.IsEmpty);\n\n        if (!current.IsEmpty && !current.Right.IsEmpty)\n        {\n            successor = Min(current.Right);\n        }\n\n        return successor;\n    }\n\n    public class SetEnumerator<K> : IEnumerator<K>\n    {\n        internal struct NewStack : New<SetItem<K>[]>\n        {\n            public SetItem<K>[] New() =>\n                new SetItem<K>[32];\n        }\n\n        int stackDepth;\n        SetItem<K>[]? stack;\n        readonly SetItem<K> map;\n        int left;\n        readonly bool rev;\n        readonly int start;\n\n        public SetEnumerator(SetItem<K> root, bool rev, int start)\n        {\n            this.rev = rev;\n            this.start = start;\n            map = root;\n            stack = Pool<NewStack, SetItem<K>[]>.Pop();\n            NodeCurrent = default!;\n            Reset();\n        }\n\n        private SetItem<K> NodeCurrent\n        {\n            get;\n            set;\n        }\n\n        public K Current => NodeCurrent.Key;\n        object IEnumerator.Current => NodeCurrent.Key!;\n\n        public void Dispose()\n        {\n            if (stack is not null)\n            {\n                Pool<NewStack, SetItem<K>[]>.Push(stack);\n                stack = default!;\n            }\n        }\n\n        private SetItem<K> Next(SetItem<K> node) =>\n            rev ? node.Left : node.Right;\n\n        private SetItem<K> Prev(SetItem<K> node) =>\n            rev ? node.Right : node.Left;\n\n        private void Push(SetItem<K> node)\n        {\n            while (!node.IsEmpty)\n            {\n                stack![stackDepth] = node;\n                stackDepth++;\n                node = Prev(node);\n            }\n        }\n\n        public bool MoveNext()\n        {\n            if (left > 0 && stackDepth > 0)\n            {\n                stackDepth--;\n                NodeCurrent = stack![stackDepth];\n                Push(Next(NodeCurrent));\n                left--;\n                return true;\n            }\n\n            NodeCurrent = default!;\n            return false;\n        }\n\n        public void Reset()\n        {\n            var skip = rev ? map.Count - start - 1 : start;\n\n            stackDepth = 0;\n            NodeCurrent = map;\n            left = map.Count;\n\n            while (!NodeCurrent.IsEmpty && skip != Prev(NodeCurrent).Count)\n            {\n                if (skip < Prev(NodeCurrent).Count)\n                {\n                    stack![stackDepth] = NodeCurrent;\n                    stackDepth++;\n                    NodeCurrent = Prev(NodeCurrent);\n                }\n                else\n                {\n                    skip -= Prev(NodeCurrent).Count + 1;\n                    NodeCurrent = Next(NodeCurrent);\n                }\n            }\n\n            if (!NodeCurrent.IsEmpty)\n            {\n                stack![stackDepth] = NodeCurrent;\n                stackDepth++;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Prelude/Set.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Set<B> map<A, B>(Func<A, B> f, K<Set, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Set<B> action<A, B>(K<Set, A> ma, K<Set, B> mb) =>\n        Applicative.action(ma, mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Set<B> apply<A, B>(K<Set, Func<A, B>> mf, K<Set, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Set.Module.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic partial class Set\n{\n    /// <summary>\n    /// True if the set has no elements\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>True if the set has no elements</returns>\n    [Pure]\n    public static bool isEmpty<T>(Set<T> set) =>\n        set.IsEmpty;\n\n    /// <summary>\n    /// Singleton set\n    /// </summary>\n    [Pure]\n    public static Set<A> singleton<A>(A value) =>\n        [value];\n\n    /// <summary>\n    /// Create a new empty set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>Empty set</returns>\n    [Pure]\n    public static Set<T> create<T>() =>\n        Set<T>.Empty;\n\n    /// <summary>\n    /// Create a new set pre-populated with the items in range\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"range\">Range of items</param>\n    /// <returns>Set</returns>\n    [Pure]\n    public static Set<T> createRange<T>(IEnumerable<T> range) =>\n        new (range);\n\n    /// <summary>\n    /// Create a new set pre-populated with the items in range\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"range\">Range of items</param>\n    /// <returns>Set</returns>\n    [Pure]\n    public static Set<A> createRange<A>(ReadOnlySpan<A> range) =>\n        range.IsEmpty\n            ? Set<A>.Empty\n            : new (range);\n\n    /// <summary>\n    /// Create a new empty set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>Empty set</returns>\n    [Pure]\n    public static Set<T> empty<T>() =>\n        Set<T>.Empty;\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public static Set<T> add<T>(Set<T> set, T value) =>\n        set.Add(value);\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public static Set<T> tryAdd<T>(Set<T> set, T value) =>\n        set.TryAdd(value);\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public static Set<T> addOrUpdate<T>(Set<T> set, T value) =>\n        set.AddOrUpdate(value);\n\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public static Set<A> addRange<A>(Set<A> set, IEnumerable<A> range) =>\n        set.AddRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists, it's ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public static Set<A> tryAddRange<A>(Set<A> set, IEnumerable<A> range) =>\n        set.TryAddRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists then replace it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public static Set<A> addOrUpdateRange<A>(Set<A> set, IEnumerable<A> range) =>\n        set.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Attempts to find an item in the set.  \n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"value\">Value to find</param>\n    /// <returns>Some(T) if found, None otherwise</returns>\n    [Pure]\n    public static Option<T> find<T>(Set<T> set, T value) =>\n        set.Find(value);\n\n    /// <summary>\n    /// Check the existence of an item in the set using a \n    /// predicate.\n    /// </summary>\n    /// <remarks>Note this scans the entire set.</remarks>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if predicate returns true for any item</returns>\n    [Pure]\n    public static bool exists<T>(Set<T> set, Func<T, bool> pred) =>\n        set.Exists(pred);\n\n    /// <summary>\n    /// Returns true if both sets contain the same elements\n    /// </summary>\n    [Pure]\n    public static bool equals<T>(Set<T> setA, Set<T> setB) =>\n        setA.SetEquals(setB);\n\n    /// <summary>\n    /// Get the number of elements in the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <returns>Number of elements</returns>\n    [Pure]\n    public static int length<T>(Set<T> set) =>\n        set.Count;\n\n    /// <summary>\n    /// Returns setA - setB.  Only the items in setA that are not in \n    /// setB will be returned.\n    /// </summary>\n    [Pure]\n    public static Set<T> subtract<T>(Set<T> setA, Set<T> setB) =>\n        setA.Except(setB);\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set A</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public static Set<T> union<T>(Set<T> setA, Set<T> setB) =>\n        setA.Union(setB);\n\n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public static Set<T> filter<T>(Set<T> set, Func<T, bool> pred) =>\n        set.Filter(pred);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the set. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Set element type</typeparam>\n    /// <param name=\"set\">Set to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S fold<T, S>(Set<T> set, S state, Func<S, T, S> folder) =>\n        set.Fold(state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the set. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Set element type</typeparam>\n    /// <param name=\"set\">Set to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBack<T, S>(Set<T> set, S state, Func<S, T, S> folder) =>\n        set.FoldBack(state, folder);\n\n    /// <summary>\n    /// Returns the elements that are in both setA and setB\n    /// </summary>\n    [Pure]\n    public static Set<T> intersect<T>(Set<T> setA, IEnumerable<T> setB) =>\n        setA.Intersect(setB);\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public static Set<T> except<T>(Set<T> setA, IEnumerable<T> setB) =>\n        setA.Except(setB);\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public static Set<T> symmetricExcept<T>(Set<T> setA, IEnumerable<T> setB) =>\n        setA.SymmetricExcept(setB);\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Set<R> map<T, R>(Set<T> set, Func<T, R> mapper) =>\n        set.Map(mapper);\n\n    /// <summary>\n    /// Returns True if the value is in the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if the item 'value' is in the Set 'set'</returns>\n    [Pure]\n    public static bool contains<T>(Set<T> set, T value) =>\n        set.Contains(value);\n\n    /// <summary>\n    /// Removes an item from the set (if it exists)\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>New set with item removed</returns>\n    [Pure]\n    public static Set<T> remove<T>(Set<T> set, T value) =>\n        set.Remove(value);\n\n    /// <summary>\n    /// Returns True if setB is a subset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a subset of setA</returns>\n    [Pure]\n    public static bool isSubset<T>(Set<T> setA, IEnumerable<T> setB) =>\n        setA.IsSubsetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a superset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a superset of setA</returns>\n    [Pure]\n    public static bool isSuperset<T>(Set<T> setA, IEnumerable<T> setB) =>\n        setA.IsSupersetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a proper subset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a proper subset of setA</returns>\n    [Pure]\n    public static bool isProperSubset<T>(Set<T> setA, IEnumerable<T> setB) =>\n        setA.IsProperSubsetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a proper superset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a proper subset of setA</returns>\n    [Pure]\n    public static bool isProperSuperset<T>(Set<T> setA, IEnumerable<T> setB) =>\n        setA.IsProperSupersetOf(setB);\n\n    /// <summary>\n    /// Returns True if setA overlaps setB\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True if setA overlaps setB</returns>\n    [Pure]\n    public static bool overlaps<T>(Set<T> setA, IEnumerable<T> setB) =>\n        setA.Overlaps(setB);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Set.Ord.Module.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable set module\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// http://en.wikipedia.org/wiki/AVL_tree\n/// </summary>\npublic partial class Set\n{\n    /// <summary>\n    /// True if the set has no elements\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>True if the set has no elements</returns>\n    [Pure]\n    public static bool isEmpty<OrdT, T>(Set<OrdT, T> set) where OrdT : Ord<T> =>\n        set.IsEmpty;\n\n    /// <summary>\n    /// Create a new single item set\n    /// </summary>\n    /// <typeparam name=\"A\">Element type</typeparam>\n    /// <returns>Singleton set</returns>\n    [Pure]\n    public static Set<OrdA, A> singleton<OrdA, A>(A value) where OrdA : Ord<A> =>\n        [value];\n\n    /// <summary>\n    /// Create a new empty set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>Empty set</returns>\n    [Pure]\n    public static Set<OrdT, T> create<OrdT, T>() where OrdT : Ord<T> =>\n        Set<OrdT, T>.Empty;\n\n    /// <summary>\n    /// Create a new set pre-populated with the items in range\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"range\">Range of items</param>\n    /// <returns>Set</returns>\n    [Pure]\n    public static Set<OrdT, T> createRange<OrdT, T>(IEnumerable<T> range) where OrdT : Ord<T> =>\n        new (range);\n\n    /// <summary>\n    /// Create a new set pre-populated with the items in range\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"range\">Range of items</param>\n    /// <returns>Set</returns>\n    [Pure]\n    public static Set<OrdA, A> createRange<OrdA, A>(ReadOnlySpan<A> range) where OrdA : Ord<A> =>\n        range.IsEmpty\n            ? Set<OrdA, A>.Empty\n            : new (range);\n\n    /// <summary>\n    /// Create a new empty set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <returns>Empty set</returns>\n    [Pure]\n    public static Set<OrdT, T> empty<OrdT, T>() where OrdT : Ord<T> =>\n        Set<OrdT, T>.Empty;\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public static Set<OrdT, T> add<OrdT, T>(Set<OrdT, T> set, T value) where OrdT : Ord<T> =>\n        set.Add(value);\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public static Set<OrdT, T> tryAdd<OrdT, T>(Set<OrdT, T> set, T value) where OrdT : Ord<T> =>\n        set.TryAdd(value);\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set to add item to</param>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public static Set<OrdT, T> addOrUpdate<OrdT, T>(Set<OrdT, T> set, T value) where OrdT : Ord<T> =>\n        set.AddOrUpdate(value);\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public static Set<OrdT, T> addRange<OrdT, T>(Set<OrdT, T> set, IEnumerable<T> range) where OrdT : Ord<T> =>\n        set.AddRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists, it's ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public static Set<OrdT, T> tryAddRange<OrdT, T>(Set<OrdT, T> set, IEnumerable<T> range) where OrdT : Ord<T> =>\n        set.TryAddRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists then replace it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public static Set<OrdT, T> addOrUpdateRange<OrdT, T>(Set<OrdT, T> set, IEnumerable<T> range) where OrdT : Ord<T> =>\n        set.AddOrUpdateRange(range);\n\n\n    /// <summary>\n    /// Attempts to find an item in the set.  \n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"value\">Value to find</param>\n    /// <returns>Some(T) if found, None otherwise</returns>\n    [Pure]\n    public static Option<T> find<OrdT, T>(Set<OrdT, T> set, T value) where OrdT : Ord<T> =>\n        set.Find(value);\n\n    /// <summary>\n    /// Check the existence of an item in the set using a \n    /// predicate.\n    /// </summary>\n    /// <remarks>Note this scans the entire set.</remarks>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if predicate returns true for any item</returns>\n    [Pure]\n    public static bool exists<OrdT, T>(Set<OrdT, T> set, Func<T, bool> pred) where OrdT : Ord<T> =>\n        set.Exists(pred);\n\n    /// <summary>\n    /// Returns true if both sets contain the same elements\n    /// </summary>\n    [Pure]\n    public static bool equals<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.SetEquals(setB);\n\n    /// <summary>\n    /// Get the number of elements in the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <returns>Number of elements</returns>\n    [Pure]\n    public static int length<OrdT, T>(Set<OrdT, T> set) where OrdT : Ord<T> =>\n        set.Count();\n\n    /// <summary>\n    /// Returns setA - setB.  Only the items in setA that are not in \n    /// setB will be returned.\n    /// </summary>\n    [Pure]\n    public static Set<OrdT, T> subtract<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.Except(setB);\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set A</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public static Set<OrdT, T> union<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.Union(setB);\n\n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public static Set<OrdT, T> filter<OrdT, T>(Set<OrdT, T> set, Func<T, bool> pred) where OrdT : Ord<T> =>\n        set.Filter(pred);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the set. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Set element type</typeparam>\n    /// <param name=\"set\">Set to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S fold<OrdT, T, S>(Set<OrdT, T> set, S state, Func<S, T, S> folder) where OrdT : Ord<T> =>\n        set.Fold(state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the set. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Set element type</typeparam>\n    /// <param name=\"set\">Set to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBack<OrdT, T, S>(Set<OrdT, T> set, S state, Func<S, T, S> folder) where OrdT : Ord<T> =>\n        set.FoldBack(state, folder);\n\n    /// <summary>\n    /// Returns the elements that are in both setA and setB\n    /// </summary>\n    [Pure]\n    public static Set<OrdT, T> intersect<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.Intersect(setB);\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public static Set<OrdT, T> except<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.Except(setB);\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public static Set<OrdT, T> symmetricExcept<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.SymmetricExcept(setB);\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Set<OrdR, R> map<OrdT, OrdR, T, R>(Set<OrdT, T> set, Func<T, R> mapper) \n        where OrdT : Ord<T>\n        where OrdR : Ord<R> =>\n        set.Map<OrdR, R>(mapper);\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Set<OrdT, T> map<OrdT, T>(Set<OrdT, T> set, Func<T, T> mapper) where OrdT : Ord<T> =>\n        set.Map(mapper);\n\n    /// <summary>\n    /// Returns True if the value is in the set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if the item 'value' is in the Set 'set'</returns>\n    [Pure]\n    public static bool contains<OrdT, T>(Set<OrdT, T> set, T value) where OrdT : Ord<T> =>\n        set.Contains(value);\n\n    /// <summary>\n    /// Removes an item from the set (if it exists)\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"set\">Set</param>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>New set with item removed</returns>\n    [Pure]\n    public static Set<OrdT, T> remove<OrdT, T>(Set<OrdT, T> set, T value) where OrdT : Ord<T> =>\n        set.Remove(value);\n\n    /// <summary>\n    /// Returns True if setB is a subset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a subset of setA</returns>\n    [Pure]\n    public static bool isSubset<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.IsSubsetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a superset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a superset of setA</returns>\n    [Pure]\n    public static bool isSuperset<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.IsSupersetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a proper subset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a proper subset of setA</returns>\n    [Pure]\n    public static bool isProperSubset<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.IsProperSubsetOf(setB);\n\n    /// <summary>\n    /// Returns True if setB is a proper superset of setA\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True is setB is a proper subset of setA</returns>\n    [Pure]\n    public static bool isProperSuperset<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.IsProperSupersetOf(setB);\n\n    /// <summary>\n    /// Returns True if setA overlaps setB\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True if setA overlaps setB</returns>\n    [Pure]\n    public static bool overlaps<OrdT, T>(Set<OrdT, T> setA, Set<OrdT, T> setB) where OrdT : Ord<T> =>\n        setA.Overlaps(setB);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Set.Ord.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable set\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// [wikipedia.org/wiki/AVL_tree](http://en.wikipedia.org/wiki/AVL_tree)\n/// </summary>\n/// <typeparam name=\"A\">Set item type</typeparam>\n[Serializable]\n[CollectionBuilder(typeof(Set), nameof(Set.createRange))]\npublic readonly struct Set<OrdA, A> :\n    IEnumerable<A>,\n    IEquatable<Set<OrdA, A>>,\n    IComparable<Set<OrdA, A>>\n    where OrdA : Ord<A>\n{\n    public static readonly Set<OrdA, A> Empty = new (SetInternal<OrdA, A>.Empty);\n\n    readonly SetInternal<OrdA, A> value;\n\n    SetInternal<OrdA, A> Value => value ?? Empty.Value;\n\n    /// <summary>\n    /// Ctor from an enumerable \n    /// </summary>\n    public Set(IEnumerable<A> items) : this(items, true)\n    {\n    }\n\n    /// <summary>\n    /// Ctor from an enumerable \n    /// </summary>\n    public Set(ReadOnlySpan<A> items) : this(items, true)\n    {\n    }\n\n    /// <summary>\n    /// Default ctor\n    /// </summary>\n    internal Set(SetInternal<OrdA, A> set) =>\n        value = set;\n\n    /// <summary>\n    /// Ctor that takes a root element\n    /// </summary>\n    /// <param name=\"root\"></param>\n    internal Set(SetItem<A> root) =>\n        value = new SetInternal<OrdA, A>(root);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    public Set(IEnumerable<A> items, bool tryAdd) =>\n        value = new SetInternal<OrdA, A>(\n            items, \n            tryAdd\n                ? SetModuleM.AddOpt.TryAdd\n                : SetModuleM.AddOpt.ThrowOnDuplicate);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    public Set(ReadOnlySpan<A> items, bool tryAdd) =>\n        value = new SetInternal<OrdA, A>(\n            items, \n            tryAdd\n                ? SetModuleM.AddOpt.TryAdd\n                : SetModuleM.AddOpt.ThrowOnDuplicate);\n\n    static Set<OrdA, A> Wrap(SetInternal<OrdA, A> set) =>\n        new (set);\n\n    static Set<OrdB, B> Wrap<OrdB, B>(SetInternal<OrdB, B> set) where OrdB : Ord<B>  =>\n        new (set);\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = null\n    ///     Singleton collection = A\n    ///     More                 = (A, Seq〈A〉)   -- head and tail\n    ///\n    ///     var res = set.Case switch\n    ///     {\n    ///       \n    ///        (var x, var xs) => ...,\n    ///        A value         => ...,\n    ///        _               => ...\n    ///     }\n    /// \n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty\n            ? null\n            : toSeq(Value).Case;\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public Set<OrdA, A> Add(A value) =>\n        Wrap(Value.Add(value));\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public Set<OrdA, A> TryAdd(A value) =>\n        Wrap(Value.TryAdd(value));\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public Set<OrdA, A> AddOrUpdate(A value) =>\n        Wrap(Value.AddOrUpdate(value));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public Set<OrdA, A> AddRange(IEnumerable<A> range) =>\n        Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists, it's ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public Set<OrdA, A> TryAddRange(IEnumerable<A> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists then replace it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public Set<OrdA, A> AddOrUpdateRange(IEnumerable<A> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Attempts to find an item in the set.  \n    /// </summary>\n    /// <param name=\"value\">Value to find</param>\n    /// <returns>Some(T) if found, None otherwise</returns>\n    [Pure]\n    public Option<A> Find(A value) =>\n        Value.Find(value);\n\n    /// <summary>\n    /// Retrieve the value from previous item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindPredecessor(A key) => Value.FindPredecessor(key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the previous item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindExactOrPredecessor(A key) => Value.FindOrPredecessor(key);\n\n    /// <summary>\n    /// Retrieve the value from next item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindSuccessor(A key) => Value.FindSuccessor(key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the next item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindExactOrSuccessor(A key) => Value.FindOrSuccessor(key);\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    public Iterable<A> FindRange(A keyFrom, A keyTo) => Value.FindRange(keyFrom, keyTo);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public Set<OrdA, A> Intersect(Set<OrdA, A> other) =>\n        Wrap(Value.Intersect(other));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public Set<OrdA, A> Except(Set<OrdA, A> other) =>\n        Wrap(Value.Except(other.Value));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public Set<OrdA, A> Except(IEnumerable<A> other) =>\n        other is Set<OrdA, A> rhs\n            ? Except(rhs)\n            : Wrap(Value.Except(other));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public Set<OrdA, A> SymmetricExcept(Set<OrdA, A> other) =>\n        Wrap(Value.SymmetricExcept(other));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public Set<OrdA, A> SymmetricExcept(IEnumerable<A> other) =>\n        other is Set<OrdA, A> rhs\n            ? SymmetricExcept(rhs)\n            : Wrap(Value.SymmetricExcept(other));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public Set<OrdA, A> Union(Set<OrdA, A> other) =>\n        Wrap(Value.Union(other));\n\n    /// <summary>\n    /// Clears the set\n    /// </summary>\n    /// <returns>An empty set</returns>\n    [Pure]\n    public Set<OrdA, A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns>IEnumerator T</returns>\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns>IEnumerator</returns>\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// Removes an item from the set (if it exists)\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>New set with item removed</returns>\n    [Pure]\n    public Set<OrdA, A> Remove(A value) =>\n        Wrap(Value.Remove(value));\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the set. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, A, S> folder) =>\n        Value.Fold(state,folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the set. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public S FoldBack<S>(S state, Func<S, A, S> folder) =>\n        Value.FoldBack(state, folder);\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Set<OrdA, A> Do(Action<A> f)\n    {\n        this.AsIterable().Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped Set</returns>\n    [Pure]\n    public Set<OrdB, B> Map<OrdB, B>(Func<A, B> map) where OrdB : Ord<B> =>\n        Wrap(Value.Map<OrdB, B>(map));\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped Set</returns>\n    [Pure]\n    public Set<OrdA, A> Map(Func<A, A> map) =>\n        Wrap(Value.Map(map));\n\n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public Set<OrdA, A> Filter(Func<A, bool> pred) =>\n        Wrap(Value.Filter(pred));\n\n    /// <summary>\n    /// Check the existence of an item in the set using a \n    /// predicate.\n    /// </summary>\n    /// <remarks>Note this scans the entire set.</remarks>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if predicate returns true for any item</returns>\n    [Pure]\n    public bool Exists(Func<A, bool> pred) =>\n        Value.Exists(pred);\n\n    /// <summary>\n    /// Returns True if the value is in the set\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if the item 'value' is in the Set 'set'</returns>\n    [Pure]\n    public bool Contains(A value) =>\n        Value.Contains(value);\n\n    /// <summary>\n    /// Returns true if both sets contain the same elements\n    /// </summary>\n    /// <param name=\"other\">Other distinct set to compare</param>\n    /// <returns>True if the sets are equal</returns>\n    [Pure]\n    public bool SetEquals(Set<OrdA, A> other) =>\n        Value.SetEquals(other);\n    /// <summary>\n    /// Is the set empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the set\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n        \n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(Set<OrdA, A> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(Set<OrdA, A> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(Set<OrdA, A> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(Set<OrdA, A> other) =>\n        Value.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True if other overlaps this set</returns>\n    [Pure]\n    public bool Overlaps(Set<OrdA, A> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public void CopyTo(A[] array, int index) =>\n        Value.CopyTo(array, index);\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public void CopyTo(Array array, int index) =>\n        Value.CopyTo(array, index);\n\n    /// <summary>\n    /// Add operator - performs a union of the two sets\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Unioned set</returns>\n    [Pure]\n    public static Set<OrdA, A> operator +(Set<OrdA, A> lhs, Set<OrdA, A> rhs) =>\n        Wrap(lhs.Value + rhs.Value);\n\n    /// <summary>\n    /// Add operator - performs a union of the two sets\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Unioned set</returns>\n    [Pure]\n    public Set<OrdA, A> Append(Set<OrdA, A> rhs) =>\n        Wrap(Value.Append(rhs.Value));\n\n    /// <summary>\n    /// Subtract operator - performs a subtract of the two sets\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Subtracted set</returns>\n    [Pure]\n    public static Set<OrdA, A> operator -(Set<OrdA, A> lhs, Set<OrdA, A> rhs) =>\n        Wrap(lhs.Value - rhs.Value);\n\n    /// <summary>\n    /// Subtract operator - performs a subtract of the two sets\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Subtracted set</returns>\n    [Pure]\n    public Set<OrdA, A> Subtract(Set<OrdA, A> rhs) =>\n        Wrap(Value.Subtract(rhs.Value));\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"other\">Other set to test</param>\n    /// <returns>True if sets are equal</returns>\n    [Pure]\n    public bool Equals(Set<OrdA, A> other) =>\n        Value.SetEquals(other.Value.AsIterable());\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>True if the two sets are equal</returns>\n    [Pure]\n    public static bool operator ==(Set<OrdA, A> lhs, Set<OrdA, A> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Non-equality operator\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>True if the two sets are equal</returns>\n    [Pure]\n    public static bool operator !=(Set<OrdA, A> lhs, Set<OrdA, A> rhs) =>\n        !lhs.Equals(rhs);\n\n    [Pure]\n    public static bool operator <(Set<OrdA, A> lhs, Set<OrdA, A> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    [Pure]\n    public static bool operator <=(Set<OrdA, A> lhs, Set<OrdA, A> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    [Pure]\n    public static bool operator >(Set<OrdA, A> lhs, Set<OrdA, A> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    [Pure]\n    public static bool operator >=(Set<OrdA, A> lhs, Set<OrdA, A> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is Set<OrdA, A> @as &&  Equals(@as);\n\n    /// <summary>\n    /// Get the hash code.  Calculated from all items in the set.\n    /// </summary>\n    /// <remarks>\n    /// The hash-code is cached after the first read.\n    /// </remarks>\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    public override string ToString() =>\n        $\"Set[{Count}]\";\n\n    [Pure]\n    public Seq<A> ToSeq() =>\n        toSeq(this);\n\n    [Pure]\n    public Iterable<A> AsEnumerable() => \n        Iterable.createRange(this);\n\n    [Pure]\n    public Set<OrdA, A> Where(Func<A, bool> pred) =>\n        Filter(pred);\n\n    [Pure]\n    public Set<OrdB, B> Bind<OrdB, B>(Func<A, Set<OrdB, B>> f) where OrdB : Ord<B>\n    {\n        var self = this;\n\n        IEnumerable<B> Yield()\n        {\n            foreach (var x in self.AsEnumerable())\n            {\n                foreach (var y in f(x))\n                {\n                    yield return y;\n                }\n            }\n        }\n        return new Set<OrdB, B>(Yield(), true);\n    }\n\n    [Pure]\n    public Set<OrdA, A> Bind(Func<A, Set<OrdA, A>> f)\n    {\n        var self = this;\n\n        IEnumerable<A> Yield()\n        {\n            foreach (var x in self.AsEnumerable())\n            {\n                foreach (var y in f(x))\n                {\n                    yield return y;\n                }\n            }\n        }\n        return new Set<OrdA, A>(Yield(), true);\n    }\n\n    [Pure]\n    public Iterable<A> Skip(int amount) =>\n        Value.Skip(amount);\n\n    [Pure]\n    public int CompareTo(Set<OrdA, A> other) =>\n        Value.CompareTo(other.Value);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    public static implicit operator Set<OrdA, A>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Creates a new map from a range/slice of this map\n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <returns></returns>\n    [Pure]\n    public Set<OrdA, A> Slice(A keyFrom, A keyTo) =>\n        new (FindRange(keyFrom, keyTo));\n\n    /// <summary>\n    /// Find the lowest ordered item in the set\n    /// </summary>\n    [Pure]\n    public Option<A> Min => Value.Min;\n\n    /// <summary>\n    /// Find the highest ordered item in the set\n    /// </summary>\n    [Pure]\n    public Option<A> Max => Value.Max;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Set.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable set\n/// AVL tree implementation\n/// AVL tree is a self-balancing binary search tree. \n/// [wikipedia.org/wiki/AVL_tree](http://en.wikipedia.org/wiki/AVL_tree)\n/// </summary>\n/// <typeparam name=\"A\">Set item type</typeparam>\n[Serializable]\n[CollectionBuilder(typeof(Set), nameof(Set.createRange))]\npublic readonly struct Set<A> : \n    IEquatable<Set<A>>,\n    IComparable<Set<A>>,\n    IComparable,\n    IComparisonOperators<Set<A>, Set<A>, bool>,\n    IAdditionOperators<Set<A>, Set<A>, Set<A>>,\n    ISubtractionOperators<Set<A>, Set<A>, Set<A>>,\n    IAdditiveIdentity<Set<A>, Set<A>>,\n    IReadOnlyCollection<A>,\n    Monoid<Set<A>>,\n    K<Set, A>\n{\n    public static Set<A> Empty { get; } = new(SetInternal<OrdDefault<A>, A>.Empty);\n\n    readonly SetInternal<OrdDefault<A>, A> value;\n\n    internal SetInternal<OrdDefault<A>, A> Value => value ?? Empty.Value;\n\n    /// <summary>\n    /// Ctor from an enumerable \n    /// </summary>\n    public Set(IEnumerable<A> items) : this(items, true)\n    {\n    }\n\n    /// <summary>\n    /// Ctor from an enumerable \n    /// </summary>\n    public Set(ReadOnlySpan<A> items) : this(items, true)\n    {\n    }\n\n    /// <summary>\n    /// Default ctor\n    /// </summary>\n    internal Set(SetInternal<OrdDefault<A>, A> set) =>\n        value = set;\n\n    /// <summary>\n    /// Ctor that takes a root element\n    /// </summary>\n    /// <param name=\"root\"></param>\n    internal Set(SetItem<A> root) =>\n        value = new SetInternal<OrdDefault<A>, A>(root);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    public Set(IEnumerable<A> items, bool tryAdd) =>\n        value = new SetInternal<OrdDefault<A>, A>(\n            items, \n            tryAdd\n                ? SetModuleM.AddOpt.TryAdd\n                : SetModuleM.AddOpt.ThrowOnDuplicate);\n\n    /// <summary>\n    /// Ctor that takes an initial (distinct) set of items\n    /// </summary>\n    /// <param name=\"items\"></param>\n    public Set(ReadOnlySpan<A> items, bool tryAdd) =>\n        value = new SetInternal<OrdDefault<A>, A>(\n            items, \n            tryAdd\n                ? SetModuleM.AddOpt.TryAdd\n                : SetModuleM.AddOpt.ThrowOnDuplicate);\n\n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    public static Lens<Set<A>, bool> item(A key) => Lens<Set<A>, bool>.New(\n        Get: la => la.Contains(key),\n        Set: a => la => a ? la.AddOrUpdate(key) : la.Remove(key));\n\n    /// <summary>\n    /// Lens map\n    /// </summary>\n    [Pure]\n    public static Lens<Set<A>, Set<A>> map(Lens<A, A> lens) => Lens<Set<A>, Set<A>>.New(\n        Get: la => la.Map(lens.Get),\n        Set: lb => la =>\n                   {\n                       foreach (var item in lb)\n                       {\n                           la = la.Find(item).Match(Some: x => la.AddOrUpdate(lens.Set(x, item)), None: () => la);\n                       }\n                       return la;\n                   });\n\n    static Set<A> Wrap(SetInternal<OrdDefault<A>, A> set) =>\n        new (set);\n\n    static Set<B> Wrap<B>(SetInternal<OrdDefault<B>, B> set) =>\n        new (set);\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = null\n    ///     Singleton collection = A\n    ///     More                 = (A, Seq〈A〉)   -- head and tail\n    ///\n    ///     var res = set.Case switch\n    ///     {\n    ///       \n    ///        (var x, var xs) => ...,\n    ///        A value         => ...,\n    ///        _               => ...\n    ///     }\n    /// \n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty\n            ? null\n            : toSeq(Value).Case;\n\n    /*\n    /// <summary>\n    /// Stream as an enumerable\n    /// </summary>\n    [Pure]\n    public StreamT<M, A> AsStream<M>()\n        where M : Monad<M> =>\n        StreamT<M, A>.Lift(AsEnumerable());\n        */\n\n    /// <summary>\n    /// Add an item to the set\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item added</returns>\n    [Pure]\n    public Set<A> Add(A value) =>\n        Wrap(Value.Add(value));\n\n    /// <summary>\n    /// Attempt to add an item to the set.  If an item already\n    /// exists then return the Set as-is.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public Set<A> TryAdd(A value) =>\n        Wrap(Value.TryAdd(value));\n\n    /// <summary>\n    /// Add an item to the set.  If an item already\n    /// exists then replace it.\n    /// </summary>\n    /// <param name=\"value\">Value to add to the set</param>\n    /// <returns>New set with the item maybe added</returns>\n    [Pure]\n    public Set<A> AddOrUpdate(A value) =>\n        Wrap(Value.AddOrUpdate(value));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public Set<A> AddRange(IEnumerable<A> range) =>\n        Wrap(Value.AddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists, it's ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public Set<A> TryAddRange(IEnumerable<A> range) =>\n        Wrap(Value.TryAddRange(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the set.  If an item already exists then replace it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key</remarks>\n    /// <param name=\"range\">Range of keys to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if any of the keys are null</exception>\n    /// <returns>New Set with the items added</returns>\n    [Pure]\n    public Set<A> AddOrUpdateRange(IEnumerable<A> range) =>\n        Wrap(Value.AddOrUpdateRange(range));\n\n    /// <summary>\n    /// Attempts to find an item in the set.  \n    /// </summary>\n    /// <param name=\"value\">Value to find</param>\n    /// <returns>Some(T) if found, None otherwise</returns>\n    [Pure]\n    public Option<A> Find(A value) =>\n        Value.Find(value);\n\n    /// <summary>\n    /// Retrieve a range of values \n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keyFrom or keyTo are null</exception>\n    /// <returns>Range of values</returns>\n    [Pure]\n    public Iterable<A> FindRange(A keyFrom, A keyTo) => Value.FindRange(keyFrom, keyTo);\n\n    /// <summary>\n    /// Retrieve the value from previous item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindPredecessor(A key) => Value.FindPredecessor(key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the previous item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindExactOrPredecessor(A key) => Value.FindOrPredecessor(key);\n\n    /// <summary>\n    /// Retrieve the value from next item to specified key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindSuccessor(A key) => Value.FindSuccessor(key);\n\n    /// <summary>\n    /// Retrieve the value from exact key, or if not found, the next item \n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found key</returns>\n    [Pure]\n    public Option<A> FindExactOrSuccessor(A key) => Value.FindOrSuccessor(key);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public Set<A> Intersect(IEnumerable<A> other) =>\n        Wrap(Value.Intersect(other));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public Set<A> Except(IEnumerable<A> other) =>\n        other is Set<A> set\n            ? Except(set)\n            : Wrap(Value.Except(other));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public Set<A> Except(Set<A> other) =>\n        Wrap(Value.Except(other.Value));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public Set<A> SymmetricExcept(IEnumerable<A> other) =>\n        other is Set<A> set\n            ? SymmetricExcept(set)\n            : Wrap(Value.SymmetricExcept(other));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public Set<A> SymmetricExcept(Set<A> other) =>\n        Wrap(Value.SymmetricExcept(other.Value));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public Set<A> Union(IEnumerable<A> other) =>\n        Wrap(Value.Union(other));\n\n    /// <summary>\n    /// Clears the set\n    /// </summary>\n    /// <returns>An empty set</returns>\n    [Pure]\n    public Set<A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns>IEnumerator T</returns>\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns>IEnumerator</returns>\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// Removes an item from the set (if it exists)\n    /// </summary>\n    /// <param name=\"value\">Value to remove</param>\n    /// <returns>New set with item removed</returns>\n    [Pure]\n    public Set<A> Remove(A value) =>\n        Wrap(Value.Remove(value));\n\n    /// <summary>\n    /// Removes a range of items from the set (if they exist)\n    /// </summary>\n    /// <param name=\"value\">Value to remove</param>\n    /// <returns>New set with items removed</returns>\n    [Pure]\n    public Set<A> RemoveRange(IEnumerable<A> values)\n    {\n        var set = Value;\n        foreach(var x in values)\n        {\n            set = set.Remove(x);\n        }\n        return Wrap(set);\n    }\n\n    /// <summary>\n    /// Impure iteration of the bound value in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Set<A> Do(Action<A> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Maps the values of this set into a new set of values using the\n    /// mapper function to tranform the source values.\n    /// </summary>\n    /// <typeparam name=\"R\">Mapped element type</typeparam>\n    /// <param name=\"mapper\">Mapping function</param>\n    /// <returns>Mapped Set</returns>\n    [Pure]\n    public Set<B> Map<B>(Func<A, B> map) =>\n        Wrap(Value.Map<OrdDefault<B>, B>(map));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Set<B>> Traverse<F, B>(Func<A, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n        \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, Set<B>> TraverseM<M, B>(Func<A, K<M, B>> f) \n        where M : Monad<M> =>\n        M.Map(x => x.As(), Traversable.traverseM(f, this));\n    \n    /// <summary>\n    /// Filters items from the set using the predicate.  If the predicate\n    /// returns True for any item then it remains in the set, otherwise\n    /// it's dropped.\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Filtered enumerable</returns>\n    [Pure]\n    public Set<A> Filter(Func<A, bool> pred) =>\n        Wrap(Value.Filter(pred));\n\n    /// <summary>\n    /// Check the existence of an item in the set using a \n    /// predicate.\n    /// </summary>\n    /// <remarks>Note this scans the entire set.</remarks>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if predicate returns true for any item</returns>\n    [Pure]\n    public bool Exists(Func<A, bool> pred) =>\n        Value.Exists(pred);\n\n    /// <summary>\n    /// Returns True if the value is in the set\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if the item 'value' is in the Set 'set'</returns>\n    [Pure]\n    public bool Contains(A value) =>\n        Value.Contains(value);\n\n    /// <summary>\n    /// Returns true if both sets contain the same elements\n    /// </summary>\n    /// <param name=\"other\">Other distinct set to compare</param>\n    /// <returns>True if the sets are equal</returns>\n    [Pure]\n    public bool SetEquals(IEnumerable<A> other) =>\n        Value.SetEquals(other);\n\n    /// <summary>\n    /// Is the set empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the set\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n        \n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<A> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<A> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<A> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<A> other) =>\n        Value.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    /// <typeparam name=\"T\">Element type</typeparam>\n    /// <param name=\"setA\">Set A</param>\n    /// <param name=\"setB\">Set B</param>\n    /// <returns>True if other overlaps this set</returns>\n    [Pure]\n    public bool Overlaps(IEnumerable<A> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public void CopyTo(A[] array, int index) =>\n        Value.CopyTo(array, index);\n\n    /// <summary>\n    /// Copy the items from the set into the specified array\n    /// </summary>\n    /// <param name=\"array\">Array to copy to</param>\n    /// <param name=\"index\">Index into the array to start</param>\n    public void CopyTo(Array array, int index) =>\n        Value.CopyTo(array, index);\n\n    /// <summary>\n    /// Add operator + performs a union of the two sets\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Unioned set</returns>\n    [Pure]\n    public static Set<A> operator +(Set<A> lhs, Set<A> rhs) =>\n        Wrap(lhs.Value + rhs.Value);\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Set<A> operator |(Set<A> x, K<Set, A> y) =>\n        x.Choose(y).As();\n\n    /// <summary>\n    /// Choice operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Set<A> operator |(K<Set, A> x, Set<A> y) =>\n        x.Choose(y).As();\n\n    /// <summary>\n    /// Append performs a union of the two sets\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Unioned set</returns>\n    [Pure]\n    public Set<A> Combine(Set<A> rhs) =>\n        Wrap(Value.Append(rhs.Value));\n\n    /// <summary>\n    /// Subtract operator - performs a subtract of the two sets\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Subtractd set</returns>\n    [Pure]\n    public static Set<A> operator -(Set<A> lhs, Set<A> rhs) =>\n        Wrap(lhs.Value - rhs.Value);\n\n    /// <summary>\n    /// Subtract operator - performs a subtract of the two sets\n    /// </summary>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>Subtracted set</returns>\n    [Pure]\n    public Set<A> Subtract(Set<A> rhs) =>\n        Wrap(Value.Subtract(rhs.Value));\n\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"other\">Other set to test</param>\n    /// <returns>True if sets are equal</returns>\n    [Pure]\n    public bool Equals(Set<A> other) =>\n        Value.SetEquals(other.Value.AsIterable());\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>True if the two sets are equal</returns>\n    [Pure]\n    public static bool operator ==(Set<A> lhs, Set<A> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Non-equality operator\n    /// </summary>\n    /// <param name=\"lhs\">Left hand side set</param>\n    /// <param name=\"rhs\">Right hand side set</param>\n    /// <returns>True if the two sets are equal</returns>\n    [Pure]\n    public static bool operator !=(Set<A> lhs, Set<A> rhs) =>\n        !lhs.Equals(rhs);\n\n    [Pure]\n    public static bool operator <(Set<A> lhs, Set<A> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    [Pure]\n    public static bool operator <=(Set<A> lhs, Set<A> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    [Pure]\n    public static bool operator >(Set<A> lhs, Set<A> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    [Pure]\n    public static bool operator >=(Set<A> lhs, Set<A> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is Set<A> set && Equals(set);\n\n    /// <summary>\n    /// Get the hash code.  Calculated from all items in the set.\n    /// </summary>\n    /// <remarks>\n    /// The hash-code is cached after the first read.\n    /// </remarks>\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj is Set<A> t ? CompareTo(t) : 1;\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The ellipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(this, Count);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(this, separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(this, separator);\n\n    [Pure]\n    public Seq<A> ToSeq() =>\n        toSeq(this);\n\n    [Pure]\n    public Iterable<A> AsEnumerable() =>\n        Iterable.createRange(this);\n\n    [Pure]\n    public Set<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    [Pure]\n    public Set<A> Where(Func<A, bool> pred) =>\n        Filter(pred);\n\n    [Pure]\n    public Set<B> Bind<B>(Func<A, Set<B>> f)\n    {\n        var self = this;\n\n        IEnumerable<B> Yield()\n        {\n            foreach (var x in self.AsEnumerable())\n            {\n                foreach (var y in f(x))\n                {\n                    yield return y;\n                }\n            }\n        }\n        return new Set<B>(Yield(), true);\n    }\n\n    [Pure]\n    public Set<C> SelectMany<B, C>(Func<A, Set<B>> bind, Func<A, B, C> project)\n    {\n        var self = this;\n\n        IEnumerable<C> Yield()\n        {\n            foreach(var x in self.AsEnumerable())\n            {\n                foreach(var y in bind(x))\n                {\n                    yield return project(x, y);\n                }\n            }\n        }\n        return new Set<C>(Yield(), true);\n    }\n\n    [Pure]\n    public Iterable<A> Skip(int amount) =>\n        Value.Skip(amount);\n\n    [Pure]\n    public int CompareTo(Set<A> other) =>\n        Value.CompareTo(other.Value);\n\n    [Pure]\n    public int CompareTo<OrdA>(Set<A> other) where OrdA : Ord<A> =>\n        Value.CompareTo<OrdA>(other.Value);\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    public static implicit operator Set<A>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Creates a new map from a range/slice of this map\n    /// </summary>\n    /// <param name=\"keyFrom\">Range start (inclusive)</param>\n    /// <param name=\"keyTo\">Range to (inclusive)</param>\n    /// <returns></returns>\n    [Pure]\n    public Set<A> Slice(A keyFrom, A keyTo) =>\n        new (FindRange(keyFrom, keyTo));\n\n    /// <summary>\n    /// Find the lowest ordered item in the set\n    /// </summary>\n    [Pure]\n    public Option<A> Min => Value.Min;\n\n    /// <summary>\n    /// Find the highest ordered item in the set\n    /// </summary>\n    [Pure]\n    public Option<A> Max => Value.Max;\n\n    public static Set<A> AdditiveIdentity => \n        Empty;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Set/Trait/Set.TraitImpl.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Set : \n    Monad<Set>,\n    MonoidK<Set>,\n    Alternative<Set>, \n    Traversable<Set>\n{\n    static K<Set, B> Monad<Set>.Recur<A, B>(A value, Func<A, K<Set, Next<A, B>>> f) =>\n        createRange(Monad.enumerableRecur(value, x =>f(x).As().AsEnumerable()));\n    \n    static K<Set, B> Monad<Set>.Bind<A, B>(K<Set, A> ma, Func<A, K<Set, B>> f)\n    {\n        return new Set<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var x in ma.As())\n            {\n                foreach (var y in f(x).As())\n                {\n                    yield return y;\n                }\n            }\n        }\n    }\n\n    static K<Set, B> Functor<Set>.Map<A, B>(Func<A, B> f, K<Set, A> ma)\n    {\n        return new Set<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var x in ma.As())\n            {\n                yield return f(x);\n            }\n        }\n    }\n\n    static K<Set, A> Applicative<Set>.Pure<A>(A value) =>\n        singleton(value);\n\n    static K<Set, B> Applicative<Set>.Apply<A, B>(K<Set, Func<A, B>> mf, K<Set, A> ma)\n    {\n        return new Set<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var f in mf.As())\n            {\n                foreach (var a in ma.As())\n                {\n                    yield return f(a);\n                }\n            }\n        }\n    }    \n\n    static K<Set, B> Applicative<Set>.Apply<A, B>(K<Set, Func<A, B>> mf, Memo<Set, A> ma)\n    {\n        return new Set<B>(Go());\n        IEnumerable<B> Go()\n        {\n            foreach (var f in mf.As())\n            {\n                foreach (var a in ma.Value.As())\n                {\n                    yield return f(a);\n                }\n            }\n        }\n    }    \n\n    static K<Set, A> MonoidK<Set>.Empty<A>() =>\n        Set<A>.Empty;\n\n    static K<Set, A> Alternative<Set>.Empty<A>() =>\n        Set<A>.Empty;\n\n    static K<Set, A> SemigroupK<Set>.Combine<A>(K<Set, A> ma, K<Set, A> mb) =>\n        ma.As() + mb.As();\n    \n    static K<Set, A> Choice<Set>.Choose<A>(K<Set, A> ma, K<Set, A> mb) => \n        ma.IsEmpty ? mb : ma;\n\n    static K<Set, A> Choice<Set>.Choose<A>(K<Set, A> ma, Memo<Set, A> mb) => \n        ma.IsEmpty ? mb.Value : ma;\n\n    static bool Foldable<Set>.Contains<EqA, A>(A value, K<Set, A> ta) =>\n        ta.As().Contains(value);\n\n    static int Foldable<Set>.Count<A>(K<Set, A> ta) =>\n        ta.As().Count;\n\n    static bool Foldable<Set>.IsEmpty<A>(K<Set, A> ta) =>\n        ta.As().IsEmpty;\n\n    static S Foldable<Set>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Set, A> ta)\n    {\n        foreach (var x in ta.As())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(x)(state);\n        }\n        return state;\n    }\n    \n    static S Foldable<Set>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S state, \n        K<Set, A> ta)\n    {\n        foreach (var x in ta.As().Reverse())\n        {\n            if (!predicate((state, x))) return state;\n            state = f(state)(x);\n        }\n        return state;\n    }    \n\n    static K<F, K<Set, B>> Traversable<Set>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Set, A> ta) \n    {\n        return F.Map<Set<B>, K<Set, B>>(\n            ks => ks,\n            Foldable.fold(acc, F.Pure(empty<B>()), ta));\n\n        K<F, Set<B>> acc(K<F, Set<B>> ys, A x) =>\n            Applicative.lift((bs, b) => bs.Add(b), ys, f(x));\n    }\n\n    static K<F, K<Set, B>> Traversable<Set>.TraverseM<F, A, B>(Func<A, K<F, B>> f, K<Set, A> ta) \n    {\n        return F.Map<Set<B>, K<Set, B>>(\n            ks => ks,\n            Foldable.fold(acc, F.Pure(empty<B>()), ta));\n\n        K<F, Set<B>> acc(K<F, Set<B>> fys, A x) =>\n            fys.Bind(ys => f(x).Map(ys.Add));\n    }\n    \n    static Option<A> Foldable<Set>.Head<A>(K<Set, A> ta) =>\n        ta.As().Min;\n\n    static Option<A> Foldable<Set>.Last<A>(K<Set, A> ta) =>\n        ta.As().Max;\n\n    static Option<A> Foldable<Set>.Min<A>(K<Set, A> ta) =>\n        ta.As().Min;\n\n    static Option<A> Foldable<Set>.Max<A>(K<Set, A> ta) =>\n        ta.As().Max;\n    \n    static Fold<A, S> Foldable<Set>.FoldStep<A, S>(K<Set, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }   \n        \n    static Fold<A, S> Foldable<Set>.FoldStepBack<A, S>(K<Set, A> ta, S initialState)\n    {\n        // ReSharper disable once GenericEnumeratorNotDisposed\n        var iter = ta.As().Reverse().GetEnumerator();\n        return go(initialState);\n        Fold<A, S> go(S state) =>\n            iter.MoveNext()\n                ? Fold.Loop(state, iter.Current, go)\n                : Fold.Done<A, S>(state);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Stack/Stack.Extensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class StackExtensions\n{\n    /// <summary>\n    /// Projects the values in the stack using a map function into a new enumerable (Select in LINQ).\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"stack\">Stack to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Stck<R> Map<T, R>(this Stck<T> stack, Func<T, R> map) =>\n        toStackRev(List.map(stack, map));\n\n    /// <summary>\n    /// Projects the values in the stack into a new stack using a map function, which is also given an index value\n    /// (Select in LINQ - note that the order of the arguments of the map function are the other way around, here the index\n    /// is the first argument).\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"stack\">Stack to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Stck<R> Map<T, R>(this Stck<T> stack, Func<int, T, R> map) =>\n        toStackRev(List.map(stack, map));\n\n    /// <summary>\n    /// Removes items from the stack that do not match the given predicate (Where in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to filter</param>\n    /// <param name=\"predicate\">Predicate function</param>\n    /// <returns>Filtered stack</returns>\n    [Pure]\n    public static Stck<T> Filter<T>(this Stck<T> stack, Func<T, bool> predicate) =>\n        toStackRev(List.filter(stack, predicate));\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the stack. Returns an enumerable comprised of \n    /// the results for each element where the function returns Some(f(x)).\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered enumerable</returns>\n    [Pure]\n    public static Stck<U> Choose<T, U>(this Stck<T> stack, Func<T, Option<U>> selector) =>\n        toStackRev(List.choose(stack, selector));\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the stack. Returns an enumerable comprised of \n    /// the results for each element where the function returns Some(f(x)).\n    /// An index value is passed through to the selector function also.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered enumerable</returns>\n    [Pure]\n    public static Stck<U> Choose<T, U>(this Stck<T> stack, Func<int, T, Option<U>> selector) =>\n        toStackRev(List.choose(stack, selector));\n\n    /// <summary>\n    /// For each element of the stack, applies the given function. Concatenates all the results and \n    /// returns the combined list.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"stack\">Stack to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Stck<R> Collect<T, R>(this Stck<T> stack, Func<T, IEnumerable<R>> map) =>\n        toStackRev(List.collect(stack, map));\n\n    /// <summary>\n    /// Reverses the order of the items in the stack\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public static Stck<T> Rev<T>(this Stck<T> stack) =>\n        toStackRev(List.rev(stack));\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the stack. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S Fold<S, T>(this Stck<T> stack, S state, Func<S, T, S> folder) =>\n        List.fold(stack, state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the stack. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S FoldBack<S, T>(this Stck<T> stack, S state, Func<S, T, S> folder) =>\n        List.foldBack(stack, state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection whilst the predicate function \n    /// returns true for the item being processed, threading an aggregate state through the \n    /// computation. The fold function takes the state argument, and applies the function 'folder' \n    /// to it and the first element of the stack. Then, it feeds this result into the function 'folder' \n    /// along with the second element, and so on. It returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"preditem\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S FoldWhile<S, T>(this Stck<T> stack, S state, Func<S, T, S> folder, Func<T, bool> preditem) =>\n        List.foldWhile(stack, state, folder, preditem: preditem);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation (and whilst the predicate function returns true when passed \n    /// the aggregate state). The fold function takes the state argument, and applies the function \n    /// 'folder' to it and the first element of the stack. Then, it feeds this result into the \n    /// function 'folder' along with the second element, and so on. It returns the final result. \n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"predstate\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S FoldWhile<S, T>(this Stck<T> stack, S state, Func<S, T, S> folder, Func<S, bool> predstate) =>\n        List.foldWhile(stack, state, folder, predstate: predstate);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first)\n    /// whilst the predicate function returns true for the item being processed, threading an \n    /// aggregate state through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the stack. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"preditem\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S FoldBackWhile<S, T>(this Stck<T> stack, S state, Func<S, T, S> folder, Func<T, bool> preditem) =>\n        List.foldBackWhile(stack, state, folder, preditem: preditem);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an accumulator argument through the computation (and whilst the predicate function \n    /// returns true when passed the aggregate state). The fold function takes the state argument, \n    /// and applies the function 'folder' to it and the first element of the stack. Then, it feeds \n    /// this result into the function 'folder' along with the second element, and so on. It returns \n    /// the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"predstate\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S FoldBackWhile<S, T>(this Stck<T> stack, S state, Func<S, T, S> folder, Func<S, bool> predstate) =>\n        List.foldBackWhile(stack, state, folder, predstate: predstate);\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function first applies the function to the first two \n    /// elements of the stack. Then, it passes this result into the function along with the third \n    /// element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static T ReduceBack<T>(Stck<T> stack, Func<T, T, T> reducer) =>\n        List.reduceBack(stack, reducer);\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from last element to first), threading \n    /// an accumulator argument through the computation. This function first applies the function \n    /// to the first two elements of the stack. Then, it passes this result into the function along \n    /// with the third element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static T Reduce<T>(this Stck<T> stack, Func<T, T, T> reducer) =>\n        List.reduce(stack, reducer);\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function takes the state argument, and applies the function \n    /// to it and the first element of the stack. Then, it passes this result into the function \n    /// along with the second element, and so on. Finally, it returns the list of intermediate \n    /// results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static Stck<S> Scan<S, T>(this Stck<T> stack, S state, Func<S, T, S> folder) =>\n        toStackRev(List.scan(stack, state, folder));\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from last element to first), \n    /// threading an accumulator argument through the computation. This function takes the state \n    /// argument, and applies the function to it and the first element of the stack. Then, it \n    /// passes this result into the function along with the second element, and so on. Finally, \n    /// it returns the list of intermediate results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static Stck<S> ScanBack<S, T>(this Stck<T> stack, S state, Func<S, T, S> folder) =>\n        toStackRev(List.scanBack(stack, state, folder));\n\n    /// <summary>\n    /// Returns Some(x) for the first item in the stack that matches the predicate \n    /// provided, None otherwise.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Some(x) for the first item in the stack that matches the predicate \n    /// provided, None otherwise.</returns>\n    [Pure]\n    public static Option<T> Find<T>(this Stck<T> stack, Func<T, bool> pred) =>\n        List.find(stack, pred);\n\n    /// <summary>\n    /// Returns the number of items in the stack\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>The number of items in the enumerable</returns>\n    [Pure]\n    public static int Length<T>(this Stck<T> stack) =>\n        List.length(stack);\n\n    /// <summary>\n    /// Invokes an action for each item in the stack in order\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to iterate</param>\n    /// <param name=\"action\">Action to invoke with each item</param>\n    /// <returns>Unit</returns>\n    public static Unit Iter<T>(this Stck<T> stack, Action<T> action) =>\n        List.iter(stack, action);\n\n    /// <summary>\n    /// Invokes an action for each item in the stack in order and supplies\n    /// a running index value.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to iterate</param>\n    /// <param name=\"action\">Action to invoke with each item</param>\n    /// <returns>Unit</returns>\n    public static Unit Iter<T>(this Stck<T> stack, Action<int, T> action) =>\n        List.iter(stack, action);\n\n    /// <summary>\n    /// Return an enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>An enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static bool ForAll<T>(this Stck<T> stack, Func<T, bool> pred) =>\n        List.forall(stack, pred);\n\n    /// <summary>\n    /// Return an enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>An enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static Stck<T> Distinct<T>(this Stck<T> stack) =>\n        toStackRev(List.distinct(stack));\n\n    /// <summary>\n    /// Return an enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>An enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static Stck<T> Distinct<EQ,T>(this Stck<T> stack) where EQ : Eq<T> =>\n        toStackRev(List.distinct<EQ,T>(stack));\n\n    /// <summary>\n    /// Return an enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>An enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static Stck<T> Distinct<T, K>(this Stck<T> stack, Func<T, K> keySelector, Option<Func<K, K, bool>> compare = default(Option<Func<K, K, bool>>)) =>\n        toStackRev(List.distinct(stack, keySelector, compare));\n\n    /// <summary>\n    /// Returns a new enumerable with the first 'count' items from the stack\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first 'count' items from the enumerable provided</returns>\n    [Pure]\n    public static Stck<T> Take<T>(this Stck<T> stack, int count) =>\n        toStackRev(List.take(stack, count));\n\n    /// <summary>\n    /// Iterate the stack, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first items that match the predicate</returns>\n    [Pure]\n    public static Stck<T> TakeWhile<T>(this Stck<T> stack, Func<T, bool> pred) =>\n        toStackRev(List.takeWhile(stack, pred));\n\n    /// <summary>\n    /// Iterate the stack, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't  An index value is also provided to the predicate function.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first items that match the predicate</returns>\n    [Pure]\n    public static Stck<T> TakeWhile<T>(this Stck<T> stack, Func<T, int, bool> pred) =>\n        toStackRev(List.takeWhile(stack, pred));\n\n    /// <summary>\n    /// Returns true if any item in the stack matches the predicate provided\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if any item in the stack matches the predicate provided</returns>\n    [Pure]\n    public static bool Exists<T>(this Stck<T> stack, Func<T, bool> pred) =>\n        List.exists(stack, pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Stack/Stack.Module.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Functional module for working with the Stck T type\n/// </summary>\npublic static class Stack\n{\n    /// <summary>\n    /// Create a new stack from a single element\n    /// </summary>\n    /// <param name=\"item\">Item to populate the singleton stack</param>\n    /// <typeparam name=\"A\">Type of the items</typeparam>\n    /// <returns>Constructed stack collection</returns>\n    public static Stck<A> singleton<A>(A item) =>\n        [item];\n    \n    /// <summary>\n    /// Create a new stack from an existing span\n    /// </summary>\n    /// <param name=\"items\">Items to populate the stack</param>\n    /// <typeparam name=\"A\">Type of the items</typeparam>\n    /// <returns>Constructed stack collection</returns>\n    public static Stck<A> createRange<A>(IEnumerable<A> items) =>\n        new (items);\n    \n    /// <summary>\n    /// Create a new stack from an existing span\n    /// </summary>\n    /// <param name=\"items\">Items to populate the stack</param>\n    /// <typeparam name=\"A\">Type of the items</typeparam>\n    /// <returns>Constructed stack collection</returns>\n    public static Stck<A> createRange<A>(ReadOnlySpan<A> items) =>\n        items.IsEmpty\n            ? Stck<A>.Empty\n            : new (items);\n    \n    /// <summary>\n    /// Reverses the order of the items in the stack\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public static Stck<T> rev<T>(Stck<T> stack) =>\n        stack.Reverse();\n\n    /// <summary>\n    /// True if the stack is empty\n    /// </summary>\n    [Pure]\n    public static bool isEmpty<T>(Stck<T> stack) =>\n        stack.IsEmpty;\n\n    /// <summary>\n    /// Clear the stack (returns Empty)\n    /// </summary>\n    /// <returns>Stck.Empty of T</returns>\n    [Pure]\n    public static Stck<T> clear<T>(Stck<T> stack) =>\n        stack.Clear();\n\n    /// <summary>\n    /// Return the item on the top of the stack without affecting the stack itself\n    /// NOTE: Will throw an ExpectedException if the stack is empty\n    /// </summary>\n    /// <exception cref=\"ExpectedException\">Stack is empty</exception>\n    /// <returns>Top item value</returns>\n    [Pure]\n    public static T peek<T>(Stck<T> stack) =>\n        stack.Peek();\n\n    /// <summary>\n    /// Peek and match\n    /// </summary>\n    /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n    /// <param name=\"None\">Handler if the stack is empty</param>\n    /// <returns>Untouched stack</returns>\n    [Pure]\n    public static Stck<T> peek<T>(Stck<T> stack, Action<T> Some, Action None) =>\n        stack.Peek(Some, None);\n\n    /// <summary>\n    /// Peek and match\n    /// </summary>\n    /// <typeparam name=\"R\">Return type</typeparam>\n    /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n    /// <param name=\"None\">Handler if the stack is empty</param>\n    /// <returns>Return value from Some or None</returns>\n    [Pure]\n    public static R peek<T, R>(Stck<T> stack, Func<T, R> Some, Func<R> None) =>\n        stack.Peek(Some, None);\n\n    /// <summary>\n    /// Safely return the item on the top of the stack without affecting the stack itself\n    /// </summary>\n    /// <returns>Returns the top item value, or None</returns>\n    [Pure]\n    public static Option<T> trypeek<T>(Stck<T> stack) =>\n        stack.TryPeek();\n\n    /// <summary>\n    /// Pop an item off the top of the stack\n    /// NOTE: Will throw an ExpectedException if the stack is empty\n    /// </summary>\n    /// <exception cref=\"ExpectedException\">Stack is empty</exception>\n    /// <returns>Stack with the top item popped</returns>\n    [Pure]\n    public static Stck<T> pop<T>(Stck<T> stack) =>\n        stack.Pop();\n\n    /// <summary>\n    /// Safe pop\n    /// </summary>\n    /// <returns>Tuple of popped stack and optional top-of-stack value</returns>\n    [Pure]\n    public static (Stck<T>, Option<T>) trypop<T>(Stck<T> stack) =>\n        stack.TryPop();\n\n    /// <summary>\n    /// Pop and match\n    /// </summary>\n    /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n    /// <param name=\"None\">Handler if the stack is empty</param>\n    /// <returns>Popped stack</returns>\n    [Pure]\n    public static Stck<T> pop<T>(Stck<T> stack, Action<T> Some, Action None) =>\n        stack.Pop(Some, None);\n\n    /// <summary>\n    /// Pop and match\n    /// </summary>\n    /// <typeparam name=\"R\">Return type</typeparam>\n    /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n    /// <param name=\"None\">Handler if the stack is empty</param>\n    /// <returns>Return value from Some or None</returns>\n    [Pure]\n    public static R pop<T, R>(Stck<T> stack, Func<Stck<T>, T, R> Some, Func<R> None) =>\n        stack.Pop(Some, None);\n\n    /// <summary>\n    /// Push an item onto the stack\n    /// </summary>\n    /// <param name=\"value\">Item to push</param>\n    /// <returns>New stack with the pushed item on top</returns>\n    [Pure]\n    public static Stck<T> push<T>(Stck<T> stack, T value) =>\n        stack.Push(value);\n\n    /// <summary>\n    /// Projects the values in the stack using a map function into a new enumerable (Select in LINQ).\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"stack\">Stack to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Stck<R> map<T, R>(Stck<T> stack, Func<T, R> map) =>\n        toStackRev(List.map(stack, map));\n\n    /// <summary>\n    /// Projects the values in the stack into a new enumerable using a map function, which is also given an index value\n    /// (Select in LINQ - note that the order of the arguments of the map function are the other way around, here the index\n    /// is the first argument).\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"stack\">Stack to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Stck<R> map<T, R>(Stck<T> stack, Func<int, T, R> map) =>\n        toStackRev(List.map(stack, map));\n\n    /// <summary>\n    /// Removes items from the stack that do not match the given predicate (Where in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to filter</param>\n    /// <param name=\"predicate\">Predicate function</param>\n    /// <returns>Filtered stack</returns>\n    [Pure]\n    public static Stck<T> filter<T>(Stck<T> stack, Func<T, bool> predicate) =>\n        toStackRev(List.filter(stack, predicate));\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the stack. Returns an enumerable comprised of \n    /// the results for each element where the function returns Some(f(x)).\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered enumerable</returns>\n    [Pure]\n    public static Stck<U> choose<T, U>(Stck<T> stack, Func<T, Option<U>> selector) =>\n        toStackRev(List.choose(stack, selector));\n\n    /// <summary>\n    /// Applies the given function 'selector' to each element of the stack. Returns an enumerable comprised of \n    /// the results for each element where the function returns Some(f(x)).\n    /// An index value is passed through to the selector function also.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"selector\">Selector function</param>\n    /// <returns>Mapped and filtered enumerable</returns>\n    [Pure]\n    public static Stck<U> choose<T, U>(Stck<T> stack, Func<int, T, Option<U>> selector) =>\n        toStackRev(List.choose(stack, selector));\n\n    /// <summary>\n    /// For each element of the stack, applies the given function. Concatenates all the results and \n    /// returns the combined list.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <typeparam name=\"R\">Return enumerable item type</typeparam>\n    /// <param name=\"stack\">Stack to map</param>\n    /// <param name=\"map\">Map function</param>\n    /// <returns>Mapped enumerable</returns>\n    [Pure]\n    public static Stck<R> collect<T, R>(Stck<T> stack, Func<T, IEnumerable<R>> map) =>\n        toStackRev(List.collect(stack, map));\n\n    /// <summary>\n    /// Append another stack to the top of this stack\n    /// The rhs will be reversed and pushed onto 'this' stack.  That will\n    /// maintain the order of the items in the resulting stack.  So the top\n    /// of 'rhs' will be the top of the newly created stack.  'this' stack\n    /// will be under the 'rhs' stack.\n    /// </summary>\n    /// <param name=\"rhs\">Stack to append</param>\n    /// <returns>Appended stacks</returns>\n    [Pure]\n    public static Stck<T> append<T>(Stck<T> lhs, IEnumerable<T> rhs) =>\n        toStackRev(List.append(lhs, rhs));\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the stack. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result. (Aggregate in LINQ)\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S fold<S, T>(Stck<T> stack, S state, Func<S, T, S> folder) =>\n        List.fold(stack, state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an aggregate state through the computation. The fold function takes the state \n    /// argument, and applies the function 'folder' to it and the first element of the stack. Then, \n    /// it feeds this result into the function 'folder' along with the second element, and so on. It \n    /// returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBack<S, T>(Stck<T> stack, S state, Func<S, T, S> folder) =>\n        List.foldBack(stack, state, folder);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection whilst the predicate function \n    /// returns true for the item being processed, threading an aggregate state through the \n    /// computation. The fold function takes the state argument, and applies the function 'folder' \n    /// to it and the first element of the stack. Then, it feeds this result into the function 'folder' \n    /// along with the second element, and so on. It returns the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"preditem\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldWhile<S, T>(Stck<T> stack, S state, Func<S, T, S> folder, Func<T, bool> preditem) =>\n        List.foldWhile(stack, state, folder, preditem: preditem);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection, threading an accumulator \n    /// argument through the computation (and whilst the predicate function returns true when passed \n    /// the aggregate state). The fold function takes the state argument, and applies the function \n    /// 'folder' to it and the first element of the stack. Then, it feeds this result into the \n    /// function 'folder' along with the second element, and so on. It returns the final result. \n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"predstate\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldWhile<S, T>(Stck<T> stack, S state, Func<S, T, S> folder, Func<S, bool> predstate) =>\n        List.foldWhile(stack, state, folder, predstate: predstate);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first)\n    /// whilst the predicate function returns true for the item being processed, threading an \n    /// aggregate state through the computation. The fold function takes the state argument, and \n    /// applies the function 'folder' to it and the first element of the stack. Then, it feeds this \n    /// result into the function 'folder' along with the second element, and so on. It returns the \n    /// final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"preditem\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBackWhile<S, T>(Stck<T> stack, S state, Func<S, T, S> folder, Func<T, bool> preditem) =>\n        List.foldBackWhile(stack, state, folder, preditem: preditem);\n\n    /// <summary>\n    /// Applies a function 'folder' to each element of the collection (from last element to first), \n    /// threading an accumulator argument through the computation (and whilst the predicate function \n    /// returns true when passed the aggregate state). The fold function takes the state argument, \n    /// and applies the function 'folder' to it and the first element of the stack. Then, it feeds \n    /// this result into the function 'folder' along with the second element, and so on. It returns \n    /// the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <param name=\"predstate\">Predicate function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static S foldBackWhile<S, T>(Stck<T> stack, S state, Func<S, T, S> folder, Func<S, bool> predstate) =>\n        List.foldBackWhile(stack, state, folder, predstate: predstate);\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from last element to first), threading \n    /// an accumulator argument through the computation. This function first applies the function \n    /// to the first two elements of the stack. Then, it passes this result into the function along \n    /// with the third element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to fold</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static T reduce<T>(Stck<T> stack, Func<T, T, T> reducer) =>\n        List.reduce(stack, reducer);\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function first applies the function to the first two \n    /// elements of the stack. Then, it passes this result into the function along with the third \n    /// element and so on. Finally, it returns the final result.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"reducer\">Reduce function</param>\n    /// <returns>Aggregate value</returns>\n    [Pure]\n    public static T reduceBack<T>(Stck<T> stack, Func<T, T, T> reducer) =>\n        List.reduceBack(stack, reducer);\n\n    /// <summary>\n    /// Applies a function to each element of the collection, threading an accumulator argument \n    /// through the computation. This function takes the state argument, and applies the function \n    /// to it and the first element of the stack. Then, it passes this result into the function \n    /// along with the second element, and so on. Finally, it returns the list of intermediate \n    /// results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static Stck<S> scan<S, T>(Stck<T> stack, S state, Func<S, T, S> folder) =>\n        toStackRev(List.scan(stack, state, folder));\n\n    /// <summary>\n    /// Applies a function to each element of the collection (from last element to first), \n    /// threading an accumulator argument through the computation. This function takes the state \n    /// argument, and applies the function to it and the first element of the stack. Then, it \n    /// passes this result into the function along with the second element, and so on. Finally, \n    /// it returns the list of intermediate results and the final result.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folding function</param>\n    /// <returns>Aggregate state</returns>\n    [Pure]\n    public static Stck<S> scanBack<S, T>(Stck<T> stack, S state, Func<S, T, S> folder) =>\n        toStackRev(List.scanBack(stack, state, folder));\n\n    /// <summary>\n    /// Returns Some(x) for the first item in the stack that matches the predicate \n    /// provided, None otherwise.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>Some(x) for the first item in the stack that matches the predicate \n    /// provided, None otherwise.</returns>\n    [Pure]\n    public static Option<T> find<T>(Stck<T> stack, Func<T, bool> pred) =>\n        List.find(stack, pred);\n\n    /// <summary>\n    /// Joins a stack and and enumerable together either into a single enumerable\n    /// using the join function provided\n    /// </summary>\n    /// <param name=\"stack\">First stack to join</param>\n    /// <param name=\"other\">Second list to join</param>\n    /// <param name=\"zipper\">Join function</param>\n    /// <returns>Joined enumerable</returns>\n    [Pure]\n    public static Stck<V> zip<T, U, V>(Stck<T> stack, IEnumerable<U> other, Func<T, U, V> zipper) =>\n        toStackRev(List.zip(stack, other, zipper));\n\n    /// <summary>\n    /// Returns the number of items in the stack\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>The number of items in the enumerable</returns>\n    [Pure]\n    public static int length<T>(Stck<T> stack) =>\n        List.length(stack);\n\n    /// <summary>\n    /// Invokes an action for each item in the stack in order\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to iterate</param>\n    /// <param name=\"action\">Action to invoke with each item</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<T>(Stck<T> stack, Action<T> action) =>\n        List.iter(stack, action);\n\n    /// <summary>\n    /// Invokes an action for each item in the stack in order and supplies\n    /// a running index value.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to iterate</param>\n    /// <param name=\"action\">Action to invoke with each item</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<T>(Stck<T> stack, Action<int, T> action) =>\n        List.iter(stack, action);\n\n    /// <summary>\n    /// Returns true if all items in the stack match a predicate (Any in LINQ)\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack to test</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the stack match the predicate</returns>\n    [Pure]\n    public static bool forall<T>(Stck<T> stack, Func<T, bool> pred) =>\n        List.forall(stack, pred);\n\n    /// <summary>\n    /// Return an enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>An enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static Stck<T> distinct<T>(Stck<T> stack) =>\n        toStackRev(List.distinct(stack));\n\n    /// <summary>\n    /// Return an enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>An enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static Stck<T> distinct<EQ, T>(Stck<T> stack) where EQ : Eq<T> =>\n        toStackRev(List.distinct<EQ,T>(stack));\n\n    /// <summary>\n    /// Return an enumerable with all duplicate values removed\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <returns>An enumerable with all duplicate values removed</returns>\n    [Pure]\n    public static Stck<T> distinct<T, K>(Stck<T> stack, Func<T, K> keySelector, Option<Func<K, K, bool>> compare = default(Option<Func<K, K, bool>>)) =>\n        toStackRev(List.distinct(stack, keySelector, compare));\n\n    /// <summary>\n    /// Returns a new enumerable with the first 'count' items from the stack\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first 'count' items from the enumerable provided</returns>\n    [Pure]\n    public static Stck<T> take<T>(Stck<T> stack, int count) =>\n        toStackRev(List.take(stack, count));\n\n    /// <summary>\n    /// Iterate the stack, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first items that match the predicate</returns>\n    [Pure]\n    public static Stck<T> takeWhile<T>(Stck<T> stack, Func<T, bool> pred) =>\n        toStackRev(List.takeWhile(stack, pred));\n\n    /// <summary>\n    /// Iterate the stack, yielding items if they match the predicate provided, and stopping \n    /// as soon as one doesn't  An index value is also provided to the predicate function.\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"count\">Number of items to take</param>\n    /// <returns>A new enumerable with the first items that match the predicate</returns>\n    [Pure]\n    public static Stck<T> takeWhile<T>(Stck<T> stack, Func<T, int, bool> pred) =>\n        toStackRev(List.takeWhile(stack, pred));\n\n    /// <summary>\n    /// Returns true if any item in the stack matches the predicate provided\n    /// </summary>\n    /// <typeparam name=\"T\">Stack item type</typeparam>\n    /// <param name=\"stack\">Stack</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if any item in the stack matches the predicate provided</returns>\n    [Pure]\n    public static bool exists<T>(Stck<T> stack, Func<T, bool> pred) =>\n        List.exists(stack, pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Stack/Stck.Internal.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Immutable stack\n    /// </summary>\n    /// <typeparam name=\"A\">Stack element type</typeparam>\n    [Serializable]\n    internal class StckInternal<A> : IEnumerable<A>\n    {\n        public static readonly StckInternal<A> Empty = new ();\n\n        readonly A? value;\n        readonly StckInternal<A>? tail;\n        int hashCode;\n\n        /// <summary>\n        /// Default ctor\n        /// </summary>\n        internal StckInternal()\n        {\n        }\n\n        /// <summary>\n        /// Ctor for Push\n        /// </summary>\n        /// <param name=\"value\"></param>\n        /// <param name=\"tail\"></param>\n        internal StckInternal(A value, StckInternal<A> tail)\n        {\n            Count = tail.Count + 1;\n            this.tail = tail;\n            this.value = value;\n        }\n\n        /// <summary>\n        /// Ctor that takes an initial state as an IEnumerable T\n        /// </summary>\n        public StckInternal(A[] initial)\n        {\n            tail = new StckInternal<A>();\n            foreach (var item in initial)\n            {\n                value = item;\n                tail = tail.Push(item);\n                Count++;\n            }\n            tail = tail.Pop();\n        }\n\n        /// <summary>\n        /// Ctor that takes an initial state as an IEnumerable T\n        /// </summary>\n        public StckInternal(ReadOnlySpan<A> initial)\n        {\n            tail = new StckInternal<A>();\n            foreach (var item in initial)\n            {\n                value = item;\n                tail = tail.Push(item);\n                Count++;\n            }\n            tail = tail.Pop();\n        }\n\n        /// <summary>\n        /// Ctor that takes an initial state as a Lst T\n        /// </summary>\n        internal StckInternal(Lst<A> initial)\n        {\n            tail = new StckInternal<A>();\n            foreach (var item in initial)\n            {\n                value = item;\n                tail = tail.Push(item);\n                Count++;\n            }\n            tail = tail.Pop();\n        }\n\n        /// <summary>\n        /// Number of items in the stack\n        /// </summary>\n        [Pure]\n        public int Count { get; }\n\n        /// <summary>\n        /// Reverses the order of the items in the stack\n        /// </summary>\n        /// <returns></returns>\n        [Pure]\n        public StckInternal<A> Reverse()\n        {\n            var s = new StckInternal<A>();\n            foreach (var item in this)\n            {\n                s = s.Push(item);\n            }\n            return s;\n        }\n\n        /// <summary>\n        /// True if the stack is empty\n        /// </summary>\n        [Pure]\n        public bool IsEmpty => \n            Count == 0;\n\n        /// <summary>\n        /// Clear the stack (returns Empty)\n        /// </summary>\n        /// <returns>Stck.Empty of T</returns>\n        [Pure]\n        public StckInternal<A> Clear() =>\n            Empty;\n\n        /// <summary>\n        /// Get enumerator\n        /// </summary>\n        /// <returns>IEnumerator of T</returns>\n        [Pure]\n        public IEnumerator<A> GetEnumerator() =>\n            // ReSharper disable once NotDisposedResourceIsReturned\n            AsIterable().GetEnumerator();\n\n        /// <summary>\n        /// Returns the stack as an IEnumerable.  The first item in the enumerable\n        /// will be the item at the top of the stack.\n        /// </summary>\n        /// <returns>IEnumerable of T</returns>\n        [Pure]\n        public Iterable<A> AsIterable()\n        {\n            IEnumerable<A> Yield()\n            {\n                var self = this;\n                while (self!.Count != 0)\n                {\n                    yield return self.value!;\n                    self = self.tail;\n                }\n            }\n            return Iterable.createRange(Yield());\n        }\n\n        /// <summary>\n        /// Return the item on the top of the stack without affecting the stack itself\n        /// NOTE: Will throw an ExpectedException if the stack is empty\n        /// </summary>\n        /// <exception cref=\"ExpectedException\">Stack is empty</exception>\n        /// <returns>Top item value</returns>\n        [Pure]\n        public A Peek()\n        {\n            if (Count > 0)\n            {\n                return value!;\n            }\n            else\n            {\n                throw Exceptions.SequenceEmpty;\n            }\n        }\n\n        /// <summary>\n        /// Peek and match\n        /// </summary>\n        /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n        /// <param name=\"None\">Handler if the stack is empty</param>\n        /// <returns>Untouched stack (this)</returns>\n        [Pure]\n        public StckInternal<A> Peek(Action<A> Some, Action None)\n        {\n            if (Count > 0)\n            {\n                Some(value!);\n            }\n            else\n            {\n                None();\n            }\n            return this;\n        }\n\n        /// <summary>\n        /// Peek and match\n        /// </summary>\n        /// <typeparam name=\"R\">Return type</typeparam>\n        /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n        /// <param name=\"None\">Handler if the stack is empty</param>\n        /// <returns>Return value from Some or None</returns>\n        [Pure]\n        public R Peek<R>(Func<A, R> Some, Func<R> None) =>\n            Count > 0\n                ? Some(value!)\n                : None();\n\n        /// <summary>\n        /// Safely return the item on the top of the stack without affecting the stack itself\n        /// </summary>\n        /// <returns>Returns the top item value, or None</returns>\n        [Pure]\n        public Option<A> TryPeek() =>\n            Count > 0\n                ? Prelude.Some(value!)\n                : Prelude.None;\n\n        /// <summary>\n        /// Pop an item off the top of the stack\n        /// NOTE: Will throw an ExpectedException if the stack is empty\n        /// </summary>\n        /// <exception cref=\"ExpectedException\">Stack is empty</exception>\n        /// <returns>Stack with the top item popped</returns>\n        [Pure]\n        public StckInternal<A> Pop()\n        {\n            if (Count > 0)\n            {\n                return tail!;\n            }\n            else\n            {\n                throw Exceptions.SequenceEmpty;\n            }\n        }\n\n        /// <summary>\n        /// Safe pop\n        /// </summary>\n        /// <returns>Tuple of popped stack and optional top-of-stack value</returns>\n        [Pure]\n        public (StckInternal<A>, Option<A>) TryPop() =>\n            Count > 0\n                ? (tail!, Option.Some(value!))\n                : (this, Option<A>.None);\n\n        /// <summary>\n        /// Pop and match\n        /// </summary>\n        /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n        /// <param name=\"None\">Handler if the stack is empty</param>\n        /// <returns>Popped stack</returns>\n        [Pure]\n        public StckInternal<A> Pop(Action<A> Some, Action None)\n        {\n            if (Count > 0)\n            {\n                Some(value!);\n                return tail!;\n            }\n            else\n            {\n                None();\n                return this;\n            }\n        }\n\n        /// <summary>\n        /// Pop and match\n        /// </summary>\n        /// <typeparam name=\"R\">Return type</typeparam>\n        /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n        /// <param name=\"None\">Handler if the stack is empty</param>\n        /// <returns>Return value from Some or None</returns>\n        [Pure]\n        public R Pop<R>(Func<StckInternal<A>, A, R> Some, Func<R> None) =>\n            Count > 0\n                ? Some(tail!, value!)\n                : None();\n\n        /// <summary>\n        /// Push an item onto the stack\n        /// </summary>\n        /// <param name=\"value\">Item to push</param>\n        /// <returns>New stack with the pushed item on top</returns>\n        [Pure]\n        public StckInternal<A> Push(A value) =>\n            new (value, this);\n\n        /// <summary>\n        /// Get enumerator\n        /// </summary>\n        /// <returns>IEnumerator of T</returns>\n        [Pure]\n        IEnumerator IEnumerable.GetEnumerator() =>\n            AsIterable().GetEnumerator();\n\n        /// <summary>\n        /// Append another stack to the top of this stack\n        /// The rhs will be reversed and pushed onto 'this' stack.  That will\n        /// maintain the order of the items in the resulting stack.  So the top\n        /// of 'rhs' will be the top of the newly created stack.  'this' stack\n        /// will be under the 'rhs' stack.\n        /// </summary>\n        [Pure]\n        public static StckInternal<A> operator +(StckInternal<A> lhs, StckInternal<A> rhs) =>\n            lhs.Combine(rhs);\n\n        /// <summary>\n        /// Append another stack to the top of this stack\n        /// The rhs will be reversed and pushed onto 'this' stack.  That will\n        /// maintain the order of the items in the resulting stack.  So the top\n        /// of 'rhs' will be the top of the newly created stack.  'this' stack\n        /// will be under the 'rhs' stack.\n        /// </summary>\n        /// <param name=\"rhs\">Stack to append</param>\n        /// <returns>Appended stacks</returns>\n        [Pure]\n        public StckInternal<A> Combine(StckInternal<A> rhs)\n        {\n            var self = this;\n            foreach (var item in rhs.Reverse())\n            {\n                self = self.Push(item);\n            }\n            return self;\n        }\n\n        public override int GetHashCode() =>\n            hashCode == 0\n                ? hashCode = FNV32.Hash<HashableDefault<A>, A>(this)\n                : hashCode;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/Stack/Stck.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable stack\n/// </summary>\n/// <typeparam name=\"A\">Stack element type</typeparam>\n[Serializable]\n[CollectionBuilder(typeof(Stack), nameof(Stack.createRange))]\npublic readonly struct Stck<A> : \n    IEnumerable<A>, \n    IEquatable<Stck<A>>,\n    Monoid<Stck<A>>\n{\n    public static Stck<A> Empty { get; } = new(StckInternal<A>.Empty);\n\n    readonly StckInternal<A> value;\n    StckInternal<A> Value => value ?? StckInternal<A>.Empty;\n\n    /// <summary>\n    /// Default ctor\n    /// </summary>\n    internal Stck(StckInternal<A> value) =>\n        this.value = value;\n\n    /// <summary>\n    /// Ctor that takes an initial state as an IEnumerable T\n    /// </summary>\n    public Stck(IEnumerable<A> initial)\n    {\n        var xs = initial.ToArray();\n        value = xs.Length == 0 ? StckInternal<A>.Empty : new StckInternal<A>(xs);\n    }\n\n    /// <summary>\n    /// Ctor that takes an initial state as an IEnumerable T\n    /// </summary>\n    public Stck(ReadOnlySpan<A> initial) =>\n        value = initial.IsEmpty\n                    ? StckInternal<A>.Empty\n                    : new StckInternal<A>(initial);\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Empty collection     = null\n    ///     Singleton collection = A\n    ///     More                 = (A, Seq〈A〉)   -- head and tail\n    ///\n    ///     var res = stack.Case switch\n    ///     {\n    ///       \n    ///        (var x, var xs) => ...,\n    ///        A value         => ...,\n    ///        _               => ...\n    ///     }\n    /// \n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsEmpty\n            ? null\n            : toSeq(Value).Case;\n\n    /// <summary>\n    /// Reverses the order of the items in the stack\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public Stck<A> Reverse() =>\n        new (Value.Reverse());\n\n    /// <summary>\n    /// Is the stack empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the stack\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n        \n    /// <summary>\n    /// Clear the stack (returns Empty)\n    /// </summary>\n    /// <returns>Stck.Empty of T</returns>\n    [Pure]\n    public Stck<A> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns>IEnumerator of T</returns>\n    [Pure]\n    public IEnumerator<A> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsIterable().GetEnumerator();\n\n    /// <summary>\n    /// Returns the stack as a Seq.  The first item in the sequence\n    /// will be the item at the top of the stack.\n    /// </summary>\n    /// <returns>IEnumerable of T</returns>\n    [Pure]\n    public Seq<A> ToSeq() =>\n        toSeq(Value);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(this, Count);\n\n    /// <summary>\n    /// Format the collection as `a, b, c, ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(this, separator);\n\n    /// <summary>\n    /// Format the collection as `[a, b, c, ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(this, separator);\n\n    /// <summary>\n    /// Returns the stack as an IEnumerable.  The first item in the enumerable\n    /// will be the item at the top of the stack.\n    /// </summary>\n    /// <returns>IEnumerable of T</returns>\n    [Pure]\n    public Iterable<A> AsIterable() =>\n        Iterable.createRange(Value);\n\n    /// <summary>\n    /// Impure iteration of the bound value in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Stck<A> Do(Action<A> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Return the item on the top of the stack without affecting the stack itself\n    /// NOTE: Will throw an ExpectedException if the stack is empty\n    /// </summary>\n    /// <exception cref=\"ExpectedException\">Stack is empty</exception>\n    /// <returns>Top item value</returns>\n    [Pure]\n    public A Peek() =>\n        Value.Peek();\n\n    /// <summary>\n    /// Peek and match\n    /// </summary>\n    /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n    /// <param name=\"None\">Handler if the stack is empty</param>\n    /// <returns>Untouched stack (this)</returns>\n    [Pure]\n    public Stck<A> Peek(Action<A> Some, Action None) =>\n        new (Value.Peek(Some, None));\n\n    /// <summary>\n    /// Peek and match\n    /// </summary>\n    /// <typeparam name=\"R\">Return type</typeparam>\n    /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n    /// <param name=\"None\">Handler if the stack is empty</param>\n    /// <returns>Return value from Some or None</returns>\n    [Pure]\n    public R Peek<R>(Func<A, R> Some, Func<R> None) =>\n        Value.Peek(Some, None);\n\n    /// <summary>\n    /// Safely return the item on the top of the stack without affecting the stack itself\n    /// </summary>\n    /// <returns>Returns the top item value, or None</returns>\n    [Pure]\n    public Option<A> TryPeek() =>\n        Value.TryPeek();\n\n    /// <summary>\n    /// Pop an item off the top of the stack\n    /// NOTE: Will throw an ExpectedException if the stack is empty\n    /// </summary>\n    /// <exception cref=\"ExpectedException\">Stack is empty</exception>\n    /// <returns>Stack with the top item popped</returns>\n    [Pure]\n    public Stck<A> Pop() =>\n        new (Value.Pop());\n\n    /// <summary>\n    /// Safe pop\n    /// </summary>\n    /// <returns>Tuple of popped stack and optional top-of-stack value</returns>\n    [Pure]\n    public (Stck<A> Stack, Option<A> Value) TryPop() =>\n        Value.TryPop().MapFirst(x => new Stck<A>(x));\n\n    /// <summary>\n    /// Pop and match\n    /// </summary>\n    /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n    /// <param name=\"None\">Handler if the stack is empty</param>\n    /// <returns>Popped stack</returns>\n    [Pure]\n    public Stck<A> Pop(Action<A> Some, Action None) =>\n        new (Value.Pop(Some, None));\n\n    /// <summary>\n    /// Pop and match\n    /// </summary>\n    /// <typeparam name=\"R\">Return type</typeparam>\n    /// <param name=\"Some\">Handler if there is a value on the top of the stack</param>\n    /// <param name=\"None\">Handler if the stack is empty</param>\n    /// <returns>Return value from Some or None</returns>\n    [Pure]\n    public R Pop<R>(Func<Stck<A>, A, R> Some, Func<R> None) =>\n        Value.Pop((s, t) => Some(new Stck<A>(s), t), None);\n\n    /// <summary>\n    /// Push an item onto the stack\n    /// </summary>\n    /// <param name=\"value\">Item to push</param>\n    /// <returns>New stack with the pushed item on top</returns>\n    [Pure]\n    public Stck<A> Push(A value) =>\n        new (Value.Push(value));\n\n    /// <summary>\n    /// Get enumerator\n    /// </summary>\n    /// <returns>IEnumerator of T</returns>\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsIterable().GetEnumerator();\n        \n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Stck<A>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Append another stack to the top of this stack\n    /// The rhs will be reversed and pushed onto 'this' stack.  That will\n    /// maintain the order of the items in the resulting stack.  So the top\n    /// of 'rhs' will be the top of the newly created stack.  'this' stack\n    /// will be under the 'rhs' stack.\n    /// </summary>\n    [Pure]\n    public static Stck<A> operator +(Stck<A> lhs, Stck<A> rhs) =>\n        lhs.Combine(rhs);\n\n    /// <summary>\n    /// Append another stack to the top of this stack\n    /// The rhs will be reversed and pushed onto 'this' stack.  That will\n    /// maintain the order of the items in the resulting stack.  So the top\n    /// of 'rhs' will be the top of the newly created stack.  'this' stack\n    /// will be under the 'rhs' stack.\n    /// </summary>\n    /// <param name=\"rhs\">Stack to append</param>\n    /// <returns>Appended stacks</returns>\n    [Pure]\n    public Stck<A> Combine(Stck<A> rhs) =>\n        new (Value.Combine(rhs.Value));\n\n    /// <summary>\n    /// Subtract one stack from another: lhs except rhs\n    /// </summary>\n    [Pure]\n    public static Stck<A> operator -(Stck<A> lhs, Stck<A> rhs) =>\n        lhs.Subtract(rhs);\n\n    /// <summary>\n    /// Append another stack to the top of this stack\n    /// The rhs will be reversed and pushed onto 'this' stack.  That will\n    /// maintain the order of the items in the resulting stack.  So the top\n    /// of 'rhs' will be the top of the newly created stack.  'this' stack\n    /// will be under the 'rhs' stack.\n    /// </summary>\n    /// <param name=\"rhs\">Stack to append</param>\n    /// <returns>Appended stacks</returns>\n    [Pure]\n    public Stck<A> Subtract(Stck<A> rhs) =>\n        new (Enumerable.Except(this, rhs));\n\n    [Pure]\n    public static bool operator ==(Stck<A> lhs, Stck<A> rhs) =>\n        lhs.Equals(rhs);\n\n    [Pure]\n    public static bool operator !=(Stck<A> lhs, Stck<A> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is Stck<A> @as && Equals(@as);\n\n    [Pure]\n    public bool Equals(Stck<A> other) =>\n        GetHashCode() == other.GetHashCode() &&\n        EqEnumerable<A>.Equals(Value, other.Value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/TrackingHashMap/TrackingHashMap.Eq.cs",
    "content": "﻿using LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Unsorted immutable hash-map that tracks changes.\n/// </summary>\n/// <remarks>\n/// Changes are accessible via the `Changes` property.  It is a `HashMap` of `Change` values from either the initial\n/// empty state of the collection, or since the last call to `Snapshot()`.\n///\n/// The fact that the changes are represented as a single-value `HashMap` shows that the tracked changes are not an\n/// ever increasing log of changes, but instead a morphism between one previous state of the `TrackingHashMap` and\n/// another.  Therefore there's at most one morphism for each key, and potentially none.\n///\n/// The morphisms are:\n///\n///     * `EntryAdded`\n///     * `EntryMapped`\n///     * `EntryRemoved`\n///\n/// A new 'zero-changes starting-state' can be created by calling `Snapshot()`.  `Snapshot` creates the first\n/// snapshot (effectively clears the `Changes` to zero), and `Changes` will collect the difference from this point\n/// to any morphed future-state as collection-transforming operations are performed\n/// </remarks>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value</typeparam>\n[CollectionBuilder(typeof(TrackingHashMap), nameof(TrackingHashMap.createRange))]\npublic readonly struct TrackingHashMap<EqK, K, V> :\n    IReadOnlyDictionary<K, V>,\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<TrackingHashMap<EqK, K, V>>,\n    Monoid<TrackingHashMap<EqK, K, V>>\n    where EqK : Eq<K>\n{\n    public static TrackingHashMap<EqK, K, V> Empty { get; } = new(TrieMap<EqK, K, V>.Empty);\n\n    readonly TrieMap<EqK, K, V> value;\n    readonly TrieMap<EqK, K, Change<V>> changes;\n\n    internal TrieMap<EqK, K, V> Value => \n        value ?? TrieMap<EqK, K, V>.Empty;\n\n    internal TrieMap<EqK, K, Change<V>> ChangesInternal => \n        changes ?? TrieMap<EqK, K, Change<V>>.Empty;\n\n    public HashMap<EqK, K, Change<V>> Changes => \n        new (ChangesInternal);\n\n    internal TrackingHashMap(TrieMap<EqK, K, V> value, TrieMap<EqK, K, Change<V>> changes)\n    {\n        this.value = value;\n        this.changes = changes;\n    }\n\n    public TrackingHashMap(IEnumerable<(K Key, V Value)> items) \n        : this(items, true)\n    { }\n\n    public TrackingHashMap(IEnumerable<(K Key, V Value)> items, bool tryAdd)\n    {\n        value = new TrieMap<EqK, K, V>(items, tryAdd);\n        changes = TrieMap<EqK, K, Change<V>>.Empty;\n    }\n\n    public TrackingHashMap(ReadOnlySpan<(K Key, V Value)> items) \n        : this(items, true)\n    { }\n\n    public TrackingHashMap(ReadOnlySpan<(K Key, V Value)> items, bool tryAdd)\n    {\n        value = new TrieMap<EqK, K, V>(items, tryAdd);\n        changes = TrieMap<EqK, K, Change<V>>.Empty;\n    }\n\n    /// <summary>\n    /// Creates a 'zero change' snapshot.  *The data does not change*!   \n    /// </summary>\n    /// <remarks>Useful for creating new starting points for capturing the difference between two snapshots of the\n    /// `TrackingHashMap`.  `Snapshot` creates the first snapshot (effectively clears the `Changes` to zero), and\n    /// `Changes` will collect the difference from this point to any morphed future point as collection-\n    /// transforming operations are performed</remarks>\n    /// <returns>Map with changes zeroed</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Snapshot() =>\n        new (Value, TrieMap<EqK, K, Change<V>>.Empty);\n\n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    public static Lens<TrackingHashMap<EqK, K, V>, V> item(K key) => Lens<TrackingHashMap<EqK, K, V>, V>.New(\n        Get: la => la[key],\n        Set: a => la => la.AddOrUpdate(key, a)\n    );\n\n    /// <summary>\n    /// Item or none at index lens\n    /// </summary>\n    [Pure]\n    public static Lens<TrackingHashMap<EqK, K, V>, Option<V>> itemOrNone(K key) => Lens<TrackingHashMap<EqK, K, V>, Option<V>>.New(\n        Get: la => la.Find(key),\n        Set: a => la => a.Match(Some: x => la.AddOrUpdate(key, x), None: () => la.Remove(key))\n    );\n\n    TrackingHashMap<EqK, K, V> Wrap((TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) pair) =>\n        new (pair.Map, ChangesInternal.Merge(pair.Changes));\n\n    TrackingHashMap<EqK, K, V> Wrap(K key, (TrieMap<EqK, K, V> Map, Change<V> Change) pair) =>\n        new(pair.Map, ChangesInternal.AddOrUpdate(key, Some: ex => ex.Combine(pair.Change), pair.Change));\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public V this[K key] =>\n        Value[key];\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Filter(Func<V, bool> pred) =>\n        Wrap(Value.FilterWithLog(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Filter(Func<K, V, bool> pred) =>\n        Wrap(Value.FilterWithLog(pred));\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Add(K key, V value) =>\n        Wrap(key, Value.AddWithLog(key, value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TryAdd(K key, V value) =>\n        Wrap(key, Value.TryAddWithLog(key, value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddOrUpdate(K key, V value) =>\n        Wrap(key, Value.AddOrUpdateWithLog(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddOrUpdate(K key, Func<V, V> Some, Func<V> None) =>\n        Wrap(key, Value.AddOrUpdateWithLog(key, Some, None));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddOrUpdate(K key, Func<V, V> Some, V None) =>\n        Wrap(key, Value.AddOrUpdateWithLog(key, Some, None));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.AddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.AddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TryAddRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.TryAddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TryAddRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.TryAddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TryAddRange(IEnumerable<KeyValuePair<K, V>> range) =>\n        Wrap(Value.TryAddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddOrUpdateRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.AddOrUpdateRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddOrUpdateRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.AddOrUpdateRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range) =>\n        Wrap(Value.AddOrUpdateRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Remove(K key) =>\n        Wrap(key, Value.RemoveWithLog(key));\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Option<V> Find(K key) =>\n        Value.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Seq<V> FindSeq(K key) =>\n        Value.FindAll(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) =>\n        Value.Find(key, Some, None);\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (TrackingHashMap<EqK, K, V> Map, V Value) FindOrAdd(K key, Func<V> None)\n    {\n        var (x, y, cs) = Value.FindOrAddWithLog(key, None);\n        return (Wrap(key, (x, cs)), y);\n    }\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (TrackingHashMap<EqK, K, V>, V Value) FindOrAdd(K key, V value)\n    {\n        var (x, y, cs) = Value.FindOrAddWithLog(key, value);\n        return (Wrap(key, (x, cs)), y);\n    }\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (TrackingHashMap<EqK, K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Func<Option<V>> None)\n    {\n        var (x, y, cs) = Value.FindOrMaybeAddWithLog(key, None);\n        return (Wrap(key, (x, cs)), y);\n    }\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (TrackingHashMap<EqK, K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Option<V> None)\n    {\n        var (x, y, cs) = Value.FindOrMaybeAddWithLog(key, None);\n        return (Wrap(key, (x, cs)), y);\n    }\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> SetItem(K key, V value) =>\n        Wrap(key, Value.SetItemWithLog(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> SetItem(K key, Func<V, V> Some) =>\n        Wrap(key, Value.SetItemWithLog(key, Some));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TrySetItem(K key, V value) =>\n        Wrap(key, Value.TrySetItemWithLog(key, value));\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TrySetItem(K key, Func<V, V> Some) =>\n        Wrap(key, Value.TrySetItemWithLog(key, Some));\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool ContainsKey(K key) =>\n        Value.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains(K key, V value) =>\n        Value.Contains(key, value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    public bool Contains(V value) =>\n        Value.Contains(value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    public bool Contains<EqV>(V value) where EqV : Eq<V> =>\n        Value.Contains<EqV>(value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains<EqV>(K key, V value) where EqV : Eq<V> =>\n        Value.Contains<EqV>(key, value);\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Clear() =>\n        Wrap(Value.ClearWithLog());\n\n    /// <summary>\n    /// Atomically adds a range of items to the map\n    /// </summary>\n    /// <param name=\"pairs\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> AddRange(IEnumerable<KeyValuePair<K, V>> pairs) =>\n        Wrap(Value.AddRangeWithLog(pairs));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> SetItems(IEnumerable<KeyValuePair<K, V>> items) =>\n        Wrap(Value.SetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> SetItems(IEnumerable<Tuple<K, V>> items) =>\n        Wrap(Value.SetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> SetItems(IEnumerable<(K Key, V Value)> items) =>\n        Wrap(Value.SetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TrySetItems(IEnumerable<KeyValuePair<K, V>> items) =>\n        Wrap(Value.TrySetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TrySetItems(IEnumerable<Tuple<K, V>> items) =>\n        Wrap(Value.TrySetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TrySetItems(IEnumerable<(K Key, V Value)> items) =>\n        Wrap(Value.TrySetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> TrySetItems(IEnumerable<K> keys, Func<V, V> Some) =>\n        Wrap(Value.TrySetItemsWithLog(keys, Some));\n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New map with the items removed</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> RemoveRange(IEnumerable<K> keys) =>\n        Wrap(Value.RemoveRangeWithLog(keys));\n\n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    public bool Contains(KeyValuePair<K, V> pair) =>\n        Value.Contains(pair.Key, pair.Value);\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys =>\n        Value.Keys;\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values =>\n        Value.Values;\n\n    /// <summary>\n    /// Convert the map to an IDictionary\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public IReadOnlyDictionary<K, V> ToDictionary() =>\n        this;\n\n    /// <summary>\n    /// Map the map the a dictionary\n    /// </summary>\n    [Pure]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(\n        Func<(K Key, V Value), KR> keySelector, \n        Func<(K Key, V Value), VR> valueSelector) \n        where KR : notnull =>\n        AsEnumerable().ToDictionary(x => keySelector(x), x => valueSelector(x));\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Value.GetEnumerator();\n\n    [Pure]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        toSeq(AsEnumerable());\n\n    /// <summary>\n    /// Allocation free conversion to a HashMap\n    /// </summary>\n    [Pure]\n    public HashMap<EqK, K, V> ToHashMap() =>\n        new (value);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    public Iterable<(K Key, V Value)> AsEnumerable() =>\n        Value.AsIterable();\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator ==(TrackingHashMap<EqK, K, V> lhs, TrackingHashMap<EqK, K, V> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator !=(TrackingHashMap<EqK, K, V> lhs, TrackingHashMap<EqK, K, V> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> operator +(TrackingHashMap<EqK, K, V> lhs, TrackingHashMap<EqK, K, V> rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Combine(TrackingHashMap<EqK, K, V> rhs) =>\n        Wrap(Value.AppendWithLog(rhs.Value));\n\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> operator -(TrackingHashMap<EqK, K, V> lhs, TrackingHashMap<EqK, K, V> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Subtract(TrackingHashMap<EqK, K, V> rhs) =>\n        Wrap(Value.SubtractWithLog(rhs.Value));\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<K> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<K> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<K> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(TrackingHashMap<EqK, K, V> other) =>\n        Value.IsSubsetOf(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<K> rhs) =>\n        Value.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Intersect(IEnumerable<K> rhs) =>\n        Wrap(Value.IntersectWithLog(rhs));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Intersect(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.IntersectWithLog(rhs));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<EqK, K, V> Intersect(IEnumerable<(K Key, V Value)> rhs, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.IntersectWithLog(new TrieMap<EqK, K, V>(rhs), Merge));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<EqK, K, V> Intersect(HashMap<EqK, K, V> rhs, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.IntersectWithLog(rhs.Value, Merge));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<EqK, K, V> Intersect(TrackingHashMap<EqK, K, V> rhs, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.IntersectWithLog(rhs.Value, Merge));\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<K> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Except(IEnumerable<K> rhs) =>\n        Wrap(Value.ExceptWithLog(rhs));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Except(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.ExceptWithLog(rhs));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> SymmetricExcept(TrackingHashMap<EqK, K, V> rhs) =>\n        Wrap(Value.SymmetricExceptWithLog(rhs.Value));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> SymmetricExcept(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.SymmetricExceptWithLog(rhs));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public TrackingHashMap<EqK, K, V> Union(IEnumerable<(K, V)> rhs) =>\n        this.TryAddRange(rhs);\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<EqK, K, V> Union(IEnumerable<(K Key, V Value)> other, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.UnionWithLog(other, static (_, v) => v, static (_, v) => v, Merge));\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the right-hand side, but not the left-hand-side.\n    /// This allows the `V2` value-type to be mapped to the target `V` value-type. \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<EqK, K, V> Union<W>(IEnumerable<(K Key, W Value)> other, WhenMissing<K, W, V> MapRight, WhenMatched<K, V, W, V> Merge) =>\n        Wrap(Value.UnionWithLog(other, static (_, v) => v, MapRight, Merge));\n        \n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is TrackingHashMap<EqK, K, V> hm && Equals(hm);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals(TrackingHashMap<EqK, K, V> other) =>\n        Value.Equals<EqDefault<V>>(other.Value);\n\n    /// <summary>\n    /// Equality of keys and values with `EqV` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals<EqV>(TrackingHashMap<EqK, K, V> other) where EqV : Eq<V> =>\n        Value.Equals<EqV>(other.Value);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    public bool EqualsKeys(TrackingHashMap<EqK, K, V> other) =>\n        Value.Equals<EqTrue<V>>(other.Value);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public TrackingHashMap<EqK, K, V> Do(Action<V> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public TrackingHashMap<EqK, K, V> Where(Func<V, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public TrackingHashMap<EqK, K, V> Where(Func<K, V, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<K, V, bool> pred)\n    {\n        foreach (var item in AsEnumerable())\n        {\n            if (!pred(item.Key, item.Value)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        AsEnumerable().Map(kv => (kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if *all* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<KeyValuePair<K, V>, bool> pred) =>\n        AsEnumerable().Map(kv => new KeyValuePair<K, V>(kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<V, bool> pred) =>\n        Values.ForAll(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    public bool Exists(Func<K, V, bool> pred)\n    {\n        foreach (var item in AsEnumerable())\n        {\n            if (pred(item.Key, item.Value)) return true;\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<(K Key, V Value), bool> pred) =>\n        AsEnumerable().Map(kv => (kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<KeyValuePair<K, V>, bool> pred) =>\n        AsEnumerable().Map(kv => new KeyValuePair<K, V>(kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<V, bool> pred) =>\n        Values.Exists(pred);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<K, V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Key, item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<Tuple<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new Tuple<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<(K Key, V Value)> action)\n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<KeyValuePair<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new KeyValuePair<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        AsEnumerable().Fold(state, (s, x) => folder(s, x.Key, x.Value));\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() =>\n        AsEnumerable().Map(p => new KeyValuePair<K, V>(p.Key, p.Value)).GetEnumerator();\n    \n    [Pure]\n    IEnumerable<K> IReadOnlyDictionary<K, V>.Keys => Keys;\n    \n    [Pure]\n    IEnumerable<V> IReadOnlyDictionary<K, V>.Values => Values;\n\n    [Pure]\n    public bool TryGetValue(K key, out V value)\n    {\n        var v = Find(key);\n        if (v.IsSome)\n        {\n            value = (V)v;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n    \n    /// <summary>\n    /// Get a IReadOnlyDictionary for this map.  No mapping is required, so this is very fast.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IReadOnlyDictionary<K, V> ToReadOnlyDictionary() =>\n        this;\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, V, S> folder) =>\n        Values.Fold(state, folder);\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(ValueTuple<(K, V)> items) =>\n        [items.Item1];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V)) items) =>\n        [items.Item1, items.Item2];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<EqK, K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15, items.Item16];\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/TrackingHashMap/TrackingHashMap.Extensions.Eq.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TrackingHashMapExtensions\n{\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> ToTrackingHashMap<EqK, K, V>(this IEnumerable<(K, V)> items) \n        where EqK : Eq<K> =>\n        TrackingHashMap.createRange<EqK, K, V>(items);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> ToTrackingHashMap<EqK, K, V>(this IEnumerable<Tuple<K, V>> items)\n        where EqK : Eq<K> =>\n        TrackingHashMap.createRange<EqK, K, V>(items);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> ToTrackingHashMap<EqK, K, V>(this IEnumerable<KeyValuePair<K, V>> items)\n        where EqK : Eq<K> =>\n        TrackingHashMap.createRange<EqK, K, V>(items);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/TrackingHashMap/TrackingHashMap.Extensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class TrackingHashMapExtensions\n{\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> ToTrackingHashMap<K, V>(this IEnumerable<(K, V)> items) =>\n        TrackingHashMap.createRange(items);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> ToTrackingHashMap<K, V>(this IEnumerable<Tuple<K, V>> items) =>\n        TrackingHashMap.createRange(items);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> ToTrackingHashMap<K, V>(this IEnumerable<KeyValuePair<K, V>> items) =>\n        TrackingHashMap.createRange(items);\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K1, TrackingHashMap<K2, V>> ToTrackingHashMap<K1, K2, V>(this IEnumerable<(K1, K2, V)> items) =>\n        items.AsIterable().Fold(TrackingHashMap<K1, TrackingHashMap<K2, V>>(), (s, x) => s.AddOrUpdate(x.Item1, x.Item2, x.Item3));\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K1, TrackingHashMap<K2, V>> ToTrackingHashMap<K1, K2, V>(this IEnumerable<Tuple<K1, K2, V>> items) =>\n        items.AsIterable().Fold(TrackingHashMap<K1, TrackingHashMap<K2, V>>(), (s, x) => s.AddOrUpdate(x.Item1, x.Item2, x.Item3));\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K1, TrackingHashMap<K2, TrackingHashMap<K3, V>>> ToTrackingHashMap<K1, K2, K3, V>(this IEnumerable<(K1, K2, K3, V)> items) =>\n        items.AsIterable().Fold(TrackingHashMap<K1, TrackingHashMap<K2, TrackingHashMap<K3, V>>>(), (s, x) => s.AddOrUpdate(x.Item1, x.Item2, x.Item3, x.Item4));\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K1, TrackingHashMap<K2, TrackingHashMap<K3, V>>> ToTrackingHashMap<K1, K2, K3, V>(this IEnumerable<Tuple<K1, K2, K3, V>> items) =>\n        items.AsIterable().Fold(TrackingHashMap<K1, TrackingHashMap<K2, TrackingHashMap<K3, V>>>(), (s, x) => s.AddOrUpdate(x.Item1, x.Item2, x.Item3, x.Item4));\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K1, TrackingHashMap<K2, TrackingHashMap<K3, TrackingHashMap<K4, V>>>> ToTrackingHashMap<K1, K2, K3, K4, V>(this IEnumerable<(K1, K2, K3, K4, V)> items) =>\n        items.AsIterable().Fold(TrackingHashMap<K1, TrackingHashMap<K2, TrackingHashMap<K3, TrackingHashMap<K4, V>>>>(), (s, x) => s.AddOrUpdate(x.Item1, x.Item2, x.Item3, x.Item4, x.Item5));\n\n    /// <summary>\n    /// Create an immutable tracking hash-map\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K1, TrackingHashMap<K2, TrackingHashMap<K3, TrackingHashMap<K4, V>>>> ToTrackingHashMap<K1, K2, K3, K4, V>(this IEnumerable<Tuple<K1, K2, K3, K4, V>> items) =>\n        items.AsIterable().Fold(TrackingHashMap<K1, TrackingHashMap<K2, TrackingHashMap<K3, TrackingHashMap<K4, V>>>>(), (s, x) => s.AddOrUpdate(x.Item1, x.Item2, x.Item3, x.Item4, x.Item5));\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public static int Count<K, V>(this TrackingHashMap<K, V> self) =>\n        self.Count;\n\n    [Pure]\n    public static int Sum<K>(this TrackingHashMap<K, int> self) =>\n        self.Values.Sum();\n\n    [Pure]\n    public static Option<T> Find<A, B, T>(this TrackingHashMap<A, TrackingHashMap<B, T>> self, A outerKey, B innerKey) =>\n        self.Find(outerKey, b => b.Find(innerKey), () => None);\n\n    [Pure]\n    public static Option<T> Find<A, B, C, T>(this TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, T>>> self, A aKey, B bKey, C cKey) =>\n        self.Find(aKey, b => b.Find(bKey, c => c.Find(cKey), () => None), () => None);\n\n    [Pure]\n    public static R Find<A, B, T, R>(this TrackingHashMap<A, TrackingHashMap<B, T>> self, A outerKey, B innerKey, Func<T, R> Some, Func<R> None) =>\n        self.Find(outerKey, b => b.Find(innerKey, Some, None), None);\n\n    [Pure]\n    public static R Find<A, B, C, T, R>(this TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, T>>> self, A aKey, B bKey, C cKey, Func<T, R> Some, Func<R> None) =>\n        self.Find(aKey,\n            b => b.Find(bKey,\n                c => c.Find(cKey, Some, None),\n                None),\n            None);\n\n    [Pure]\n    public static R Find<A, B, C, D, T, R>(this TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, TrackingHashMap<D, T>>>> self, A aKey, B bKey, C cKey, D dKey, Func<T, R> Some, Func<R> None) =>\n        self.Find(aKey,\n            b => b.Find(bKey,\n                c => c.Find(cKey,\n                    d => d.Find(dKey, Some, None),\n                    None),\n                None),\n            None);\n\n    [Pure]\n    public static TrackingHashMap<A, TrackingHashMap<B, T>> AddOrUpdate<A, B, T>(this TrackingHashMap<A, TrackingHashMap<B, T>> self, A outerKey, B innerKey, Func<T, T> Some, Func<T> None) =>\n        self.AddOrUpdate(\n            outerKey,\n            b => b.AddOrUpdate(innerKey, Some, None),\n            () => TrackingHashMap((innerKey, None()))\n        );\n\n    [Pure]\n    public static TrackingHashMap<A, TrackingHashMap<B, T>> AddOrUpdate<A, B, T>(this TrackingHashMap<A, TrackingHashMap<B, T>> self, A outerKey, B innerKey, T value) =>\n        self.AddOrUpdate(\n            outerKey,\n            b => b.AddOrUpdate(innerKey, _ => value, value),\n            () => TrackingHashMap((innerKey, value))\n        );\n\n    [Pure]\n    public static TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, T>>> AddOrUpdate<A, B, C, T>(this TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, T>>> self, A aKey, B bKey, C cKey, T value) =>\n        self.AddOrUpdate(\n            aKey,\n            bKey,\n            c => c.AddOrUpdate(cKey, _ => value, value),\n            () => TrackingHashMap((cKey, value))\n        );\n\n    [Pure]\n    public static TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, T>>> AddOrUpdate<A, B, C, T>(this TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, T>>> self, A aKey, B bKey, C cKey, Func<T, T> Some, Func<T> None) =>\n        self.AddOrUpdate(\n            aKey,\n            bKey,\n            c => c.AddOrUpdate(cKey, Some, None),\n            () => TrackingHashMap((cKey, None()))\n        );\n\n    [Pure]\n    public static TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, TrackingHashMap<D, T>>>> AddOrUpdate<A, B, C, D, T>(this TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, TrackingHashMap<D, T>>>> self, A aKey, B bKey, C cKey, D dKey, T value) =>\n        self.AddOrUpdate(\n            aKey,\n            bKey,\n            cKey,\n            d => d.AddOrUpdate(dKey, _ => value, value),\n            () => TrackingHashMap((dKey, value))\n        );\n\n    [Pure]\n    public static TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, TrackingHashMap<D, T>>>> AddOrUpdate<A, B, C, D, T>(this TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, TrackingHashMap<D, T>>>> self, A aKey, B bKey, C cKey, D dKey, Func<T, T> Some, Func<T> None) =>\n        self.AddOrUpdate(\n            aKey,\n            bKey,\n            cKey,\n            d => d.AddOrUpdate(dKey, Some, None),\n            () => TrackingHashMap((dKey, None()))\n        );\n\n    [Pure]\n    public static TrackingHashMap<A, TrackingHashMap<B, T>> Remove<A, B, T>(this TrackingHashMap<A, TrackingHashMap<B, T>> self, A outerKey, B innerKey)\n    {\n        var b = self.Find(outerKey);\n        if (b.IsSome)\n        {\n            var bv = b.Value.Remove(innerKey);\n            if (bv.Count() == 0)\n            {\n                return self.Remove(outerKey);\n            }\n            else\n            {\n                return self.SetItem(outerKey, bv);\n            }\n        }\n        else\n        {\n            return self;\n        }\n    }\n\n    [Pure]\n    public static TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, T>>> Remove<A, B, C, T>(this TrackingHashMap<A, TrackingHashMap<B, TrackingHashMap<C, T>>> self, A aKey, B bKey, C cKey)\n    {\n        var b = self.Find(aKey);\n        if (b.IsSome)\n        {\n            var c = b.Value.Find(bKey);\n            if (c.IsSome)\n            {\n                var cv = c.Value.Remove(cKey);\n                if (cv.Count() == 0)\n                {\n                    var bv = b.Value.Remove(bKey);\n                    if (b.Value.Count() == 0)\n                    {\n                        return self.Remove(aKey);\n                    }\n                    else\n                    {\n                        return self.SetItem(aKey, bv);\n                    }\n                }\n                else\n                {\n                    return self.SetItem(aKey, b.Value.SetItem(bKey, cv));\n                }\n            }\n            else\n            {\n                return self;\n            }\n        }\n        else\n        {\n            return self;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/TrackingHashMap/TrackingHashMap.Module.Eq.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable tracking hash-map module\n/// </summary>\npublic static partial class TrackingHashMap\n{\n    /// <summary>\n    /// Creates a singleton TrackingHashMap \n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> singleton<EqK, K, V>((K, V) value) where EqK : Eq<K>  =>\n        [value];\n    \n    /// <summary>\n    /// Creates a singleton TrackingHashMap \n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> singleton<EqK, K, V>(K key, V value) where EqK : Eq<K>  =>\n        [(key, value)];\n\n    /// <summary>\n    /// Creates a new empty TrackingHashMap \n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> empty<EqK, K, V>() where EqK : Eq<K> =>\n        TrackingHashMap<EqK, K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new empty TrackingHashMap \n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> create<EqK, K, V>() where EqK : Eq<K> =>\n        TrackingHashMap<EqK, K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> create<EqK, K, V>(Tuple<K, V> head, params Tuple<K, V>[] tail) where EqK : Eq<K> =>\n        empty<EqK, K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> create<EqK, K, V>((K, V) head, params (K, V)[] tail) where EqK : Eq<K> =>\n        empty<EqK, K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> create<EqK, K, V>(KeyValuePair<K, V> head, params KeyValuePair<K,V>[] tail) where EqK : Eq<K> =>\n        empty<EqK, K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> createRange<EqK, K, V>(IEnumerable<Tuple<K, V>> keyValues) where EqK : Eq<K> =>\n        empty<EqK, K, V>().AddRange(keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> createRange<EqK, K, V>(IEnumerable<(K, V)> keyValues) where EqK : Eq<K> =>\n        new (keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> createRange<EqK, K, V>(ReadOnlySpan<(K, V)> keyValues) where EqK : Eq<K> =>\n        keyValues.IsEmpty\n            ? TrackingHashMap<EqK, K, V>.Empty\n            : new(keyValues);\n\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> createRange<EqK, K, V>(IEnumerable<KeyValuePair<K, V>> keyValues) where EqK : Eq<K> =>\n        empty<EqK, K, V>().AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> add<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.Add(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> tryAdd<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.TryAdd(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addOrUpdate<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.AddOrUpdate(key, value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addOrUpdate<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, Func<V, V> Some, Func<V> None) where EqK : Eq<K> =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addOrUpdate<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, Func<V, V> Some, V None) where EqK : Eq<K> =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> keyValues) where EqK : Eq<K> =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<(K, V)> keyValues) where EqK : Eq<K> =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) where EqK : Eq<K> =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> tryAddRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> keyValues) where EqK : Eq<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> tryAddRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<(K, V)> keyValues) where EqK : Eq<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> tryAddRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) where EqK : Eq<K> =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addOrUpdateRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> range) where EqK : Eq<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addOrUpdateRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<(K, V)> range) where EqK : Eq<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> addOrUpdateRange<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> range) where EqK : Eq<K> =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> remove<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key) where EqK : Eq<K> =>\n        map.Remove(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool containsKey<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key) where EqK : Eq<K> =>\n        map.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<EqK, K, V>(TrackingHashMap<EqK, K, V> map, KeyValuePair<K, V> kv) where EqK : Eq<K> =>\n        map.Contains(kv.Key, kv.Value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Tuple<K, V> kv) where EqK : Eq<K> =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<EqK, K, V>(TrackingHashMap<EqK, K, V> map, (K, V) kv) where EqK : Eq<K> =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> setItem<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.SetItem(key, value);\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> trySetItem<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, V value) where EqK : Eq<K> =>\n        map.TrySetItem(key, value);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map (Some), and then putting \n    /// it back. Silently fails if the value doesn't exist.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> trySetItem<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, Func<V, V> Some) where EqK : Eq<K> =>\n        map.TrySetItem(key, Some);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> setItems<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> setItems<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<(K, V)> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> setItems<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> trySetItems<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<Tuple<K, V>> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> trySetItems<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<(K, V)> items) where EqK : Eq<K> =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> trySetItems<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<KeyValuePair<K, V>> items) where EqK : Eq<K> =>\n        map.TrySetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> trySetItems<EqK, K, V>(TrackingHashMap<EqK, K, V> map, IEnumerable<K> keys, Func<V, V> Some) where EqK : Eq<K> =>\n        map.TrySetItems(keys, Some);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static Option<V> find<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key) where EqK : Eq<K> =>\n        map.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static IEnumerable<V> findSeq<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key) where EqK : Eq<K> =>\n        map.FindSeq(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static R find<EqK, K, V, R>(TrackingHashMap<EqK, K, V> map, K key, Func<V, R> Some, Func<R> None) where EqK : Eq<K> =>\n        map.Find(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> setItem<EqK, K, V>(TrackingHashMap<EqK, K, V> map, K key, Func<V, V> mapper) where EqK : Eq<K> =>\n        map.SetItem(key, mapper);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Action<V> action) where EqK : Eq<K> =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Action<K, V> action) where EqK : Eq<K> =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<V, bool> pred) where EqK : Eq<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<K, V, bool> pred) where EqK : Eq<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<(K Key, V Value), bool> pred) where EqK : Eq<K> =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<KeyValuePair<K, V>, bool> pred) where EqK : Eq<K> =>\n        map.ForAll(pred);\n\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> filter<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<V, bool> predicate) where EqK : Eq<K> =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public static TrackingHashMap<EqK, K, V> filter<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<K, V, bool> predicate) where EqK : Eq<K> =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public static int length<EqK, K, T>(TrackingHashMap<EqK, K, T> map) where EqK : Eq<K> =>\n        map.Count;\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<EqK, S, K, V>(TrackingHashMap<EqK, K, V> map, S state, Func<S, K, V, S> folder) where EqK : Eq<K> =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<EqK, S, K, V>(TrackingHashMap<EqK, K, V> map, S state, Func<S, V, S> folder) where EqK : Eq<K> =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<K, V, bool> pred) where EqK : Eq<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<(K Key, V Value), bool> pred) where EqK : Eq<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<KeyValuePair<K, V>, bool> pred) where EqK : Eq<K> =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<EqK, K, V>(TrackingHashMap<EqK, K, V> map, Func<V, bool> pred) where EqK : Eq<K> =>\n        map.Exists(pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/TrackingHashMap/TrackingHashMap.Module.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Immutable tracking hash-map module\n/// </summary>\npublic static partial class TrackingHashMap\n{\n    /// <summary>\n    /// Creates a new empty TrackingHashMap \n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> empty<K, V>() =>\n        TrackingHashMap<K, V>.Empty;\n        \n    /// <summary>\n    /// Creates a singleton TrackingHashMap \n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> singleton<K, V>((K, V) value) =>\n        [value];\n        \n    /// <summary>\n    /// Creates a singleton TrackingHashMap \n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> singleton<K, V>(K key, V value) =>\n        [(key, value)];\n\n    /// <summary>\n    /// Creates a new empty TrackingHashMap \n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> create<K, V>() =>\n        TrackingHashMap<K, V>.Empty;\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> create<K, V>(Tuple<K, V> head, params Tuple<K, V>[] tail) =>\n        empty<K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> create<K, V>((K, V) head, params (K, V)[] tail) =>\n        empty<K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> create<K, V>(KeyValuePair<K, V> head, params KeyValuePair<K,V>[] tail) =>\n        empty<K, V>().AddRange(head.Cons(tail));\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> createRange<K, V>(IEnumerable<Tuple<K, V>> keyValues) =>\n        empty<K, V>().AddRange(keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> createRange<K, V>(IEnumerable<(K, V)> keyValues) =>\n        new (keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> createRange<K, V>(ReadOnlySpan<(K, V)> keyValues) =>\n        keyValues.IsEmpty\n            ? TrackingHashMap<K, V>.Empty \n            : new (keyValues);\n\n    /// <summary>\n    /// Creates a new Map seeded with the keyValues provided\n    /// </summary>\n    [Pure]\n    public static TrackingHashMap<K, V> createRange<K, V>(IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        empty<K, V>().AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> add<K, V>(TrackingHashMap<K, V> map, K key, V value) =>\n        map.Add(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> tryAdd<K, V>(TrackingHashMap<K, V> map, K key, V value) =>\n        map.TryAdd(key, value);\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addOrUpdate<K, V>(TrackingHashMap<K, V> map, K key, V value) =>\n        map.AddOrUpdate(key, value);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addOrUpdate<K, V>(TrackingHashMap<K, V> map, K key, Func<V, V> Some, Func<V> None) =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addOrUpdate<K, V>(TrackingHashMap<K, V> map, K key, Func<V, V> Some, V None) =>\n        map.AddOrUpdate(key, Some, None);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<Tuple<K, V>> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<(K, V)> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        map.AddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> tryAddRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<Tuple<K, V>> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> tryAddRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<(K, V)> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> tryAddRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> keyValues) =>\n        map.TryAddRange(keyValues);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addOrUpdateRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<Tuple<K, V>> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addOrUpdateRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<(K, V)> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> addOrUpdateRange<K, V>(TrackingHashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> range) =>\n        map.AddOrUpdateRange(range);\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> remove<K, V>(TrackingHashMap<K, V> map, K key) =>\n        map.Remove(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool containsKey<K, V>(TrackingHashMap<K, V> map, K key) =>\n        map.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<K, V>(TrackingHashMap<K, V> map, KeyValuePair<K, V> kv) =>\n        map.Contains(kv.Key, kv.Value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<K, V>(TrackingHashMap<K, V> map, Tuple<K, V> kv) =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public static bool contains<K, V>(TrackingHashMap<K, V> map, (K, V) kv) =>\n        map.Contains(kv.Item1, kv.Item2);\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> setItem<K, V>(TrackingHashMap<K, V> map, K key, V value) =>\n        map.SetItem(key, value);\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> trySetItem<K, V>(TrackingHashMap<K, V> map, K key, V value) =>\n        map.TrySetItem(key, value);\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map (Some), and then putting \n    /// it back. Silently fails if the value doesn't exist.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> trySetItem<K, V>(TrackingHashMap<K, V> map, K key, Func<V, V> Some) =>\n        map.TrySetItem(key, Some);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> setItems<K, V>(TrackingHashMap<K, V> map, IEnumerable<Tuple<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> setItems<K, V>(TrackingHashMap<K, V> map, IEnumerable<(K, V)> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> setItems<K, V>(TrackingHashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> trySetItems<K, V>(TrackingHashMap<K, V> map, IEnumerable<Tuple<K, V>> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> trySetItems<K, V>(TrackingHashMap<K, V> map, IEnumerable<(K, V)> items) =>\n        map.SetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> trySetItems<K, V>(TrackingHashMap<K, V> map, IEnumerable<KeyValuePair<K, V>> items) =>\n        map.TrySetItems(items);\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> trySetItems<K, V>(TrackingHashMap<K, V> map, IEnumerable<K> keys, Func<V, V> Some) =>\n        map.TrySetItems(keys, Some);\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static Option<V> find<K, V>(TrackingHashMap<K, V> map, K key) =>\n        map.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static IEnumerable<V> findSeq<K, V>(TrackingHashMap<K, V> map, K key) =>\n        map.FindSeq(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public static R find<K, V, R>(TrackingHashMap<K, V> map, K key, Func<V, R> Some, Func<R> None) =>\n        map.Find(key, Some, None);\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> setItem<K, V>(TrackingHashMap<K, V> map, K key, Func<V, V> mapper) =>\n        map.SetItem(key, mapper);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<K, V>(TrackingHashMap<K, V> map, Action<V> action) =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public static Unit iter<K, V>(TrackingHashMap<K, V> map, Action<K, V> action) =>\n        map.Iter(action);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(TrackingHashMap<K, V> map, Func<V, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(TrackingHashMap<K, V> map, Func<K, V, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(TrackingHashMap<K, V> map, Func<(K Key, V Value), bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool forall<K, V>(TrackingHashMap<K, V> map, Func<KeyValuePair<K, V>, bool> pred) =>\n        map.ForAll(pred);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> filter<K, V>(TrackingHashMap<K, V> map, Func<V, bool> predicate) =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public static TrackingHashMap<K, V> filter<K, V>(TrackingHashMap<K, V> map, Func<K, V, bool> predicate) =>\n        map.Filter(predicate);\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public static int length<K, T>(TrackingHashMap<K, T> map) =>\n        map.Count;\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<S, K, V>(TrackingHashMap<K, V> map, S state, Func<S, K, V, S> folder) =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public static S fold<S, K, V>(TrackingHashMap<K, V> map, S state, Func<S, V, S> folder) =>\n        map.Fold(state, folder);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(TrackingHashMap<K, V> map, Func<K, V, bool> pred) =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(TrackingHashMap<K, V> map, Func<(K Key, V Value), bool> pred) =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(TrackingHashMap<K, V> map, Func<KeyValuePair<K, V>, bool> pred) =>\n        map.Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public static bool exists<K, V>(TrackingHashMap<K, V> map, Func<V, bool> pred) =>\n        map.Exists(pred);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/TrackingHashMap/TrackingHashMap.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\n\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Unsorted immutable hash-map that tracks changes.\n/// </summary>\n/// <remarks>\n/// Changes are accessible via the `Changes` property.  It is a `HashMap` of `Change` values from either the initial\n/// empty state of the collection, or since the last call to `Snapshot()`.\n///\n/// The fact that the changes are represented as a single-value `HashMap` shows that the tracked changes are not an\n/// ever increasing log of changes, but instead a morphism between one previous state of the `TrackingHashMap` and\n/// another.  Therefore there's at most one morphism for each key, and potentially none.\n///\n/// The morphisms are:\n///\n///     * `EntryAdded`\n///     * `EntryMapped`\n///     * `EntryRemoved`\n///\n/// A new 'zero-changes starting-state' can be created by calling `Snapshot()`.  `Snapshot` creates the first\n/// snapshot (effectively clears the `Changes` to zero), and `Changes` will collect the difference from this point\n/// to any morphed future-state as collection-transforming operations are performed\n/// </remarks>\n/// <typeparam name=\"K\">Key type</typeparam>\n/// <typeparam name=\"V\">Value</typeparam>\n[CollectionBuilder(typeof(TrackingHashMap), nameof(TrackingHashMap.createRange))]\npublic readonly struct TrackingHashMap<K, V> :\n    IReadOnlyDictionary<K, V>,\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<TrackingHashMap<K, V>>,\n    Monoid<TrackingHashMap<K, V>>\n{\n    public static TrackingHashMap<K, V> Empty { get; } = new(TrieMap<EqDefault<K>, K, V>.Empty);\n\n    readonly TrieMap<EqDefault<K>, K, V> value;\n    readonly TrieMap<EqDefault<K>, K, Change<V>> changes;\n\n    internal TrieMap<EqDefault<K>, K, V> Value => \n        value ?? TrieMap<EqDefault<K>, K, V>.Empty;\n\n    internal TrieMap<EqDefault<K>, K, Change<V>> ChangesInternal => \n        changes ?? TrieMap<EqDefault<K>, K, Change<V>>.Empty;\n\n    public HashMap<K, Change<V>> Changes => \n        new (ChangesInternal);\n\n    internal TrackingHashMap(TrieMap<EqDefault<K>, K, V> value, TrieMap<EqDefault<K>, K, Change<V>> changes)\n    {\n        this.value = value;\n        this.changes = changes;\n    }\n\n    public TrackingHashMap(IEnumerable<(K Key, V Value)> items) \n        : this(items, true)\n    { }\n\n    public TrackingHashMap(IEnumerable<(K Key, V Value)> items, bool tryAdd)\n    {\n        value = new TrieMap<EqDefault<K>, K, V>(items, tryAdd);\n        changes = TrieMap<EqDefault<K>, K, Change<V>>.Empty;\n    }\n\n    public TrackingHashMap(ReadOnlySpan<(K Key, V Value)> items) \n        : this(items, true)\n    { }\n\n    public TrackingHashMap(ReadOnlySpan<(K Key, V Value)> items, bool tryAdd)\n    {\n        value = new TrieMap<EqDefault<K>, K, V>(items, tryAdd);\n        changes = TrieMap<EqDefault<K>, K, Change<V>>.Empty;\n    }\n\n    /// <summary>\n    /// Creates a 'zero change' snapshot.  *The data does not change*!   \n    /// </summary>\n    /// <remarks>Useful for creating new starting points for capturing the difference between two snapshots of the\n    /// `TrackingHashMap`.  `Snapshot` creates the first snapshot (effectively clears the `Changes` to zero), and\n    /// `Changes` will collect the difference from this point to any morphed future point as collection \n    /// transforming operations are performed</remarks>\n    /// <returns>Map with changes zeroed</returns>\n    [Pure]\n    public TrackingHashMap<K, V> Snapshot() =>\n        new (Value, TrieMap<EqDefault<K>, K, Change<V>>.Empty);\n\n    /// <summary>\n    /// Item at index lens\n    /// </summary>\n    [Pure]\n    public static Lens<TrackingHashMap<K, V>, V> item(K key) => Lens<TrackingHashMap<K, V>, V>.New(\n        Get: la => la[key],\n        Set: a => la => la.AddOrUpdate(key, a)\n    );\n\n    /// <summary>\n    /// Item or none at index lens\n    /// </summary>\n    [Pure]\n    public static Lens<TrackingHashMap<K, V>, Option<V>> itemOrNone(K key) => Lens<TrackingHashMap<K, V>, Option<V>>.New(\n        Get: la => la.Find(key),\n        Set: a => la => a.Match(Some: x => la.AddOrUpdate(key, x), None: () => la.Remove(key))\n    );\n\n    TrackingHashMap<K, V> Wrap((TrieMap<EqDefault<K>, K, V> Map, TrieMap<EqDefault<K>, K, Change<V>> Changes) pair) =>\n        new (pair.Map, ChangesInternal.Merge(pair.Changes));\n\n    TrackingHashMap<K, V> Wrap(K key, (TrieMap<EqDefault<K>, K, V> Map, Change<V> Change) pair) =>\n        new (pair.Map, ChangesInternal.AddOrUpdate(key, Some: ex => ex.Combine(pair.Change), pair.Change));\n\n    /// <summary>\n    /// 'this' accessor\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>Optional value</returns>\n    [Pure]\n    public V this[K key] =>\n        Value[key];\n\n    /// <summary>\n    /// Is the map empty\n    /// </summary>\n    [Pure]\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.IsEmpty ?? true;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    [Pure]\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Alias of Count\n    /// </summary>\n    [Pure]\n    public int Length\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => value?.Count ?? 0;\n    }\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public TrackingHashMap<K, V> Filter(Func<V, bool> pred) =>\n        Wrap(Value.FilterWithLog(pred));\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    public TrackingHashMap<K, V> Filter(Func<K, V, bool> pred) =>\n        Wrap(Value.FilterWithLog(pred));\n\n    /// <summary>\n    /// Atomically adds a new item to the map\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the key already exists</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> Add(K key, V value) =>\n        Wrap(key, Value.AddWithLog(key, value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, then the new item is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TryAdd(K key, V value) =>\n        Wrap(key, Value.TryAddWithLog(key, value));\n\n    /// <summary>\n    /// Atomically adds a new item to the map.\n    /// If the key already exists, the new item replaces it.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddOrUpdate(K key, V value) =>\n        Wrap(key, Value.AddOrUpdateWithLog(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"Exception\">Throws Exception if None returns null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddOrUpdate(K key, Func<V, V> Some, Func<V> None) =>\n        Wrap(key, Value.AddOrUpdateWithLog(key, Some, None));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.  If it doesn't exist, add a new one based on None result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException if None is null</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddOrUpdate(K key, Func<V, V> Some, V None) =>\n        Wrap(key, Value.AddOrUpdateWithLog(key, Some, None));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.AddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.AddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TryAddRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.TryAddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TryAddRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.TryAddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're ignored.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TryAddRange(IEnumerable<KeyValuePair<K, V>> range) =>\n        Wrap(Value.TryAddRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddOrUpdateRange(IEnumerable<Tuple<K, V>> range) =>\n        Wrap(Value.AddOrUpdateRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of tuples to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddOrUpdateRange(IEnumerable<(K Key, V Value)> range) =>\n        Wrap(Value.AddOrUpdateRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically adds a range of items to the map.  If any of the keys exist already\n    /// then they're replaced.\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"range\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the keys or values are null</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> range) =>\n        Wrap(Value.AddOrUpdateRangeWithLog(range));\n\n    /// <summary>\n    /// Atomically removes an item from the map\n    /// If the key doesn't exists, the request is ignored.\n    /// </summary>\n    /// <param name=\"key\">Key</param>\n    /// <returns>New map with the item removed</returns>\n    [Pure]\n    public TrackingHashMap<K, V> Remove(K key) =>\n        Wrap(key, Value.RemoveWithLog(key));\n\n    /// <summary>\n    /// Retrieve a value from the map by key\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Option<V> Find(K key) =>\n        Value.Find(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key as an enumerable\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public Seq<V> FindSeq(K key) =>\n        Value.FindAll(key);\n\n    /// <summary>\n    /// Retrieve a value from the map by key and pattern match the\n    /// result.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <returns>Found value</returns>\n    [Pure]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None) =>\n        Value.Find(key, Some, None);\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (TrackingHashMap<K, V> Map, V Value) FindOrAdd(K key, Func<V> None)\n    {\n        var (x, y, cs) = Value.FindOrAddWithLog(key, None);\n        return (Wrap(key, (x, cs)), y);\n    }\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"value\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (TrackingHashMap<K, V>, V Value) FindOrAdd(K key, V value)\n    {\n        var (x, y, cs) = Value.FindOrAddWithLog(key, value);\n        return (Wrap(key, (x, cs)), y);\n    }\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (TrackingHashMap<K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Func<Option<V>> None)\n    {\n        var (x, y, cs) = Value.FindOrMaybeAddWithLog(key, None);\n        return (Wrap(key, (x, cs)), y);\n    }\n\n    /// <summary>\n    /// Try to find the key in the map, if it doesn't exist, add a new \n    /// item by invoking the delegate provided.\n    /// </summary>\n    /// <param name=\"key\">Key to find</param>\n    /// <param name=\"None\">Delegate to get the value</param>\n    /// <returns>Updated map and added value</returns>\n    [Pure]\n    public (TrackingHashMap<K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Option<V> None)\n    {\n        var (x, y, cs) = Value.FindOrMaybeAddWithLog(key, None);\n        return (Wrap(key, (x, cs)), y);\n    }\n\n    /// <summary>\n    /// Atomically updates an existing item\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> SetItem(K key, V value) =>\n        Wrap(key, Value.SetItemWithLog(key, value));\n\n    /// <summary>\n    /// Retrieve a value from the map by key, map it to a new value,\n    /// put it back.\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if the item isn't found</exception>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <returns>New map with the mapped value</returns>\n    [Pure]\n    public TrackingHashMap<K, V> SetItem(K key, Func<V, V> Some) =>\n        Wrap(key, Value.SetItemWithLog(key, Some));\n\n    /// <summary>\n    /// Atomically updates an existing item, unless it doesn't exist, in which case \n    /// it is ignored\n    /// </summary>\n    /// <remarks>Null is not allowed for a Key or a Value</remarks>\n    /// <param name=\"key\">Key</param>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the value is null</exception>\n    /// <returns>New Map with the item added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TrySetItem(K key, V value) =>\n        Wrap(key, Value.TrySetItemWithLog(key, value));\n\n    /// <summary>\n    /// Atomically sets an item by first retrieving it, applying a map, and then putting it back.\n    /// Silently fails if the value doesn't exist\n    /// </summary>\n    /// <param name=\"key\">Key to set</param>\n    /// <param name=\"Some\">delegate to map the existing value to a new one before setting</param>\n    /// <exception cref=\"Exception\">Throws Exception if Some returns null</exception>\n    /// <exception cref=\"ArgumentNullException\">Throws ArgumentNullException the key or value are null</exception>\n    /// <returns>New map with the item set</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TrySetItem(K key, Func<V, V> Some) =>\n        Wrap(key, Value.TrySetItemWithLog(key, Some));\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool ContainsKey(K key) =>\n        Value.ContainsKey(key);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains(K key, V value) =>\n        Value.Contains(key, value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    public bool Contains(V value) =>\n        Value.Contains(value);\n\n    /// <summary>\n    /// Checks for existence of a value in the map\n    /// </summary>\n    /// <param name=\"value\">Value to check</param>\n    /// <returns>True if an item with the value supplied is in the map</returns>\n    [Pure]\n    public bool Contains<EqV>(V value) where EqV : Eq<V> =>\n        Value.Contains<EqV>(value);\n\n    /// <summary>\n    /// Checks for existence of a key in the map\n    /// </summary>\n    /// <param name=\"key\">Key to check</param>\n    /// <returns>True if an item with the key supplied is in the map</returns>\n    [Pure]\n    public bool Contains<EqV>(K key, V value) where EqV : Eq<V> =>\n        Value.Contains<EqV>(key, value);\n\n    /// <summary>\n    /// Clears all items from the map \n    /// </summary>\n    /// <remarks>Functionally equivalent to calling Map.empty as the original structure is untouched</remarks>\n    /// <returns>Empty map</returns>\n    [Pure]\n    public TrackingHashMap<K, V> Clear() =>\n        Wrap(Value.ClearWithLog());\n\n    /// <summary>\n    /// Atomically adds a range of items to the map\n    /// </summary>\n    /// <param name=\"pairs\">Range of KeyValuePairs to add</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys already exist</exception>\n    /// <returns>New Map with the items added</returns>\n    [Pure]\n    public TrackingHashMap<K, V> AddRange(IEnumerable<KeyValuePair<K, V>> pairs) =>\n        Wrap(Value.AddRangeWithLog(pairs));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<K, V> SetItems(IEnumerable<KeyValuePair<K, V>> items) =>\n        Wrap(Value.SetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<K, V> SetItems(IEnumerable<Tuple<K, V>> items) =>\n        Wrap(Value.SetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <exception cref=\"ArgumentException\">Throws ArgumentException if any of the keys aren't in the map</exception>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<K, V> SetItems(IEnumerable<(K Key, V Value)> items) =>\n        Wrap(Value.SetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the KeyValuePairs provided.  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TrySetItems(IEnumerable<KeyValuePair<K, V>> items) =>\n        Wrap(Value.TrySetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TrySetItems(IEnumerable<Tuple<K, V>> items) =>\n        Wrap(Value.TrySetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the Tuples provided  If any of the \n    /// items don't exist then they're silently ignored.\n    /// </summary>\n    /// <param name=\"items\">Items to set</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TrySetItems(IEnumerable<(K Key, V Value)> items) =>\n        Wrap(Value.TrySetItemsWithLog(items));\n\n    /// <summary>\n    /// Atomically sets a series of items using the keys provided to find the items\n    /// and the Some delegate maps to a new value.  If the items don't exist then\n    /// they're silently ignored.\n    /// </summary>\n    /// <param name=\"keys\">Keys of items to set</param>\n    /// <param name=\"Some\">Function map the existing item to a new one</param>\n    /// <returns>New map with the items set</returns>\n    [Pure]\n    public TrackingHashMap<K, V> TrySetItems(IEnumerable<K> keys, Func<V, V> Some) =>\n        Wrap(Value.TrySetItemsWithLog(keys, Some));\n\n    /// <summary>\n    /// Atomically removes a set of keys from the map\n    /// </summary>\n    /// <param name=\"keys\">Keys to remove</param>\n    /// <returns>New map with the items removed</returns>\n    [Pure]\n    public TrackingHashMap<K, V> RemoveRange(IEnumerable<K> keys) =>\n        Wrap(Value.RemoveRangeWithLog(keys));\n\n    /// <summary>\n    /// Returns true if a Key/Value pair exists in the map\n    /// </summary>\n    /// <param name=\"pair\">Pair to find</param>\n    /// <returns>True if exists, false otherwise</returns>\n    [Pure]\n    public bool Contains(KeyValuePair<K, V> pair) =>\n        Value.Contains(pair.Key, pair.Value);\n\n    /// <summary>\n    /// Enumerable of map keys\n    /// </summary>\n    [Pure]\n    public Iterable<K> Keys =>\n        Value.Keys;\n\n    /// <summary>\n    /// Enumerable of map values\n    /// </summary>\n    [Pure]\n    public Iterable<V> Values =>\n        Value.Values;\n\n    /// <summary>\n    /// Convert the map to an IDictionary\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public IReadOnlyDictionary<K, V> ToDictionary() =>\n        this;\n\n    /// <summary>\n    /// Map the map the a dictionary\n    /// </summary>\n    [Pure]\n    public IDictionary<KR, VR> ToDictionary<KR, VR>(\n        Func<(K Key, V Value), KR> keySelector, \n        Func<(K Key, V Value), VR> valueSelector) \n        where KR : notnull =>\n        AsEnumerable().ToDictionary(x => keySelector(x), x => valueSelector(x));\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        Value.GetEnumerator();\n\n    /// <summary>\n    /// GetEnumerator - IEnumerable interface\n    /// </summary>\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Value.GetEnumerator();\n\n    [Pure]\n    public Seq<(K Key, V Value)> ToSeq() =>\n        toSeq(AsEnumerable());\n\n    /// <summary>\n    /// Allocation free conversion to a HashMap\n    /// </summary>\n    [Pure]\n    public HashMap<K, V> ToHashMap() =>\n        new (value);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// The elipsis is used for collections over 50 items\n    /// To get a formatted string with all the items, use `ToFullString`\n    /// or `ToFullArrayString`.\n    /// </summary>\n    [Pure]\n    public override string ToString() =>\n        CollectionFormat.ToShortArrayString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), Count);\n\n    /// <summary>\n    /// Format the collection as `(key: value), (key: value), (key: value), ...`\n    /// </summary>\n    [Pure]\n    public string ToFullString(string separator = \", \") =>\n        CollectionFormat.ToFullString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    /// <summary>\n    /// Format the collection as `[(key: value), (key: value), (key: value), ...]`\n    /// </summary>\n    [Pure]\n    public string ToFullArrayString(string separator = \", \") =>\n        CollectionFormat.ToFullArrayString(AsEnumerable().Map(kv => $\"({kv.Key}: {kv.Value})\"), separator);\n\n    [Pure]\n    public Iterable<(K Key, V Value)> AsEnumerable() =>\n        Value.AsIterable();\n\n    /// <summary>\n    /// Implicit conversion from an untyped empty list\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator TrackingHashMap<K, V>(SeqEmpty _) =>\n        Empty;\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator ==(TrackingHashMap<K, V> lhs, TrackingHashMap<K, V> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// In-equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public static bool operator !=(TrackingHashMap<K, V> lhs, TrackingHashMap<K, V> rhs) =>\n        !(lhs == rhs);\n\n    [Pure]\n    public static TrackingHashMap<K, V> operator +(TrackingHashMap<K, V> lhs, TrackingHashMap<K, V> rhs) =>\n        lhs.Combine(rhs);\n\n    [Pure]\n    public TrackingHashMap<K, V> Combine(TrackingHashMap<K, V> rhs) =>\n        Wrap(Value.AppendWithLog(rhs.Value));\n\n    [Pure]\n    public static TrackingHashMap<K, V> operator -(TrackingHashMap<K, V> lhs, TrackingHashMap<K, V> rhs) =>\n        lhs.Subtract(rhs);\n\n    [Pure]\n    public TrackingHashMap<K, V> Subtract(TrackingHashMap<K, V> rhs) =>\n        Wrap(Value.SubtractWithLog(rhs.Value));\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    [Pure]\n    public bool IsProperSubsetOf(IEnumerable<K> other) =>\n        Value.IsProperSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    [Pure]\n    public bool IsProperSupersetOf(IEnumerable<K> other) =>\n        Value.IsProperSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(IEnumerable<K> other) =>\n        Value.IsSubsetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSubsetOf(TrackingHashMap<K, V> other) =>\n        Value.IsSubsetOf(other.Value);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        Value.IsSupersetOf(other);\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    [Pure]\n    public bool IsSupersetOf(IEnumerable<K> rhs) =>\n        Value.IsSupersetOf(rhs);\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<K, V> Intersect(IEnumerable<K> rhs) =>\n        Wrap(Value.IntersectWithLog(rhs));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<K, V> Intersect(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.IntersectWithLog(rhs));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<K, V> Intersect(IEnumerable<(K Key, V Value)> rhs, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.IntersectWithLog(new TrieMap<EqDefault<K>, K, V>(rhs), Merge));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<K, V> Intersect(HashMap<K, V> rhs, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.IntersectWithLog(rhs.Value, Merge));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<K, V> Intersect(TrackingHashMap<K, V> rhs, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.IntersectWithLog(rhs.Value, Merge));\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    [Pure]\n    public bool Overlaps(IEnumerable<K> other) =>\n        Value.Overlaps(other);\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<K, V> Except(IEnumerable<K> rhs) =>\n        Wrap(Value.ExceptWithLog(rhs));\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<K, V> Except(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.ExceptWithLog(rhs));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<K, V> SymmetricExcept(TrackingHashMap<K, V> rhs) =>\n        Wrap(Value.SymmetricExceptWithLog(rhs.Value));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    [Pure]\n    public TrackingHashMap<K, V> SymmetricExcept(IEnumerable<(K Key, V Value)> rhs) =>\n        Wrap(Value.SymmetricExceptWithLog(rhs));\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    [Pure]\n    public TrackingHashMap<K, V> Union(IEnumerable<(K, V)> rhs) =>\n        this.TryAddRange(rhs);\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<K, V> Union(IEnumerable<(K Key, V Value)> other, WhenMatched<K, V, V, V> Merge) =>\n        Wrap(Value.UnionWithLog(other, static (_, v) => v, static (_, v) => v, Merge));\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the right-hand side, but not the left-hand-side.\n    /// This allows the `V2` value-type to be mapped to the target `V` value-type. \n    /// </remarks>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrackingHashMap<K, V> Union<W>(IEnumerable<(K Key, W Value)> other, WhenMissing<K, W, V> MapRight, WhenMatched<K, V, W, V> Merge) =>\n        Wrap(Value.UnionWithLog(other, static (_, v) => v, MapRight, Merge));\n        \n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public override bool Equals(object? obj) =>\n        obj is TrackingHashMap<K, V> hm && Equals(hm);\n\n    /// <summary>\n    /// Equality of keys and values with `EqDefault〈V〉` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals(TrackingHashMap<K, V> other) =>\n        Value.Equals<EqDefault<V>>(other.Value);\n\n    /// <summary>\n    /// Equality of keys and values with `EqV` used for values\n    /// </summary>\n    [Pure]\n    public bool Equals<EqV>(TrackingHashMap<K, V> other) where EqV : Eq<V> =>\n        Value.Equals<EqV>(other.Value);\n\n    /// <summary>\n    /// Equality of keys only\n    /// </summary>\n    [Pure]\n    public bool EqualsKeys(TrackingHashMap<K, V> other) =>\n        Value.Equals<EqTrue<V>>(other.Value);\n\n    [Pure]\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public TrackingHashMap<K, V> Do(Action<V> f)\n    {\n        this.Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public TrackingHashMap<K, V> Where(Func<V, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Atomically filter out items that return false when a predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>New map with items filtered</returns>\n    [Pure]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public TrackingHashMap<K, V> Where(Func<K, V, bool> pred) =>\n        Filter(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<K, V, bool> pred)\n    {\n        foreach (var item in AsEnumerable())\n        {\n            if (!pred(item.Key, item.Value)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<(K Key, V Value), bool> pred) =>\n        AsEnumerable().Map(kv => (kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if *all* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<KeyValuePair<K, V>, bool> pred) =>\n        AsEnumerable().Map(kv => new KeyValuePair<K, V>(kv.Key, kv.Value)).ForAll(pred);\n\n    /// <summary>\n    /// Return true if all items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool ForAll(Func<V, bool> pred) =>\n        Values.ForAll(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    public bool Exists(Func<K, V, bool> pred)\n    {\n        foreach (var item in AsEnumerable())\n        {\n            if (pred(item.Key, item.Value)) return true;\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<(K Key, V Value), bool> pred) =>\n        AsEnumerable().Map(kv => ( kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<KeyValuePair<K, V>, bool> pred) =>\n        AsEnumerable().Map(kv => new KeyValuePair<K, V>(kv.Key, kv.Value)).Exists(pred);\n\n    /// <summary>\n    /// Return true if *any* items in the map return true when the predicate is applied\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if all items in the map return true when the predicate is applied</returns>\n    [Pure]\n    public bool Exists(Func<V, bool> pred) =>\n        Values.Exists(pred);\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<K, V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Key, item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all values in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<V> action)\n    {\n        foreach (var item in this)\n        {\n            action(item.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<Tuple<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new Tuple<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs (as tuples) in the map (in order) \n    /// and execute an action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<(K Key, V Value)> action)\n    {\n        foreach (var item in this)\n        {\n            action(item);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically iterate through all key/value pairs in the map (in order) and execute an\n    /// action on each\n    /// </summary>\n    /// <param name=\"action\">Action to execute</param>\n    /// <returns>Unit</returns>\n    public Unit Iter(Action<KeyValuePair<K, V>> action)\n    {\n        foreach (var item in this)\n        {\n            action(new KeyValuePair<K, V>(item.Key, item.Value));\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, K, V, S> folder) =>\n        AsEnumerable().Fold(state, (s, x) => folder(s, x.Key, x.Value));\n\n    /// <summary>\n    /// Atomically folds all items in the map (in order) using the folder function provided.\n    /// </summary>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Fold function</param>\n    /// <returns>Folded state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, V, S> folder) =>\n        Values.Fold(state, folder);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() =>\n        AsEnumerable().Map(p => new KeyValuePair<K, V>(p.Key, p.Value)).GetEnumerator();\n    \n    [Pure]\n    IEnumerable<K> IReadOnlyDictionary<K, V>.Keys => Keys;\n    \n    [Pure]\n    IEnumerable<V> IReadOnlyDictionary<K, V>.Values => Values;\n\n    [Pure]\n    public bool TryGetValue(K key, out V value)\n    {\n        var v = Find(key);\n        if (v.IsSome)\n        {\n            value = (V)v;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n    \n    /// <summary>\n    /// Get a IReadOnlyDictionary for this map.  No mapping is required, so this is very fast.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IReadOnlyDictionary<K, V> ToReadOnlyDictionary() =>\n        this;\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(ValueTuple<(K, V)> items) =>\n        [items.Item1];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V)) items) =>\n        [items.Item1, items.Item2];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15];\n\n    [Pure]\n    [Obsolete(Change.UseCollectionIntialiser)]\n    public static implicit operator TrackingHashMap<K, V>(((K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V), (K, V)) items) =>\n        [items.Item1, items.Item2, items.Item3, items.Item4, items.Item5, items.Item6, items.Item7, items.Item8, items.Item9, items.Item10, items.Item11, items.Item12, items.Item13, items.Item14, items.Item15, items.Item16];\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/TrieMap/TrieMap.cs",
    "content": "﻿using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Runtime.CompilerServices;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Collections;\nusing LanguageExt.ClassInstances;\nusing Array = System.Array;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Implementation of the CHAMP trie hash map data structure (Compressed Hash Array Map Trie)\n/// [efficient-immutable-collections.pdf](https://michael.steindorfer.name/publications/phd-thesis-efficient-immutable-collections.pdf)\n/// </summary>\n/// <remarks>\n/// Used by internally by `LanguageExt.HashMap`\n/// </remarks>\ninternal class TrieMap<EqK, K, V> :\n    IEnumerable<(K Key, V Value)>,\n    IEquatable<TrieMap<EqK, K, V>>\n    where EqK : Eq<K>\n{\n    internal enum UpdateType\n    {\n        Add,\n        TryAdd,\n        AddOrUpdate,\n        SetItem,\n        TrySetItem\n    }\n\n    internal enum Tag\n    {\n        Entries,\n        Collision,\n        Empty\n    }\n\n    public static readonly TrieMap<EqK, K, V> Empty = new (EmptyNode.Default, 0);\n    internal static TrieMap<EqK, K, V> EmptyForMutating => new (new EmptyNode(), 0);\n\n    readonly Node Root;\n    readonly int count;\n    int hash;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    TrieMap(Node root, int count)\n    {\n        Root = root;\n        this.count = count;\n    }\n\n    public TrieMap(IEnumerable<(K Key, V Value)> items, bool tryAdd = true)\n    {\n        Root = EmptyNode.Default;\n        var type = tryAdd ? UpdateType.TryAdd : UpdateType.AddOrUpdate;\n        foreach (var item in items)\n        {\n            var h       = (uint)EqK.GetHashCode(item.Key);\n            Sec section = default;\n            var (countDelta, newRoot, _, _) = Root.Update((type, true), item, h, section);\n            count += countDelta;\n            Root = newRoot;\n        }\n    }\n\n    public TrieMap(ReadOnlySpan<(K Key, V Value)> items, bool tryAdd = true)\n    {\n        Root = EmptyNode.Default;\n        var type = tryAdd ? UpdateType.TryAdd : UpdateType.AddOrUpdate;\n        foreach (var item in items)\n        {\n            var h       = (uint)EqK.GetHashCode(item.Key);\n            Sec section = default;\n            var (countDelta, newRoot, _, _) = Root.Update((type, true), item, h, section);\n            count += countDelta;\n            Root = newRoot;\n        }\n    }\n\n    /// <summary>\n    /// True if no items in the map\n    /// </summary>\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count == 0;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count;\n    }\n\n    /// <summary>\n    /// Add an item to the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Add(K key, V value) =>\n        Update(key, value, UpdateType.Add, false);\n\n    /// <summary>\n    /// Add an item to the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) AddWithLog(K key, V value) =>\n        UpdateWithLog(key, value, UpdateType.Add, false);\n\n    /// <summary>\n    /// Try to add an item to the map.  If it already exists, do\n    /// nothing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TryAdd(K key, V value) =>\n        Update(key, value, UpdateType.TryAdd, false);\n\n    /// <summary>\n    /// Try to add an item to the map.  If it already exists, do\n    /// nothing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) TryAddWithLog(K key, V value) =>\n        UpdateWithLog(key, value, UpdateType.TryAdd, false);\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddOrUpdate(K key, V value) =>\n        Update(key, value, UpdateType.AddOrUpdate, false);\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal TrieMap<EqK, K, V> AddOrUpdateInPlace(K key, V value) =>\n        Update(key, value, UpdateType.AddOrUpdate, true);\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) AddOrUpdateWithLog(K key, V value) =>\n        UpdateWithLog(key, value, UpdateType.AddOrUpdate, false);\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddOrUpdate(K key, Func<V, V> Some, Func<V> None)\n    {\n        var (found, _, value) = FindInternal(key);\n        return found\n                   ? AddOrUpdate(key, Some(value!))\n                   : AddOrUpdate(key, None());\n    }\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) AddOrUpdateWithLog(K key, Func<V, V> Some, Func<V> None)\n    {\n        var (found, _, value) = FindInternal(key);\n        return found\n                   ? AddOrUpdateWithLog(key, Some(value!))\n                   : AddOrUpdateWithLog(key, None());\n    }\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddOrMaybeUpdate(K key, Func<V, V> Some, Func<Option<V>> None)\n    {\n        var (found, _, value) = FindInternal(key);\n        return found\n                   ? AddOrUpdate(key, Some(value!))\n                   : None().Map(x => AddOrUpdate(key, x)).IfNone(this);\n    }\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) AddOrMaybeUpdateWithLog(K key, Func<V, V> Some, Func<Option<V>> None)\n    {\n        var (found, _, value) = FindInternal(key);\n        return found\n                   ? AddOrUpdateWithLog(key, Some(value!))\n                   : None().Map(x => AddOrUpdateWithLog(key, x)).IfNone((this, Change<V>.None));\n    }\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddOrUpdate(K key, Func<V, V> Some, V None)\n    {\n        var (found, _, value) = FindInternal(key);\n        return found\n                   ? AddOrUpdate(key, Some(value!))\n                   : AddOrUpdate(key, None);\n    }\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) AddOrUpdateWithLog(K key, Func<V, V> Some, V None)\n    {\n        var (found, _, value) = FindInternal(key);\n        return found\n                   ? AddOrUpdateWithLog(key, Some(value!))\n                   : AddOrUpdateWithLog(key, None);\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddRange(IEnumerable<(K Key, V Value)> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.Add(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) AddRangeWithLog(IEnumerable<(K Key, V Value)> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.AddWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddRange(IEnumerable<Tuple<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.Add(item.Item1, item.Item2);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) AddRangeWithLog(IEnumerable<Tuple<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.AddWithLog(item.Item1, item.Item2);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Item1, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddRange(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.Add(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) AddRangeWithLog(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.AddWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TryAddRange(IEnumerable<(K Key, V Value)> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TryAdd(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) TryAddRangeWithLog(IEnumerable<(K Key, V Value)> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.TryAddWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TryAddRange(IEnumerable<Tuple<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TryAdd(item.Item1, item.Item2);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) TryAddRangeWithLog(IEnumerable<Tuple<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.TryAddWithLog(item.Item1, item.Item2);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Item1, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TryAddRange(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TryAdd(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) TryAddRangeWithLog(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.TryAddWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddOrUpdateRange(IEnumerable<(K Key, V Value)> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.AddOrUpdate(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) AddOrUpdateRangeWithLog(IEnumerable<(K Key, V Value)> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.AddOrUpdateWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddOrUpdateRange(IEnumerable<Tuple<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.AddOrUpdate(item.Item1, item.Item2);\n        }\n        return self;\n    }\n       \n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) AddOrUpdateRangeWithLog(IEnumerable<Tuple<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.AddOrUpdateWithLog(item.Item1, item.Item2);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Item1, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n        \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> AddOrUpdateRange(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.AddOrUpdate(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) AddOrUpdateRangeWithLog(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.AddOrUpdateWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }        \n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> SetItems(IEnumerable<(K Key, V Value)> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.SetItem(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) SetItemsWithLog(IEnumerable<(K Key, V Value)> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.SetItemWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }        \n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> SetItems(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.SetItem(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) SetItemsWithLog(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.SetItemWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }        \n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> SetItems(IEnumerable<Tuple<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.SetItem(item.Item1, item.Item2);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) SetItemsWithLog(IEnumerable<Tuple<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.SetItemWithLog(item.Item1, item.Item2);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Item1, pair.Change);\n            }\n        }\n        return (self, changes);\n    }        \n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TrySetItems(IEnumerable<(K Key, V Value)> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TrySetItem(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) TrySetItemsWithLog(IEnumerable<(K Key, V Value)> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.TrySetItemWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }        \n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TrySetItems(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TrySetItem(item.Key, item.Value);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) TrySetItemsWithLog(IEnumerable<KeyValuePair<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.TrySetItemWithLog(item.Key, item.Value);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }        \n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TrySetItems(IEnumerable<Tuple<K, V>> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TrySetItem(item.Item1, item.Item2);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) TrySetItemsWithLog(IEnumerable<Tuple<K, V>> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.TrySetItemWithLog(item.Item1, item.Item2);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item.Item1, pair.Change);\n            }\n        }\n        return (self, changes);\n    }  \n        \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TrySetItems(IEnumerable<K> items, Func<V, V> Some)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TrySetItem(item, Some);\n        }\n        return self;\n    }\n        \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) TrySetItemsWithLog(IEnumerable<K> items, Func<V, V> Some)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.TrySetItemWithLog(item, Some);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> RemoveRange(IEnumerable<K> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.Remove(item);\n        }\n        return self;\n    }\n        \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V>, TrieMap<EqK, K, Change<V>> Changes) RemoveRangeWithLog(IEnumerable<K> items)\n    {\n        var self    = this;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var item in items)\n        {\n            var pair = self.RemoveWithLog(item);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    /// <summary>\n    /// Set an item that already exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> SetItem(K key, V value) =>\n        Update(key, value, UpdateType.SetItem, false);\n\n    /// <summary>\n    /// Set an item that already exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) SetItemWithLog(K key, V value) =>\n        UpdateWithLog(key, value, UpdateType.SetItem, false);\n        \n    /// <summary>\n    /// Set an item that already exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> SetItem(K key, Func<V, V> Some)\n    {\n        var value = Find(key).Map(Some).IfNone(() => throw new ArgumentException($\"Key doesn't exist in map: {key}\"));\n        return SetItem(key, value);\n    }\n        \n    /// <summary>\n    /// Set an item that already exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) SetItemWithLog(K key, Func<V, V> Some)\n    {\n        var value = Find(key).Map(Some).IfNone(() => throw new ArgumentException($\"Key doesn't exist in map: {key}\"));\n        return SetItemWithLog(key, value);\n    }\n\n    /// <summary>\n    /// Try to set an item that already exists in the map.  If none\n    /// exists, do nothing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TrySetItem(K key, V value) =>\n        Update(key, value, UpdateType.TrySetItem, false);\n\n    /// <summary>\n    /// Try to set an item that already exists in the map.  If none\n    /// exists, do nothing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) TrySetItemWithLog(K key, V value) =>\n        UpdateWithLog(key, value, UpdateType.TrySetItem, false);\n\n    /// <summary>\n    /// Set an item that already exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> TrySetItem(K key, Func<V, V> Some) =>\n        Find(key)\n           .Map(Some)\n           .Match(Some: v => SetItem(key, v),\n                  None: () => this);\n\n    /// <summary>\n    /// Set an item that already exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) TrySetItemWithLog(K key, Func<V, V> Some) =>\n        Find(key)\n           .Map(Some)\n           .Match(Some: v => SetItemWithLog(key, v),\n                  None: () => (this, Change<V>.None));\n\n    /// <summary>\n    /// Remove an item from the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Remove(K key)\n    {\n        var h       = (uint)EqK.GetHashCode(key);\n        Sec section = default;\n        var (countDelta, newRoot, _) = Root.Remove(key, h, section);\n        return ReferenceEquals(newRoot, Root)\n                   ? this\n                   : new TrieMap<EqK, K, V>(newRoot, count + countDelta);\n    }\n\n    /// <summary>\n    /// Remove an item from the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) RemoveWithLog(K key)\n    {\n        var h       = (uint)EqK.GetHashCode(key);\n        Sec section = default;\n        var (countDelta, newRoot, old) = Root.Remove(key, h, section);\n        return ReferenceEquals(newRoot, Root)\n                   ? (this, Change<V>.None)\n                   : (new TrieMap<EqK, K, V>(newRoot, count + countDelta), \n                      countDelta == 0\n                          ? Change<V>.None\n                          : Change<V>.Removed(old!));\n    }\n\n    /// <summary>\n    /// Indexer\n    /// </summary>\n    public V this[K key]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            var (found, _, value) = FindInternal(key);\n            return found\n                       ? value!\n                       : throw new ArgumentException($\"Key doesn't exist in map: {key}\");\n        }\n    }\n\n    /// <summary>\n    /// Get a key value pair from a key\n    /// </summary>\n    public (K Key, V Value) Get(K key)\n    {\n        var (found, nkey, value) = FindInternal(key);\n        return found\n                   ? (nkey, value!)\n                   : throw new ArgumentException($\"Key doesn't exist in map: {key}\");\n    }\n\n    /// <summary>\n    /// Get a key value pair from a key\n    /// </summary>\n    public Option<(K Key, V Value)> GetOption(K key)\n    {\n        var (found, nkey, value) = FindInternal(key);\n        return found\n                   ? Some((nkey, value!))\n                   : default;\n    }\n\n    /// <summary>\n    /// Get a key value pair from a key\n    /// </summary>\n    public Option<K> GetKeyOption(K key)\n    {\n        var (found, nkey, _) = FindInternal(key);\n        return found\n                   ? Some(nkey)\n                   : default;\n    }\n\n    /// <summary>\n    /// Create an empty map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Create an empty map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>>) ClearWithLog() =>\n        (Empty, Map(Change<V>.Removed));\n\n    /// <summary>\n    /// Get the hash code of the items in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        hash == 0\n            ? (hash = FNV32.Hash<HashablePair<EqK, HashableDefault<V>, K, V>, (K, V)>(AsIterable()))\n            : hash;\n\n    /// <summary>\n    /// Returns the whether the `key` exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ContainsKey(K key) =>\n        FindInternal(key).Found;\n\n    /// <summary>\n    /// Returns the whether the `value` exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(V value) =>\n        Contains<EqDefault<V>>(value);\n\n    /// <summary>\n    /// Returns the whether the `value` exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains<EqV>(V value) where EqV: Eq<V> =>\n        Values.Exists(v => EqV.Equals(v, value));\n\n    /// <summary>\n    /// Returns the whether the `key` exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains(K key, V value) =>\n        Contains<EqDefault<V>>(key, value);\n\n    /// <summary>\n    /// Returns the whether the `key` exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Contains<EqV>(K key, V Value) where EqV : Eq<V> =>\n        Find(key).Map(v => EqV.Equals(v, Value)).IfNone(false);\n\n    /// <summary>\n    /// Returns the value associated with `key`.  Or None, if no key exists\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<V> Find(K key)\n    {\n        var (found, _, value) = FindInternal(key);\n        return found\n                   ? Some(value!)\n                   : default;\n    }\n\n    /// <summary>\n    /// Returns the value associated with `key`.  Or None, if no key exists\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    (bool Found, K Key, V? Value) FindInternal(K key)\n    {\n        var h       = (uint)EqK.GetHashCode(key);\n        Sec section = default;\n        return Root.Read(key, h, section);\n    }\n\n    /// <summary>\n    /// Returns the value associated with `key` then match the result\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public R Find<R>(K key, Func<V, R> Some, Func<R> None)\n    {\n        var (found, _, value) = FindInternal(key);\n        return found\n                   ? Some(value!)\n                   : None();\n    }\n\n    /// <summary>\n    /// Tries to find the value, if not adds it and returns the update map and/or value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, V Value) FindOrAdd(K key, Func<V> None) =>\n        Find(key, Some: v => (this, v), None: () =>\n                                              {\n                                                  var v = None();\n                                                  return (Add(key, v), v);\n                                              });\n\n    /// <summary>\n    /// Tries to find the value, if not adds it and returns the update map and/or value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, V Value, Change<V> Change) FindOrAddWithLog(K key, Func<V> None)\n    {\n        var item = Find(key);\n        if (item.IsSome)\n        {\n            return (this, item.Value!, Change<V>.None);\n        }\n        else\n        {\n            var v    = None();\n            var self = AddWithLog(key, v);\n            return (self.Map, v, self.Change);\n        }\n    }\n\n    /// <summary>\n    /// Tries to find the value, if not adds it and returns the update map and/or value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, V Value) FindOrAdd(K key, V value) =>\n        Find(key, Some: v => (this, v), None: () => (Add(key, value), value));\n\n    /// <summary>\n    /// Tries to find the value, if not adds it and returns the update map and/or value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, V Value, Change<V> Change) FindOrAddWithLog(K key, V value)\n    {\n        var item = Find(key);\n        if (item.IsSome)\n        {\n            return (this, item.Value!, Change<V>.None);\n        }\n        else\n        {\n            var self = AddWithLog(key, value);\n            return (self.Map, value, self.Change);\n        }\n    }   \n        \n    /// <summary>\n    /// Tries to find the value, if not adds it and returns the update map and/or value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Func<Option<V>> None) =>\n        Find(key, Some: v => (this, v), None: () =>\n                                              {\n                                                  var v = None();\n                                                  return v.IsSome\n                                                             ? (Add(key, (V)v), v)\n                                                             : (this, v);\n                                              });\n\n    /// <summary>\n    /// Tries to find the value, if not adds it and returns the update map and/or value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, V Value, Change<V> Change) FindOrMaybeAddWithLog(K key, Func<Option<V>> None)\n    {\n        var item = Find(key);\n        if (item.IsSome)\n        {\n            return (this, item.Value!, Change<V>.None);\n        }\n        else\n        {\n            var v = None();\n            if (v.IsSome)\n            {\n                var self = AddWithLog(key, v.Value!);\n                return (self.Map, v.Value!, self.Change);\n            }\n            else\n            {\n                return (this, item.Value!, Change<V>.None);\n            }\n        }\n    }        \n\n    /// <summary>\n    /// Tries to find the value, if not adds it and returns the update map and/or value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Option<V> Value) FindOrMaybeAdd(K key, Option<V> value) =>\n        Find(key, Some: v => (this, v), None: () =>\n                                                  value.IsSome\n                                                      ? (Add(key, (V)value), value)\n                                                      : (this, value));\n\n    /// <summary>\n    /// Tries to find the value, if not adds it and returns the update map and/or value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Option<V> Value, Change<V> Change) FindOrMaybeAddWithLog(K key, Option<V> value)\n    {\n        var item = Find(key);\n        if (item.IsSome)\n        {\n            return (this, item.Value, Change<V>.None);\n        }\n        else\n        {\n            if (value.IsSome)\n            {\n                var self = AddWithLog(key, value.Value!);\n                return (self.Map, value.Value, self.Change);\n            }\n            else\n            {\n                return (this, item.Value, Change<V>.None);\n            }\n        }\n    }  \n        \n    /// <summary>\n    /// Returns the value associated with `key`.  Or None, if no key exists\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<V> FindAll(K key) =>\n        Find(key).ToSeq();\n\n    internal static TrieMap<EqK, K, Change<V>> FindChanges(TrieMap<EqK, K, V> mx, TrieMap<EqK, K, V> my)\n    {\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n\n        foreach (var x in mx)\n        {\n            var y = my.Find(x.Key);\n            if (y.IsSome)\n            {\n                if (!ReferenceEquals(x.Value, y.Value) ||\n                    !EqDefault<V>.Equals(x.Value, y.Value!)\n                   )\n                {\n                    if (!EqDefault<V>.Equals(x.Value, y.Value!))\n                    {\n                        changes = changes.AddOrUpdateInPlace(x.Key, Change<V>.Mapped(x.Value, y.Value!));\n                    }\n                }\n            }\n            else\n            {\n                changes = changes.AddOrUpdateInPlace(x.Key, Change<V>.Removed(x.Value));\n            }\n        }\n\n        foreach (var y in my)\n        {\n            var x = mx.Find(y.Key);\n            if (x.IsNone)\n            {\n                changes = changes.AddOrUpdateInPlace(y.Key, Change<V>.Added(y.Value));\n            }\n        }\n\n        return changes;\n    }\n\n    /// <summary>\n    /// Map from V to U\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, U> Map<U>(Func<V, U> f) =>\n        new (AsIterable().Select(kv => (kv.Key, f(kv.Value))), false);\n\n    /// <summary>\n    /// Map from V to U\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, U> Map, TrieMap<EqK, K, Change<U>> Changes) MapWithLog<U>(Func<V, U> f)\n    {\n        var target  = TrieMap<EqK, K, U>.EmptyForMutating;\n        var changes = TrieMap<EqK, K, Change<U>>.EmptyForMutating;\n            \n        foreach (var pair in this)\n        {\n            var newv = f(pair.Value);\n            target = target.AddOrUpdateInPlace(pair.Key, newv);\n            changes = changes.AddOrUpdateInPlace(pair.Key, new EntryMapped<V, U>(pair.Value, newv));\n        }\n        return (target, changes);\n    }\n\n    /// <summary>\n    /// Map from V to U\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, U> Map<U>(Func<K, V, U> f) =>\n        new (AsIterable().Select(kv => (kv.Key, f(kv.Key, kv.Value))), false);\n\n    /// <summary>\n    /// Map from V to U\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, U> Map, TrieMap<EqK, K, Change<U>> Changes) MapWithLog<U>(Func<K, V, U> f)\n    {\n        var target  = TrieMap<EqK, K, U>.EmptyForMutating;\n        var changes = TrieMap<EqK, K, Change<U>>.EmptyForMutating;\n            \n        foreach (var pair in this)\n        {\n            var newv = f(pair.Key, pair.Value);\n            target = target.AddOrUpdateInPlace(pair.Key, newv);\n            changes = changes.AddOrUpdateInPlace(pair.Key, new EntryMapped<V, U>(pair.Value, newv));\n        }\n        return (target, changes);\n    }\n\n    /// <summary>\n    /// Filter\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Filter(Func<V, bool> f) =>\n        new (AsIterable().Filter(kv => f(kv.Value)), false);\n\n    /// <summary>\n    /// Map from V to U\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) FilterWithLog(Func<V, bool> f)\n    {\n        var target  = EmptyForMutating;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n            \n        foreach (var pair in this)\n        {\n            var pred = f(pair.Value);\n            if (pred)\n            {\n                target = target.AddOrUpdateInPlace(pair.Key, pair.Value);\n            }\n            else\n            {\n                changes = changes.AddOrUpdateInPlace(pair.Key, Change<V>.Removed(pair.Value));\n            }\n        }\n        return (target, changes);\n    }\n        \n    /// <summary>\n    /// Filter\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Filter(Func<K, V, bool> f) =>\n        new (AsIterable().Filter(kv => f(kv.Key, kv.Value)), false);\n\n    /// <summary>\n    /// Map from V to U\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) FilterWithLog(Func<K, V, bool> f)\n    {\n        var target  = EmptyForMutating;\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n            \n        foreach (var pair in this)\n        {\n            var pred = f(pair.Key, pair.Value);\n            if (pred)\n            {\n                target = target.AddOrUpdateInPlace(pair.Key, pair.Value);\n            }\n            else\n            {\n                changes = changes.AddOrUpdateInPlace(pair.Key, Change<V>.Removed(pair.Value));\n            }\n        }\n        return (target, changes);\n    }\n\n    /// <summary>\n    /// Associative union\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Append(TrieMap<EqK, K, V> rhs) =>\n        TryAddRange(rhs.AsIterable());\n\n    /// <summary>\n    /// Associative union\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) AppendWithLog(TrieMap<EqK, K, V> rhs) =>\n        TryAddRangeWithLog(rhs.AsIterable());\n\n    /// <summary>\n    /// Subtract\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Subtract(TrieMap<EqK, K, V> rhs)\n    {\n        var lhs = this;\n        foreach (var item in rhs.Keys)\n        {\n            lhs = lhs.Remove(item);\n        }\n        return lhs;\n    }\n\n    /// <summary>\n    /// Subtract\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) SubtractWithLog(TrieMap<EqK, K, V> rhs)\n    {\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        var lhs     = this;\n        foreach (var item in rhs.Keys)\n        {\n            var pair = lhs.RemoveWithLog(item);\n            lhs = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item, pair.Change);\n            }\n        }\n        return (lhs, changes);\n    }\n\n    /// <summary>\n    /// Union\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static TrieMap<EqK, K, V> operator +(TrieMap<EqK, K, V> lhs, TrieMap<EqK, K, V> rhs) =>\n        lhs.Append(rhs);\n\n    /// <summary>\n    /// Subtract\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static TrieMap<EqK, K, V> operator -(TrieMap<EqK, K, V> lhs, TrieMap<EqK, K, V> rhs) =>\n        lhs.Subtract(rhs);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(TrieMap<EqK, K, V> lhs, TrieMap<EqK, K, V> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Non equality\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(TrieMap<EqK, K, V> lhs, TrieMap<EqK, K, V> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? rhs) =>\n        rhs is TrieMap<EqK, K, V> map && Equals<EqDefault<V>>(map);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(TrieMap<EqK, K, V>? rhs) =>\n        rhs is not null && Equals<EqDefault<V>>(rhs);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    public bool Equals<EqV>(TrieMap<EqK, K, V>? rhs)\n        where EqV : Eq<V>\n    {\n        if (ReferenceEquals(this, rhs)) return true;\n        if (ReferenceEquals(rhs, null)) return false;\n        if (Count != rhs.Count) return false;\n        using var iterA = GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            if (!EqK.Equals(iterA.Current.Key, iterB.Current.Key)) return false;\n        }\n        using var iterA1 = GetEnumerator();\n        using var iterB1 = rhs.GetEnumerator();\n        while (iterA1.MoveNext() && iterB1.MoveNext())\n        {\n            if (!EqV.Equals(iterA1.Current.Value, iterB1.Current.Value)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Update an item in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Update(K key, V value) =>\n        Update(key, value, UpdateType.Add, false);\n\n    /// <summary>\n    /// Update an item in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, Change<V> Change) UpdateWithLog(K key, V value) =>\n        UpdateWithLog(key, value, UpdateType.Add, false);\n        \n    /// <summary>\n    /// Update an item in the map - can mutate if needed\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    TrieMap<EqK, K, V> Update(K key, V value, UpdateType type, bool mutate)\n    {\n        var h       = (uint)EqK.GetHashCode(key);\n        Sec section = default;\n        var (countDelta, newRoot, _, changed) = Root.Update((type, mutate), (key, value), h, section);\n        return countDelta != 0 || changed\n                   ? new TrieMap<EqK, K, V>(newRoot, count + countDelta)\n                   : this;\n    }\n\n    /// <summary>\n    /// Update an item in the map - can mutate if needed\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    (TrieMap<EqK, K, V> Map, Change<V> Change) UpdateWithLog(K key, V value, UpdateType type, bool mutate)\n    {\n        var h       = (uint)EqK.GetHashCode(key);\n        Sec section = default;\n        var (countDelta, newRoot, oldV, changed) = Root.Update((type, mutate), (key, value), h, section);\n        return changed\n                   ? (new TrieMap<EqK, K, V>(newRoot, count + countDelta), \n                      countDelta == 0 \n                          ? EqDefault<V>.Equals(oldV!, value)\n                                ? Change<V>.None \n                                : Change<V>.Mapped(oldV, value)\n                          : Change<V>.Added(value))\n                   : (this, Change<V>.None);\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    public bool IsProperSubsetOf(IEnumerable<(K Key, V Value)> other) =>\n        IsProperSubsetOf(other.Select(x => x.Key));\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    public bool IsProperSubsetOf(IEnumerable<K> other)\n    {\n        if (IsEmpty)\n        {\n            return other.Any();\n        }\n\n        var matches    = 0;\n        var extraFound = false;\n        foreach (var item in other)\n        {\n            if (ContainsKey(item))\n            {\n                matches++;\n            }\n            else\n            {\n                extraFound = true;\n            }\n\n            if (matches == Count && extraFound)\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    public bool IsProperSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        IsProperSupersetOf(other.Select(x => x.Key));\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    public bool IsProperSupersetOf(IEnumerable<K> other)\n    {\n        if (IsEmpty)\n        {\n            return false;\n        }\n\n        var matchCount = 0;\n        foreach (var item in other)\n        {\n            matchCount++;\n            if (!ContainsKey(item))\n            {\n                return false;\n            }\n        }\n\n        return Count > matchCount;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    public bool IsSubsetOf(IEnumerable<(K Key, V Value)> other)\n    {\n        if (IsEmpty)\n        {\n            return true;\n        }\n\n        var matches = 0;\n        foreach (var item in other)\n        {\n            if (ContainsKey(item.Key))\n            {\n                matches++;\n            }\n        }\n        return matches == Count;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    public bool IsSubsetOf(IEnumerable<K> other)\n    {\n        if (IsEmpty)\n        {\n            return true;\n        }\n\n        var matches = 0;\n        foreach (var item in other)\n        {\n            if (ContainsKey(item))\n            {\n                matches++;\n            }\n        }\n        return matches == Count;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    public bool IsSubsetOf(TrieMap<EqK, K, V> other)\n    {\n        if (IsEmpty)\n        {\n            // All empty sets are subsets\n            return true;\n        }\n        if(Count > other.Count)\n        {\n            // A subset must be smaller or equal in size\n            return false;\n        }\n\n        foreach(var item in this)\n        {\n            if(!other.Contains(item))\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    public bool IsSupersetOf(IEnumerable<(K Key, V Value)> other) =>\n        IsSupersetOf(other.Select(x => x.Key));\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    public bool IsSupersetOf(IEnumerable<K> other)\n    {\n        foreach (var item in other)\n        {\n            if (!ContainsKey(item))\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    public bool Overlaps(IEnumerable<(K Key, V Value)> other) =>\n        Overlaps(other.Select(x => x.Key));\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    public bool Overlaps(IEnumerable<K> other)\n    {\n        if (IsEmpty)\n        {\n            return false;\n        }\n\n        foreach (var item in other)\n        {\n            if (ContainsKey(item))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public TrieMap<EqK, K, V> Intersect(IEnumerable<K> other)\n    {\n        var res = new List<(K, V)>();\n        foreach (var item in other)\n        {\n            var litem = GetOption(item);\n            if (litem.IsSome) res.Add(((K, V))litem);\n        }\n        return new TrieMap<EqK, K, V>(res);\n    }\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) IntersectWithLog(IEnumerable<K> other)\n    {\n        var set     = new TrieSet<EqK, K>(other);\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        var res     = EmptyForMutating;\n            \n        foreach (var item in this)\n        {\n            if (set.Contains(item.Key))\n            {\n                res = res.AddOrUpdateInPlace(item.Key, item.Value);\n            }\n            else\n            {\n                changes = changes.AddOrUpdateInPlace(item.Key, Change<V>.Removed(item.Value));\n            }\n        }\n        return (res, changes);\n    }\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public TrieMap<EqK, K, V> Intersect(IEnumerable<(K Key, V Value)> other)\n    {\n        var res = new List<(K, V)>();\n        foreach (var item in other)\n        {\n            var litem = GetOption(item.Key);\n            if (litem.IsSome) res.Add(((K, V))litem);\n        }\n        return new TrieMap<EqK, K, V>(res);\n    }\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) IntersectWithLog(\n        IEnumerable<(K Key, V Value)> other) =>\n        IntersectWithLog(other.Select(pair => pair.Key));\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public TrieMap<EqK, K, V> Intersect(\n        IEnumerable<(K Key, V Value)> other,\n        WhenMatched<K, V, V, V> Merge)\n    {\n        var t = EmptyForMutating;\n        foreach (var py in other)\n        {\n            var px = Find(py.Key);\n            if (px.IsSome)\n            {\n                var r = Merge(py.Key, px.Value!, py.Value);\n                t = t.AddOrUpdateInPlace(py.Key, r);\n            }\n        }\n        return t;\n    }\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) IntersectWithLog(\n        TrieMap<EqK, K, V> other,\n        WhenMatched<K, V, V, V> Merge)\n    {\n        var t = EmptyForMutating;\n        var c = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        foreach (var px in this)\n        {\n            var py = other.Find(px.Key);\n            if (py.IsSome)\n            {\n                var r = Merge(px.Key, px.Value, py.Value!);\n                t = t.AddOrUpdateInPlace(px.Key, r);\n                if (!EqDefault<V>.Equals(px.Value, r))\n                {\n                    c = c.AddOrUpdateInPlace(px.Key, Change<V>.Mapped(px.Value, r));\n                }\n            }\n            else\n            {\n                c = c.AddOrUpdateInPlace(px.Key, Change<V>.Removed(px.Value));\n            }\n        }\n\n        return (t, c);\n    }\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    public TrieMap<EqK, K, V> Except(IEnumerable<K> other)\n    {\n        var self = this;\n        foreach (var item in other)\n        {\n            self = self.Remove(item);\n        }\n        return self;\n    }\n        \n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) ExceptWithLog(IEnumerable<K> other)\n    {\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        var self    = this;\n            \n        foreach (var item in other)\n        {\n            var pair = self.RemoveWithLog(item);\n            self = pair.Map;\n            if (pair.Change.HasChanged)\n            {\n                changes = changes.AddOrUpdateInPlace(item, pair.Change);\n            }\n        }\n        return (self, changes);\n    }        \n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    public TrieMap<EqK, K, V> Except(IEnumerable<(K Key, V Value)> other)\n    {\n        var self = this;\n        foreach (var item in other)\n        {\n            self = self.Remove(item.Key);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) ExceptWithLog(\n        IEnumerable<(K Key, V Value)> other) =>\n        ExceptWithLog(other.Select(p => p.Key));\n \n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public TrieMap<EqK, K, V> SymmetricExcept(TrieMap<EqK, K, V> rhs)\n    {\n        var self = this;\n            \n        foreach (var item in rhs)\n        {\n            var pair = self.RemoveWithLog(item.Key);\n            if (pair.Change.HasNoChange)\n            {\n                self = self.Add(item.Key, item.Value);\n            }\n        }\n        return self;\n    }        \n        \n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) SymmetricExceptWithLog(TrieMap<EqK, K, V> rhs)\n    {\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        var self    = this;\n            \n        foreach (var item in rhs)\n        {\n            var pair = self.RemoveWithLog(item.Key);\n            if (pair.Change.HasNoChange)\n            {\n                self = self.Add(item.Key, item.Value);\n                changes = changes.AddOrUpdateInPlace(item.Key, Change<V>.Added(item.Value));\n            }\n        }\n        return (self, changes);\n    }        \n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public TrieMap<EqK, K, V> SymmetricExcept(IEnumerable<(K Key, V Value)> rhs)\n    {\n        var self = this;\n            \n        foreach (var item in rhs)\n        {\n            var pair = self.RemoveWithLog(item.Key);\n            if (pair.Change.HasNoChange)\n            {\n                self = self.Add(item.Key, item.Value);\n            }\n            else\n            {\n                self = pair.Map;\n            }\n        }\n        return self;\n    }\n        \n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) SymmetricExceptWithLog(IEnumerable<(K Key, V Value)> rhs)\n    {\n        var changes = TrieMap<EqK, K, Change<V>>.EmptyForMutating;\n        var self    = this;\n            \n        foreach (var item in rhs)\n        {\n            var pair = self.RemoveWithLog(item.Key);\n            if (pair.Change.HasNoChange)\n            {\n                self = self.Add(item.Key, item.Value);\n                changes = changes.AddOrUpdateInPlace(item.Key, Change<V>.Added(item.Value));\n            }\n            else\n            {\n                self = pair.Map;\n                changes = changes.AddOrUpdateInPlace(item.Key, pair.Change);\n            }\n        }\n        return (self, changes);\n    }\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    public TrieMap<EqK, K, V> Union(IEnumerable<(K, V)> other) =>\n        TryAddRange(other);\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) UnionWithLog(IEnumerable<(K, V)> other) =>\n        TryAddRangeWithLog(other);\n        \n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieMap<EqK, K, V> Union(\n        IEnumerable<(K Key, V Value)> other,\n        WhenMatched<K, V, V, V> Merge) =>\n        Union(other, MapLeft: static (_, v) => v, MapRight: static (_, v) => v, Merge);\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) UnionWithLog(\n        IEnumerable<(K Key, V Value)> other,\n        WhenMatched<K, V, V, V> Merge) =>\n        UnionWithLog(other, MapLeft: static (_, v) => v, MapRight: static (_, v) => v, Merge);\n        \n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the right-hand side, but not the left-hand-side.\n    /// This allows the `V2` value-type to be mapped to the target `V` value-type. \n    /// </remarks>\n    public TrieMap<EqK, K, V> Union<W>(\n        IEnumerable<(K Key, W Value)> other,\n        WhenMissing<K, W, V> MapRight, \n        WhenMatched<K, V, W, V> Merge) =>\n        Union(other, MapLeft: static (_, v) => v, MapRight, Merge);\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the right-hand side, but not the left-hand-side.\n    /// This allows the `V2` value-type to be mapped to the target `V` value-type. \n    /// </remarks>\n    public (TrieMap<EqK, K, V> Map, TrieMap<EqK, K, Change<V>> Changes) UnionWithLog<W>(\n        IEnumerable<(K Key, W Value)> other, \n        WhenMissing<K, W, V> MapRight, \n        WhenMatched<K, V, W, V> Merge) =>\n        UnionWithLog(other, MapLeft: static (_, v) => v, MapRight, Merge);\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the left-hand side, but not the right-hand-side.\n    /// This allows the `V` value-type to be mapped to the target `V2` value-type. \n    /// </remarks>\n    public TrieMap<EqK, K, W> Union<W>(\n        IEnumerable<(K Key, W Value)> other,\n        WhenMissing<K, V, W> MapLeft, \n        WhenMatched<K, V, W, W> Merge) =>\n        Union(other, MapLeft, MapRight: static (_, v2) => v2, Merge);\n\n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing` function is called when there is a key in the left-hand side, but not the right-hand-side.\n    /// This allows the `V` value-type to be mapped to the target `V2` value-type. \n    /// </remarks>\n    public (TrieMap<EqK, K, W> Map, TrieMap<EqK, K, Change<W>> Changes) UnionWithLog<W>(\n        IEnumerable<(K Key, W Value)> other,\n        WhenMissing<K, V, W> MapLeft,\n        WhenMatched<K, V, W, W> Merge) =>\n        UnionWithLog(other, MapLeft, MapRight: static (_, v2) => v2, Merge);\n        \n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing MapLeft` function is called when there is a key in the left-hand side, but not the\n    /// right-hand-side.   This allows the `V` value-type to be mapped to the target `R` value-type. \n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing MapRight` function is called when there is a key in the right-hand side, but not the\n    /// left-hand-side.   This allows the `V2` value-type to be mapped to the target `R` value-type. \n    /// </remarks>\n    public TrieMap<EqK, K, R> Union<W, R>(\n        IEnumerable<(K Key, W Value)> other, \n        WhenMissing<K, V, R> MapLeft, \n        WhenMissing<K, W, R> MapRight, \n        WhenMatched<K, V, W, R> Merge)\n    {\n        var t = TrieMap<EqK, K, R>.EmptyForMutating;\n        foreach(var (key, value) in other)\n        {\n            var px = Find(key);\n            t = t.AddOrUpdateInPlace(key, px.IsSome \n                                              ? Merge(key, px.Value!, value) \n                                              : MapRight(key, value));\n        }\n\n        foreach (var (key, value) in this)\n        {\n            if (t.ContainsKey(key)) continue;\n            t = t.AddOrUpdateInPlace(key, MapLeft(key, value));\n        }\n\n        return t;\n    }\n        \n    /// <summary>\n    /// Union two maps.  \n    /// </summary>\n    /// <remarks>\n    /// The `WhenMatched` merge function is called when keys are present in both map to allow resolving to a\n    /// sensible value.\n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing MapLeft` function is called when there is a key in the left-hand side, but not the\n    /// right-hand-side.   This allows the `V` value-type to be mapped to the target `R` value-type. \n    /// </remarks>\n    /// <remarks>\n    /// The `WhenMissing MapRight` function is called when there is a key in the right-hand side, but not the\n    /// left-hand-side.   This allows the `V2` value-type to be mapped to the target `R` value-type. \n    /// </remarks>\n    public (TrieMap<EqK, K, R> Map, TrieMap<EqK, K, Change<R>> Changes) UnionWithLog<W, R>(\n        IEnumerable<(K Key, W Value)> other, \n        WhenMissing<K, V, R> MapLeft,\n        WhenMissing<K, W, R> MapRight, \n        WhenMatched<K, V, W, R> Merge)\n    {\n        var t = TrieMap<EqK, K, R>.EmptyForMutating;\n        var c = TrieMap<EqK, K, Change<R>>.EmptyForMutating;\n        foreach(var (key, value) in other)\n        {\n            var px = Find(key);\n            if (px.IsSome)\n            {\n                var r = Merge(key, px.Value!, value);\n                t = t.AddOrUpdateInPlace(key, r);\n                if (!EqDefault<V, W>.Equals(px.Value, r))\n                {\n                    c = c.AddOrUpdateInPlace(key, Change<R>.Mapped(px.Value, r));\n                }\n            }\n            else\n            {\n                var r = MapRight(key, value);\n                t = t.AddOrUpdateInPlace(key, r);\n                c = c.AddOrUpdateInPlace(key, Change<R>.Added(r));\n            }\n        }\n\n        foreach (var (key, value) in this)\n        {\n            if (t.ContainsKey(key)) continue;\n                \n            var r = MapLeft(key, value);\n            t = t.AddOrUpdateInPlace(key, r);\n            if (!EqDefault<V, W>.Equals(value, r))\n            {\n                c = c.AddOrUpdateInPlace(key, Change<R>.Mapped(value, r));\n            }\n        }\n\n        return (t, c);\n    }\n        \n    /// <summary>\n    /// Nodes in the CHAMP hash trie map can be in one of three states:\n    /// \n    ///     Empty - nothing in the map\n    ///     Entries - contains items and sub-nodes\n    ///     Collision - keeps track of items that have different keys but the same hash\n    /// \n    /// </summary>\n    internal interface Node : IEnumerable<(K, V)>\n    {\n        Tag Type { get; }\n        (bool Found, K Key, V? Value) Read(K key, uint hash, Sec section);\n        (int CountDelta, Node Node, V? Old, bool Changed) Update((UpdateType Type, bool Mutate) env, (K Key, V Value) change, uint hash, Sec section);\n        (int CountDelta, Node Node, V? Old) Remove(K key, uint hash, Sec section);\n    }\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // NOTE: Here be dragons!  The code below is has been optimised for performace.  Yes, it's \n    //       ugly, yes there's repetition, but it's all to squeeze the last few nanoseconds of \n    //       performance out of the system.  Don't hate me ;)\n    //\n\n    /// <summary>\n    /// Contains items and sub-nodes\n    /// </summary>\n    internal class Entries : Node\n    {\n        public readonly uint EntryMap;\n        public readonly uint NodeMap;\n        public readonly (K Key, V Value)[] Items;\n        public readonly Node[] Nodes;\n\n        public Tag Type => Tag.Entries;\n\n        public Entries(uint entryMap, uint nodeMap, (K, V)[] items, Node[] nodes)\n        {\n            EntryMap = entryMap;\n            NodeMap = nodeMap;\n            Items = items;\n            Nodes = nodes;\n        }\n\n        public void Deconstruct(out uint entryMap, out uint nodeMap, out (K, V)[] items, out Node[] nodes)\n        {\n            entryMap = EntryMap;\n            nodeMap = NodeMap;\n            items = Items;\n            nodes = Nodes;\n        }\n\n        public (int CountDelta, Node Node, V? Old) Remove(K key, uint hash, Sec section)\n        {\n            var hashIndex = Bit.Get(hash, section);\n            var mask      = Mask(hashIndex);\n\n            if (Bit.Get(EntryMap, mask))\n            {\n                // If key belongs to an entry\n                var ind = Index(EntryMap, mask);\n                if (EqK.Equals(Items[ind].Key, key))\n                {\n                    var v = Items[ind].Value;\n                    return (-1, \n                            new Entries(\n                                Bit.Set(EntryMap, mask, false), \n                                NodeMap,\n                                RemoveAt(Items, ind), \n                                Nodes),\n                            v\n                           );\n                }\n                else\n                {\n                    return (0, this, default);\n                }\n            }\n            else if (Bit.Get(NodeMap, mask))\n            {\n                //If key lies in a sub-node\n                var ind = Index(NodeMap, mask);\n                var (cd, subNode, v) = Nodes[ind].Remove(key, hash, section.Next());\n                if (cd == 0) return (0, this, default);\n\n                switch (subNode.Type)\n                {\n                    case Tag.Entries:\n\n                        var subEntries = (Entries)subNode;\n\n                        if (subEntries.Items.Length == 1 && subEntries.Nodes.Length == 0)\n                        {\n                            // If the node only has one subnode, make that subnode the new node\n                            if (Items.Length == 0 && Nodes.Length == 1)\n                            {\n                                // Build a new Entries for this level with the sublevel mask fixed\n                                return (cd, new Entries(\n                                            Mask(Bit.Get((uint)EqK.GetHashCode(subEntries.Items[0].Key),\n                                                         section)),\n                                            0,\n                                            Clone(subEntries.Items),\n                                            Array.Empty<Node>()\n                                        ),\n                                        v);\n                            }\n                            else\n                            {\n                                return (cd,\n                                        new Entries(\n                                            Bit.Set(EntryMap, mask, true),\n                                            Bit.Set(NodeMap, mask, false),\n                                            Insert(Items, Index(EntryMap, mask), subEntries.Items[0]),\n                                            RemoveAt(Nodes, ind)),\n                                        v);\n                            }\n                        }\n                        else\n                        {\n                            var nodeCopy = Clone(Nodes);\n                            nodeCopy[ind] = subNode;\n                            return (cd, new Entries(EntryMap, NodeMap, Items, nodeCopy), v);\n                        }\n\n                    case Tag.Collision:\n                        var nodeCopy2 = Clone(Nodes);\n                        nodeCopy2[ind] = subNode;\n                        return (cd, new Entries(EntryMap, NodeMap, Items, nodeCopy2), v);\n\n                    default:\n                        return (0, this, default);\n                }\n            }\n            else\n            {\n                return (0, this, default);\n            }\n        }\n\n        public (bool Found, K Key, V? Value) Read(K key, uint hash, Sec section)\n        {                                                                                         \n            // var hashIndex = Bit.Get(hash, section);\n            // Mask(hashIndex)\n            var mask = (uint)(1 << (int)((hash & (uint)(Sec.Mask << section.Offset)) >> section.Offset));\n\n            // if(Bit.Get(EntryMap, mask))\n            if ((EntryMap & mask) == mask)                                                        \n            {\n                // var entryIndex = Index(EntryMap, mask);\n                var entryIndex = BitCount((int)EntryMap & (((int)mask) - 1));                     \n                if (EqK.Equals(Items[entryIndex].Key, key))\n                {\n                    var item = Items[entryIndex];\n                    return (true, item.Key, item.Value);\n                }\n                else\n                {\n                    return default;\n                }\n            }\n            // else if (Bit.Get(NodeMap, mask))\n            else if ((NodeMap & mask) == mask)                                                   \n            {\n                // var entryIndex = Index(NodeMap, mask);\n                var entryIndex = BitCount((int)NodeMap & ((int)mask - 1));                     \n                return Nodes[entryIndex].Read(key, hash, section.Next());\n            }\n            else\n            {\n                return default;\n            }\n        }\n\n        public (int CountDelta, Node Node, V? Old, bool Changed) Update((UpdateType Type, bool Mutate) env, (K Key, V Value) change, uint hash, Sec section)\n        {\n            // var hashIndex = Bit.Get(hash, section);\n            // var mask = Mask(hashIndex);\n            var mask = (uint)(1 << (int)((hash & (uint)(Sec.Mask << section.Offset)) >> section.Offset));\n\n            //if (Bit.Get(EntryMap, mask))\n            if((EntryMap & mask) == mask)\n            {\n                //var entryIndex = Index(EntryMap, mask);\n                var entryIndex   = BitCount((int)EntryMap & ((int)mask - 1));\n                var currentEntry = Items[entryIndex];\n\n                if (EqK.Equals(currentEntry.Key, change.Key))\n                {\n                    if (env.Type == UpdateType.Add)\n                    {\n                        // Key already exists - so it's an error to add again\n                        throw new ArgumentException($\"Key already exists in map: {change.Key}\");\n                    }\n                    else if (env.Type == UpdateType.TryAdd)\n                    {\n                        // Already added, so we don't continue to try\n                        return (0, this, default, false);\n                    }\n\n                    var (newItems, old) = SetItem(Items, entryIndex, change, env.Mutate);\n                    return (0, new Entries(EntryMap, NodeMap, newItems, Nodes), old.Value, true);\n                }\n                else\n                {\n                    if (env.Type == UpdateType.SetItem)\n                    {\n                        // Key must already exist to set it\n                        throw new ArgumentException($\"Key already exists in map: {change.Key}\");\n                    }\n                    else if (env.Type == UpdateType.TrySetItem)\n                    {\n                        // Key doesn't exist, so there's nothing to set\n                        return (0, this, default, false);\n                    }\n\n                    // Add\n                    var node = Merge(change, currentEntry, hash, (uint)EqK.GetHashCode(currentEntry.Key), section);\n\n                    //var newItems = Items.Filter(elem => !default(EqK).Equals(elem.Key, currentEntry.Key)).ToArray();\n                    var newItems = new (K Key, V Value)[Items.Length - 1];\n                    var i        = 0;\n                    foreach(var elem in Items)\n                    {\n                        if(!EqK.Equals(elem.Key, currentEntry.Key))\n                        {\n                            newItems[i] = elem;\n                            i++;\n                        }\n                    }\n\n                    //var newEntryMap = Bit.Set(EntryMap, mask, false);\n                    var newEntryMap = EntryMap & (~mask);\n\n                    // var newNodeMap = Bit.Set(NodeMap, mask, true);\n                    var newNodeMap = NodeMap | mask;\n\n                    // var nodeIndex = Index(NodeMap, mask);\n                    var nodeIndex = BitCount((int)NodeMap & ((int)mask - 1));\n\n                    var newNodes = Insert(Nodes, nodeIndex, node);\n\n                    return (1, new Entries(newEntryMap, newNodeMap, newItems, newNodes), default, true);\n                }\n            }\n            else if (Bit.Get(NodeMap, mask))\n            {\n                // var nodeIndex = Index(NodeMap, mask);\n                var nodeIndex = BitCount((int)NodeMap & ((int)mask - 1));\n\n                var nodeToUpdate = Nodes[nodeIndex];\n                var (cd, newNode, ov, ch) = nodeToUpdate.Update(env, change, hash, section.Next());\n                var (newNodes, _) = SetItem(Nodes, nodeIndex, newNode, env.Mutate);\n                return (cd, new Entries(EntryMap, NodeMap, Items, newNodes), ov, ch);\n            }\n            else\n            {\n                if (env.Type == UpdateType.SetItem)\n                {\n                    // Key must already exist to set it\n                    throw new ArgumentException($\"Key doesn't exist in map: {change.Key}\");\n                }\n                else if (env.Type == UpdateType.TrySetItem)\n                {\n                    // Key doesn't exist, so there's nothing to set\n                    return (0, this, default, false);\n                }\n\n                // var entryIndex = Index(EntryMap, mask);\n                var entryIndex = BitCount((int)EntryMap & ((int)mask - 1));\n\n                // var entries = Bit.Set(EntryMap, mask, true);\n                var entries = EntryMap | mask;\n\n                var newItems = Insert(Items, entryIndex, change);\n                return (1, new Entries(entries, NodeMap, newItems, Nodes), default, true);\n            }\n        }\n\n        public IEnumerator<(K, V)> GetEnumerator()\n        {\n            foreach (var item in Items)\n            {\n                yield return item;\n            }\n\n            foreach (var node in Nodes)\n            {\n                foreach (var item in node)\n                {\n                    yield return item;\n                }\n            }\n        }\n\n        IEnumerator IEnumerable.GetEnumerator() =>\n            GetEnumerator();\n    }\n\n    /// <summary>\n    /// Contains items that share the same hash but have different keys\n    /// </summary>\n    internal class Collision : Node\n    {\n        public readonly (K Key, V Value)[] Items;\n        public readonly uint Hash;\n\n        public Tag Type => Tag.Collision;\n\n        public Collision((K Key, V Value)[] items, uint hash)\n        {\n            Items = items;\n            Hash = hash;\n        }\n        \n        public (bool Found, K Key, V Value) Read(K key, uint hash, Sec section)\n        {\n            foreach (var kv in Items)\n            {\n                if (EqK.Equals(kv.Key, key))\n                {\n                    return (true, kv.Key, kv.Value);\n                }\n            }\n            return default;\n        }\n\n        public (int CountDelta, Node Node, V? Old) Remove(K key, uint hash, Sec section)\n        {\n            var len = Items.Length;\n            if (len      == 0) return (0, this, default);\n            else if (len == 1) return (-1, EmptyNode.Default, Items[0].Value);\n            else if (len == 2)\n            {\n                var ((_, n, _, _), ov) = EqK.Equals(Items[0].Key, key)\n                                          ? (EmptyNode.Default.Update((UpdateType.Add, false), Items[1], hash, default), Items[0].Value)\n                                          : (EmptyNode.Default.Update((UpdateType.Add, false), Items[0], hash, default), Items[1].Value);\n\n                return (-1, n, ov);\n            }\n            else\n            {\n                V? oldValue = default;\n                IEnumerable<(K, V)> Yield((K Key, V Value)[] items, K ikey)\n                {\n                    foreach (var item in items)\n                    {\n                        if (EqK.Equals(item.Key, ikey))\n                        {\n                            oldValue = item.Value;\n                        }\n                        else\n                        {\n                            yield return item;\n                        }\n                    }\n                }\n\n                var nitems = Yield(Items, key).ToArray();\n\n                return (nitems.Length - Items.Length, new Collision(nitems, hash), oldValue);\n            }\n        }\n\n        public (int CountDelta, Node Node, V? Old, bool Changed) Update((UpdateType Type, bool Mutate) env, (K Key, V Value) change, uint hash, Sec section)\n        {\n            var index = -1;\n            for (var i = 0; i < Items.Length; i++)\n            {\n                if (EqK.Equals(Items[i].Key, change.Key))\n                {\n                    index = i;\n                    break;\n                }\n            }\n\n            if (index >= 0)\n            {\n                if (env.Type == UpdateType.Add)\n                {\n                    // Key already exists - so it's an error to add again\n                    throw new ArgumentException($\"Key already exists in map: {change.Key}\");\n                }\n                else if (env.Type == UpdateType.TryAdd)\n                {\n                    // Already added, so we don't continue to try\n                    return (0, this, default, false);\n                }\n\n                var (newArr, ov) = SetItem(Items, index, change, false);\n                return (0, new Collision(newArr, hash), ov.Value, true);\n            }\n            else\n            {\n                if (env.Type == UpdateType.SetItem)\n                {\n                    // Key must already exist to set it\n                    throw new ArgumentException($\"Key doesn't exist in map: {change.Key}\");\n                }\n                else if (env.Type == UpdateType.TrySetItem)\n                {\n                    // Key doesn't exist, so there's nothing to set\n                    return (0, this, default, false);\n                }\n\n                var nitems = new (K, V)[Items.Length + 1];\n                Array.Copy(Items, nitems, Items.Length);\n                nitems[Items.Length] = change;\n                return (1, new Collision(nitems, hash), default, true);\n            }\n        }\n\n        public IEnumerator<(K, V)> GetEnumerator() =>\n            Items.AsEnumerable().GetEnumerator();\n\n        IEnumerator IEnumerable.GetEnumerator() =>\n            Items.AsEnumerable().GetEnumerator();\n    }\n\n    /// <summary>\n    /// Empty node\n    /// </summary>\n    internal class EmptyNode : Node\n    {\n        public static readonly EmptyNode Default = new EmptyNode();\n\n        public Tag Type => Tag.Empty;\n\n        public (bool Found, K Key, V Value) Read(K key, uint hash, Sec section) =>\n            default;\n\n        public (int CountDelta, Node Node, V? Old) Remove(K key, uint hash, Sec section) =>\n            (0, this, default);\n\n        public (int CountDelta, Node Node, V? Old, bool Changed) Update((UpdateType Type, bool Mutate) env, (K Key, V Value) change, uint hash, Sec section)\n        {\n            if (env.Type == UpdateType.SetItem)\n            {\n                // Key must already exist to set it\n                throw new ArgumentException($\"Key doesn't exist in map: {change.Key}\");\n            }\n            else if (env.Type == UpdateType.TrySetItem)\n            {\n                // Key doesn't exist, so there's nothing to set\n                return (0, this, default, false);\n            }\n\n            var dataMap = Mask(Bit.Get(hash, section));\n            return (1, new Entries(dataMap, 0, [change], []), default, true);\n        }\n\n        public IEnumerator<(K, V)> GetEnumerator()\n        {\n            yield break;\n        }\n\n        IEnumerator IEnumerable.GetEnumerator()\n        {\n            yield break;\n        }\n    }\n\n    /// <summary>\n    /// Merges two key-value pairs into a single Node\n    /// </summary>\n    static Node Merge((K, V) pair1, (K, V) pair2, uint pair1Hash, uint pair2Hash, Sec section)\n    {\n        if (section.Offset >= 25)\n        {\n            return new Collision([pair1, pair2], pair1Hash);\n        }\n        else\n        {\n            var nextLevel  = section.Next();\n            var pair1Index = Bit.Get(pair1Hash, nextLevel);\n            var pair2Index = Bit.Get(pair2Hash, nextLevel);\n            if (pair1Index == pair2Index)\n            {\n                var node    = Merge(pair1, pair2, pair1Hash, pair2Hash, nextLevel);\n                var nodeMap = Mask(pair1Index);\n                return new Entries(0, nodeMap, Array.Empty<(K, V)>(), [node]);\n            }\n            else\n            {\n                var dataMap = Mask(pair1Index);\n                dataMap = Bit.Set(dataMap, Mask(pair2Index), true);\n                return new Entries(dataMap, 0, pair1Index < pair2Index\n                                                   ? [pair1, pair2]\n                                                   : [pair2, pair1], Array.Empty<Node>());\n            }\n        }\n    }\n\n    public Iterable<(K Key, V Value)> AsIterable() =>\n        Root.AsIterable();\n\n    public IEnumerator<(K Key, V Value)> GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Root.GetEnumerator();\n\n    IEnumerator IEnumerable.GetEnumerator() =>\n        // ReSharper disable once NotDisposedResourceIsReturned\n        Root.GetEnumerator();\n\n    /// <summary>\n    /// Counts the number of 1-bits in bitmap\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static int BitCount(int bits)\n    {\n        var c2 = bits - ((bits >> 1) & 0x55555555);\n        var c4 = (c2                 & 0x33333333) + ((c2 >> 2) & 0x33333333);\n        var c8 = (c4 + (c4                                >> 4)) & 0x0f0f0f0f;\n        return (c8 * 0x01010101) >> 24;\n    }\n\n    /// <summary>\n    /// Finds the number of set bits below the bit at `location`\n    /// This function is used to find where in the array of entries or nodes \n    /// the item should be inserted\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static int Index(uint bits, int location) =>\n        BitCount((int)bits & (location - 1));\n\n    /// <summary>\n    /// Finds the number of 1-bits below the bit at `location`\n    /// This function is used to find where in the array of entries or nodes \n    /// the item should be inserted\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static int Index(uint bitmap, uint location) =>\n        BitCount((int)bitmap & ((int)location - 1));\n\n    /// <summary>\n    /// Returns the value used to index into the bit vector\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static uint Mask(int index) =>\n        (uint)(1 << index);\n\n    /// <summary>\n    /// Sets the item at index. If mutate is true it sets the \n    /// value without copying the array, otherwise the operation is pure\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static (A[] Items, A Old) SetItem<A>(A[] items, int index, A value, bool mutate)\n    {\n        if (mutate)\n        {\n            var old = items[index]; \n            items[index] = value;\n            return (items, old);\n        }\n        else\n        {\n            var old    = items[index]; \n            var nitems = new A[items.Length];\n            Array.Copy(items, nitems, items.Length);\n            nitems[index] = value;\n            return (nitems, old);\n        }\n    }\n\n    /// <summary>\n    /// Clones part of an existing array\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] Clone<A>(A[] items, int count)\n    {\n        var nitems = new A[count];\n        Array.Copy(items, nitems, count);\n        return nitems;\n    }\n\n    /// <summary>\n    /// Clones an existing array\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] Clone<A>(A[] items)\n    {\n        var len    = items.Length;\n        var nitems = new A[len];\n        Array.Copy(items, nitems, len);\n        return nitems;\n    }\n\n    /// <summary>\n    /// Inserts a new item in the array (immutably)\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] Insert<A>(A[] array, int index, A value)\n    {\n        var narray = new A[array.Length + 1];\n        Array.Copy(array, 0, narray, 0, index);\n        Array.Copy(array, index, narray, index + 1, array.Length - index);\n        narray[index] = value;\n        return narray;\n    }\n\n    /// <summary>\n    /// Returns a new array with the item at index removed\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] RemoveAt<A>(A[] array, int index)\n    {\n        if (array.Length == 0)\n        {\n            return array;\n        }\n\n        var narray = new A[array.Length - 1];\n        if (index > 0)\n        {\n            Array.Copy(array, 0, narray, 0, index);\n        }\n        if (index + 1 < array.Length)\n        {\n            Array.Copy(array, index + 1, narray, index, array.Length - index - 1);\n        }\n        return narray;\n    }\n\n    public override string ToString() =>\n        count < 50\n            ? $\"[{ string.Join(\", \", AsIterable().Select(TupleToString)) }]\"\n            : $\"[{ string.Join(\", \", AsIterable().Select(TupleToString).Take(50)) } ... ]\";\n\n    string TupleToString((K Key, V Value) tuple) =>\n        $\"({tuple.Key}, {tuple.Value})\";\n\n    public Iterable<K> Keys =>\n        AsIterable().Map(kv => kv.Key);\n\n    public Iterable<V> Values =>\n        AsIterable().Map(kv => kv.Value);\n\n    public bool TryGetValue(K key, out V value)\n    {\n        var ov = Find(key);\n        if (ov.IsSome)\n        {\n            value = (V)ov;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n}\n\ninternal readonly struct Sec\n{\n    public const int Mask = 31;\n    public readonly int Offset;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Sec(int offset) =>\n        Offset = offset;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Sec Next() =>\n        new (Offset + 5);\n}\n\ninternal static class Bit\n{\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static uint Set(uint value, int bit, bool flag) =>\n        flag\n            ? value | (uint)bit\n            : value & ~(uint)bit;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static uint Set(uint value, uint bit, bool flag) =>\n        flag\n            ? value | bit\n            : value & ~bit;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool Get(uint value, int bit) =>\n        (value & (uint)bit) == (uint)bit;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool Get(uint value, uint bit) =>\n        (value & bit) == bit;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int Get(uint data, Sec section) =>\n        (int)((data & (uint)(Sec.Mask << section.Offset)) >> section.Offset);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static uint Set(uint data, Sec section, int value)\n    {\n        value <<= section.Offset;\n        var offsetMask = (0xFFFF & Sec.Mask) << section.Offset;\n        return data & ~(uint)offsetMask | (uint)value & (uint)offsetMask;\n    }\n}\n\ninternal static class TrieMapExtentsions\n{\n    public static TrieMap<EqK, K, V> Merge<EqK, K, V>(this TrieMap<EqK, K, V> lhs, TrieMap<EqK, K, V> rhs)\n        where EqK : Eq<K>\n        where V : Semigroup<V>\n    {\n        var self = lhs;\n        foreach (var iy in rhs)\n        {\n            var ix = self.Find(iy.Key);\n            if (ix.IsSome)\n            {\n                self = self.SetItem(iy.Key, ix.Value!.Combine(iy.Value));\n            }\n            else\n            {\n                self = self.Add(iy.Key, iy.Value);\n            }\n        }\n        return self;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Immutable Collections/TrieSet/TrieSet.cs",
    "content": "﻿#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing System;\nusing System.Runtime.CompilerServices;\nusing System.Linq;\nusing System.Collections.Generic;\nusing System.Collections;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Implementation of the CHAMP trie hash map data structure (Compressed Hash Array Map Trie)\n/// https://michael.steindorfer.name/publications/phd-thesis-efficient-immutable-collections.pdf\n/// </summary>\n/// <remarks>\n/// Used by internally by `LanguageExt.HashSet`\n/// </remarks>\ninternal class TrieSet<EqK, K> :\n    IEquatable<TrieSet<EqK, K>>,\n    IReadOnlyCollection<K>\n    where EqK : Eq<K>\n{\n    internal enum UpdateType\n    {\n        Add,\n        TryAdd,\n        AddOrUpdate,\n        SetItem,\n        TrySetItem\n    }\n\n    internal enum Tag\n    {\n        Entries,\n        Collision,\n        Empty\n    }\n\n    public static readonly TrieSet<EqK, K> Empty = new (EmptyNode.Default, 0);\n\n    readonly Node Root;\n    readonly int count;\n    int hash;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    TrieSet(Node root, int count)\n    {\n        Root = root;\n        this.count = count;\n    }\n\n    public TrieSet(ReadOnlySpan<K> items, bool tryAdd = true)\n    {\n        Root = EmptyNode.Default;\n        var type = tryAdd ? UpdateType.TryAdd : UpdateType.AddOrUpdate;\n        foreach (var item in items)\n        {\n            var hash    = (uint)EqK.GetHashCode(item);\n            Sec section = default;\n            var (countDelta, newRoot) = Root.Update((type, true), item, hash, section);\n            count += countDelta;\n            Root = newRoot;\n        }\n    }\n\n    public TrieSet(IEnumerable<K> items, bool tryAdd = true)\n    {\n        Root = EmptyNode.Default;\n        var type = tryAdd ? UpdateType.TryAdd : UpdateType.AddOrUpdate;\n        foreach (var item in items)\n        {\n            var hash    = (uint)EqK.GetHashCode(item);\n            Sec section = default;\n            var (countDelta, newRoot) = Root.Update((type, true), item, hash, section);\n            count += countDelta;\n            Root = newRoot;\n        }\n    }\n\n    /// <summary>\n    /// True if no items in the map\n    /// </summary>\n    public bool IsEmpty\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count == 0;\n    }\n\n    /// <summary>\n    /// Number of items in the map\n    /// </summary>\n    public int Count\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => count;\n    }\n\n    /// <summary>\n    /// Add an item to the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> Add(K key) =>\n        Update(key, UpdateType.Add, false);\n\n    /// <summary>\n    /// Try to add an item to the map.  If it already exists, do\n    /// nothing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> TryAdd(K key) =>\n        Update(key, UpdateType.TryAdd, false);\n\n    /// <summary>\n    /// Add an item to the map, if it exists update the value\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> AddOrUpdate(K key) =>\n        Update(key, UpdateType.AddOrUpdate, false);\n\n    /// <summary>\n    /// Add a range of values to the map\n    /// If any items already exist an exception will be thrown\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> AddRange(IEnumerable<K> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.Add(item);\n        }\n        return self;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> TryAddRange(IEnumerable<K> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TryAdd(item);\n        }\n        return self;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> AddOrUpdateRange(IEnumerable<K> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.AddOrUpdate(item);\n        }\n        return self;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> SetItems(IEnumerable<K> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.SetItem(item);\n        }\n        return self;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> TrySetItems(IEnumerable<K> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.TrySetItem(item);\n        }\n        return self;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> RemoveRange(IEnumerable<K> items)\n    {\n        var self = this;\n        foreach (var item in items)\n        {\n            self = self.Remove(item);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Set an item that already exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> SetItem(K key) =>\n        Update(key, UpdateType.SetItem, false);\n\n    /// <summary>\n    /// Try to set an item that already exists in the map.  If none\n    /// exists, do nothing.\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> TrySetItem(K key) =>\n        Update(key, UpdateType.TrySetItem, false);\n\n    /// <summary>\n    /// Update an item in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> Update(K key) =>\n        Update(key, UpdateType.Add, false);\n\n    /// <summary>\n    /// Remove an item from the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> Remove(K key)\n    {\n        var hash    = (uint)EqK.GetHashCode(key);\n        Sec section = default;\n        var (countDelta, newRoot) = Root.Remove(key, hash, section);\n        return ReferenceEquals(newRoot, Root)\n                   ? this\n                   : new TrieSet<EqK, K>(newRoot, count + countDelta);\n    }\n\n    /// <summary>\n    /// Indexer\n    /// </summary>\n    public K this[K key]\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get\n        {\n            var (found, nkey) = FindInternal(key);\n            return found\n                       ? nkey\n                       : throw new ArgumentException($\"Key doesn't exist in map: {key}\");\n        }\n    }\n\n    /// <summary>\n    /// Create an empty map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> Clear() =>\n        Empty;\n\n    /// <summary>\n    /// Get the hash code of the items in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override int GetHashCode() =>\n        hash == 0\n            ? (hash = FNV32.Hash<EqK, K>(AsEnumerable()))\n            : hash;\n\n    /// <summary>\n    /// Returns the whether the `key` exists in the map\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ContainsKey(K key) =>\n        FindInternal(key).Found;\n\n    /// <summary>\n    /// Returns the value associated with `key`.  Or None, if no key exists\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<K> Find(K key)\n    {\n        var (found, nkey) = FindInternal(key);\n        return found\n                   ? Some(nkey)\n                   : default;\n    }\n\n    /// <summary>\n    /// Returns the value associated with `key`.  Or None, if no key exists\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    (bool Found, K Key) FindInternal(K key)\n    {\n        var hash    = (uint)EqK.GetHashCode(key);\n        Sec section = default;\n        return Root.Read(key, hash, section);\n    }\n\n    /// <summary>\n    /// Map from K to U\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqU, U> Map<EqU, U>(Func<K, U> f) \n        where EqU : Eq<U> =>\n        new (AsEnumerable().Select(f), true);\n\n    /// <summary>\n    /// Map from K to K\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> Map(Func<K, K> f) =>\n        new (AsEnumerable().Select(f), true);\n\n    /// <summary>\n    /// Filter\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> Filter(Func<K, bool> f) =>\n        new (AsEnumerable().Filter(f), false);\n\n    /// <summary>\n    /// Associative union\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> Append(TrieSet<EqK, K> rhs) =>\n        TryAddRange(rhs.AsEnumerable());\n\n    /// <summary>\n    /// Subtract\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public TrieSet<EqK, K> Subtract(TrieSet<EqK, K> rhs)\n    {\n        var lhs = this;\n        foreach (var item in rhs)\n        {\n            lhs = lhs.Remove(item);\n        }\n        return lhs;\n    }\n\n    /// <summary>\n    /// Union\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static TrieSet<EqK, K> operator +(TrieSet<EqK, K> lhs, TrieSet<EqK, K> rhs) =>\n        lhs.Append(rhs);\n\n    /// <summary>\n    /// Subtract\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static TrieSet<EqK, K> operator -(TrieSet<EqK, K> lhs, TrieSet<EqK, K> rhs) =>\n        lhs.Subtract(rhs);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(TrieSet<EqK, K> lhs, TrieSet<EqK, K> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Non equality\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(TrieSet<EqK, K> lhs, TrieSet<EqK, K> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? rhs) =>\n        rhs is TrieSet<EqK, K> map && Equals(map);\n\n    /// <summary>\n    /// Equality\n    /// </summary>\n    public bool Equals(TrieSet<EqK, K>? rhs)\n    {\n        if (ReferenceEquals(this, rhs)) return true;\n        if (ReferenceEquals(rhs, null)) return false;\n        if (Count != rhs.Count) return false;\n        using var iterA = GetEnumerator();\n        using var iterB = rhs.GetEnumerator();\n        while (iterA.MoveNext() && iterB.MoveNext())\n        {\n            if (!EqK.Equals(iterA.Current, iterB.Current)) return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Update an item in the map - can mutate if needed\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    TrieSet<EqK, K> Update(K key, UpdateType type, bool mutate)\n    {\n        var hash    = (uint)EqK.GetHashCode(key);\n        Sec section = default;\n        var (countDelta, newRoot) = Root.Update((type, mutate), key, hash, section);\n        return ReferenceEquals(newRoot, Root)\n                   ? this\n                   : new TrieSet<EqK, K>(newRoot, count + countDelta);\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a proper subset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper subset of this set</returns>\n    public bool IsProperSubsetOf(IEnumerable<K> other)\n    {\n        if (IsEmpty)\n        {\n            return other.Any();\n        }\n\n        int  matches    = 0;\n        bool extraFound = false;\n        foreach (var item in other)\n        {\n            if (ContainsKey(item))\n            {\n                matches++;\n            }\n            else\n            {\n                extraFound = true;\n            }\n\n            if (matches == Count && extraFound)\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a proper superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a proper superset of this set</returns>\n    public bool IsProperSupersetOf(IEnumerable<K> other)\n    {\n        if (IsEmpty)\n        {\n            return false;\n        }\n\n        int matchCount = 0;\n        foreach (var item in other)\n        {\n            matchCount++;\n            if (!ContainsKey(item))\n            {\n                return false;\n            }\n        }\n\n        return Count > matchCount;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    public bool IsSubsetOf(IEnumerable<K> other)\n    {\n        if (IsEmpty)\n        {\n            return true;\n        }\n\n        int matches = 0;\n        foreach (var item in other)\n        {\n            if (ContainsKey(item))\n            {\n                matches++;\n            }\n        }\n        return matches == Count;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    public bool IsSubsetOf(TrieSet<EqK, K> other)\n    {\n        if (IsEmpty)\n        {\n            // All empty sets are subsets\n            return true;\n        }\n        if(Count > other.Count)\n        {\n            // A subset must be smaller or equal in size\n            return false;\n        }\n\n        foreach(var item in this)\n        {\n            if(!other.Contains(item))\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Returns True if 'other' is a superset of this set\n    /// </summary>\n    /// <returns>True if 'other' is a superset of this set</returns>\n    public bool IsSupersetOf(IEnumerable<K> other)\n    {\n        foreach (var item in other)\n        {\n            if (!ContainsKey(item))\n            {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// Returns True if other overlaps this set\n    /// </summary>\n    public bool Overlaps(IEnumerable<K> other)\n    {\n        if (IsEmpty)\n        {\n            return false;\n        }\n\n        foreach (var item in other)\n        {\n            if (ContainsKey(item))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /// <summary>\n    /// Returns the elements that are in both this and other\n    /// </summary>\n    public TrieSet<EqK, K> Intersect(IEnumerable<K> other)\n    {\n        var res = new List<K>();\n        foreach (var item in other)\n        {\n            var litem = Find(item);\n            if (litem.IsSome) res.Add((K)litem);\n        }\n        return new TrieSet<EqK, K>(res);\n    }\n\n    /// <summary>\n    /// Returns this - other.  Only the items in this that are not in \n    /// other will be returned.\n    /// </summary>\n    public TrieSet<EqK, K> Except(IEnumerable<K> other)\n    {\n        var self = this;\n        foreach (var item in other)\n        {\n            self = self.Remove(item);\n        }\n        return self;\n    }\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public TrieSet<EqK, K> SymmetricExcept(IEnumerable<K> rhs) =>\n        SymmetricExcept(new TrieSet<EqK, K>(rhs, true));\n\n    /// <summary>\n    /// Only items that are in one set or the other will be returned.\n    /// If an item is in both, it is dropped.\n    /// </summary>\n    public TrieSet<EqK, K> SymmetricExcept(TrieSet<EqK, K> rhs)\n    {\n        var res = new List<K>();\n\n        foreach (var item in this)\n        {\n            if (!rhs.ContainsKey(item))\n            {\n                res.Add(item);\n            }\n        }\n\n        foreach (var item in rhs)\n        {\n            if (!ContainsKey(item))\n            {\n                res.Add(item);\n            }\n        }\n\n        return new TrieSet<EqK, K>(res);\n    }\n\n    /// <summary>\n    /// Finds the union of two sets and produces a new set with \n    /// the results\n    /// </summary>\n    /// <param name=\"other\">Other set to union with</param>\n    /// <returns>A set which contains all items from both sets</returns>\n    public TrieSet<EqK, K> Union(IEnumerable<K> other) =>\n        this.TryAddRange(other);\n\n    /// <summary>\n    /// Nodes in the CHAMP hash trie map can be in one of three states:\n    /// \n    ///     Empty - nothing in the map\n    ///     Entries - contains items and sub-nodes\n    ///     Collision - keeps track of items that have different keys but the same hash\n    /// \n    /// </summary>\n    internal interface Node : IEnumerable<K>\n    {\n        Tag Type { get; }\n        (bool Found, K Key) Read(K key, uint hash, Sec section);\n        (int CountDelta, Node Node) Update((UpdateType Type, bool Mutate) env, K change, uint hash, Sec section);\n        (int CountDelta, Node Node) Remove(K key, uint hash, Sec section);\n    }\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // NOTE: Here be dragons!  The code below is has been optimised for performace.  Yes, it's \n    //       ugly, yes there's repetition, but it's all to squeeze the last few nanoseconds of \n    //       performance out of the system.  Don't hate me ;)\n    //\n\n    /// <summary>\n    /// Contains items and sub-nodes\n    /// </summary>\n    internal class Entries : Node\n    {\n        public readonly uint EntryMap;\n        public readonly uint NodeMap;\n        public readonly K[] Items;\n        public readonly Node[] Nodes;\n\n        public Tag Type => Tag.Entries;\n\n        public Entries(uint entryMap, uint nodeMap, K[] items, Node[] nodes)\n        {\n            EntryMap = entryMap;\n            NodeMap = nodeMap;\n            Items = items;\n            Nodes = nodes;\n        }\n\n        public void Deconstruct(out uint entryMap, out uint nodeMap, out K[] items, out Node[] nodes)\n        {\n            entryMap = EntryMap;\n            nodeMap = NodeMap;\n            items = Items;\n            nodes = Nodes;\n        }\n\n        public (int CountDelta, Node Node) Remove(K key, uint hash, Sec section)\n        {\n            var hashIndex = Bit.Get(hash, section);\n            var mask      = Mask(hashIndex);\n\n            if (Bit.Get(EntryMap, mask))\n            {\n                // If key belongs to an entry\n                var ind = Index(EntryMap, mask);\n                if (EqK.Equals(Items[ind], key))\n                {\n                    return (-1, \n                            new Entries(\n                                Bit.Set(EntryMap, mask, false), \n                                NodeMap,\n                                RemoveAt(Items, ind), \n                                Nodes));\n                }\n                else\n                {\n                    return (0, this);\n                }\n            }\n            else if (Bit.Get(NodeMap, mask))\n            {\n                //If key lies in a sub-node\n                var ind = Index(NodeMap, mask);\n                var (cd, subNode) = Nodes[ind].Remove(key, hash, section.Next());\n                if (cd == 0) return (0, this);\n\n                switch (subNode.Type)\n                {\n                    case Tag.Entries:\n\n                        var subEntries = (Entries)subNode;\n\n                        if (subEntries.Items.Length == 1 && subEntries.Nodes.Length == 0)\n                        {\n                            // If the node only has one subnode, make that subnode the new node\n                            if (Items.Length == 0 && Nodes.Length == 1)\n                            {\n                                // Build a new Entries for this level with the sublevel mask fixed\n                                return (cd, new Entries(\n                                            Mask(Bit.Get((uint)EqK.GetHashCode(subEntries.Items[0]), section)),\n                                            0,\n                                            Clone(subEntries.Items),\n                                            System.Array.Empty<Node>()\n                                        ));\n                            }\n                            else\n                            {\n                                return (cd, \n                                        new Entries(\n                                            Bit.Set(EntryMap, mask, true), \n                                            Bit.Set(NodeMap, mask, false),\n                                            Insert(Items, Index(EntryMap, mask), subEntries.Items[0]),\n                                            RemoveAt(Nodes, ind)));\n                            }\n                        }\n                        else\n                        {\n                            var nodeCopy = Clone(Nodes);\n                            nodeCopy[ind] = subNode;\n                            return (cd, new Entries(EntryMap, NodeMap, Items, nodeCopy));\n                        }\n\n                    case Tag.Collision:\n                        var nodeCopy2 = Clone(Nodes);\n                        nodeCopy2[ind] = subNode;\n                        return (cd, new Entries(EntryMap, NodeMap, Items, nodeCopy2));\n\n                    default:\n                        return (cd, this);\n                }\n            }\n            else\n            {\n                return (0, this);\n            }\n        }\n\n        public (bool Found, K Key) Read(K key, uint hash, Sec section)\n        {                                                                                         \n            // var hashIndex = Bit.Get(hash, section);\n            // Mask(hashIndex)\n            var mask = (uint)(1 << (int)((hash & (uint)(Sec.Mask << section.Offset)) >> section.Offset));\n\n            // if(Bit.Get(EntryMap, mask))\n            if ((EntryMap & mask) == mask)                                                        \n            {\n                // var entryIndex = Index(EntryMap, mask);\n                var entryIndex = BitCount((int)EntryMap & (((int)mask) - 1));                     \n                if (EqK.Equals(Items[entryIndex], key))\n                {\n                    var item = Items[entryIndex];\n                    return (true, item);\n                }\n                else\n                {\n                    return default;\n                }\n            }\n            // else if (Bit.Get(NodeMap, mask))\n            else if ((NodeMap & mask) == mask)                                                   \n            {\n                // var entryIndex = Index(NodeMap, mask);\n                var entryIndex = BitCount((int)NodeMap & (((int)mask) - 1));                     \n                return Nodes[entryIndex].Read(key, hash, section.Next());\n            }\n            else\n            {\n                return default;\n            }\n        }\n\n        public (int CountDelta, Node Node) Update((UpdateType Type, bool Mutate) env, K change, uint hash, Sec section)\n        {\n            // var hashIndex = Bit.Get(hash, section);\n            // var mask = Mask(hashIndex);\n            var mask = (uint)(1 << (int)((hash & (uint)(Sec.Mask << section.Offset)) >> section.Offset));\n\n            //if (Bit.Get(EntryMap, mask))\n            if((EntryMap & mask) == mask)\n            {\n                //var entryIndex = Index(EntryMap, mask);\n                var entryIndex   = BitCount((int)EntryMap & (((int)mask) - 1));\n                var currentEntry = Items[entryIndex];\n\n                if (EqK.Equals(currentEntry, change))\n                {\n                    if (env.Type == UpdateType.Add)\n                    {\n                        // Key already exists - so it's an error to add again\n                        throw new ArgumentException($\"Key already exists in map: {change}\");\n                    }\n                    else if (env.Type == UpdateType.TryAdd)\n                    {\n                        // Already added, so we don't continue to try\n                        return (0, this);\n                    }\n\n                    var newItems = SetItem(Items, entryIndex, change, env.Mutate);\n                    return (0, new Entries(EntryMap, NodeMap, newItems, Nodes));\n                }\n                else\n                {\n                    if (env.Type == UpdateType.SetItem)\n                    {\n                        // Key must already exist to set it\n                        throw new ArgumentException($\"Key already exists in map: {change}\");\n                    }\n                    else if (env.Type == UpdateType.TrySetItem)\n                    {\n                        // Key doesn't exist, so there's nothing to set\n                        return (0, this);\n                    }\n\n                    // Add\n                    var node = Merge(change, currentEntry, hash, (uint)EqK.GetHashCode(currentEntry), section);\n\n                    //var newItems = Items.Filter(elem => !EqK.Equals(elem.Key, currentEntry.Key)).ToArray();\n                    var newItems = new K[Items.Length - 1];\n                    var i        = 0;\n                    foreach(var elem in Items)\n                    {\n                        if(!EqK.Equals(elem, currentEntry))\n                        {\n                            newItems[i] = elem;\n                            i++;\n                        }\n                    }\n\n                    //var newEntryMap = Bit.Set(EntryMap, mask, false);\n                    var newEntryMap = EntryMap & (~mask);\n\n                    // var newNodeMap = Bit.Set(NodeMap, mask, true);\n                    var newNodeMap = NodeMap | mask;\n\n                    // var nodeIndex = Index(NodeMap, mask);\n                    var nodeIndex = BitCount((int)NodeMap & (((int)mask) - 1));\n\n                    var newNodes = Insert(Nodes, nodeIndex, node);\n\n                    return (1, new Entries(\n                                newEntryMap, \n                                newNodeMap, \n                                newItems, \n                                newNodes));\n                }\n            }\n            else if (Bit.Get(NodeMap, mask))\n            {\n                // var nodeIndex = Index(NodeMap, mask);\n                var nodeIndex = BitCount((int)NodeMap & (((int)mask) - 1));\n\n                var nodeToUpdate = Nodes[nodeIndex];\n                var (cd, newNode) = nodeToUpdate.Update(env, change, hash, section.Next());\n                var newNodes = SetItem(Nodes, nodeIndex, newNode, env.Mutate);\n                return (cd, new Entries(EntryMap, NodeMap, Items, newNodes));\n            }\n            else\n            {\n                if (env.Type == UpdateType.SetItem)\n                {\n                    // Key must already exist to set it\n                    throw new ArgumentException($\"Key doesn't exist in map: {change}\");\n                }\n                else if (env.Type == UpdateType.TrySetItem)\n                {\n                    // Key doesn't exist, so there's nothing to set\n                    return (0, this);\n                }\n\n                // var entryIndex = Index(EntryMap, mask);\n                var entryIndex = BitCount((int)EntryMap & (((int)mask) - 1));\n\n                // var entries = Bit.Set(EntryMap, mask, true);\n                var entries = EntryMap | mask;\n\n                var newItems = Insert(Items, entryIndex, change);\n                return (1, new Entries(entries, NodeMap, newItems, Nodes));\n            }\n        }\n\n        public IEnumerator<K> GetEnumerator()\n        {\n            foreach (var item in Items)\n            {\n                yield return item;\n            }\n\n            foreach (var node in Nodes)\n            {\n                foreach (var item in node)\n                {\n                    yield return item;\n                }\n            }\n        }\n\n        IEnumerator IEnumerable.GetEnumerator() =>\n            GetEnumerator();\n    }\n\n    /// <summary>\n    /// Contains items that share the same hash but have different keys\n    /// </summary>\n    internal class Collision : Node\n    {\n        public readonly K[] Items;\n        public readonly uint Hash;\n\n        public Tag Type => Tag.Collision;\n\n        public Collision(K[] items, uint hash)\n        {\n            Items = items;\n            Hash = hash;\n        }\n\n        public (bool Found, K Key) Read(K key, uint hash, Sec section)\n        {\n            foreach (var kv in Items)\n            {\n                if (EqK.Equals(kv, key))\n                {\n                    return (true, kv);\n                }\n            }\n            return default;\n        }\n\n        public (int CountDelta, Node Node) Remove(K key, uint hash, Sec section)\n        {\n            var len = Items.Length;\n            if (len      == 0) return (0, this);\n            else if (len == 1) return (-1, EmptyNode.Default);\n            else if (len == 2)\n            {\n                var (_, n) = EqK.Equals(Items[0], key)\n                                 ? EmptyNode.Default.Update((UpdateType.Add, false), Items[1], hash, default)\n                                 : EmptyNode.Default.Update((UpdateType.Add, false), Items[0], hash, default);\n\n                return (-1, n);\n            }\n            else\n            {\n                IEnumerable<K> Yield(K[] items, K ikey)\n                {\n                    foreach (var item in items)\n                    {\n                        if (!EqK.Equals(item, ikey))\n                        {\n                            yield return item;\n                        }\n                    }\n                }\n\n                var nitems = Yield(Items, key).ToArray();\n\n                return (nitems.Length - Items.Length, new Collision(nitems, hash));\n            }\n        }\n\n        public (int CountDelta, Node Node) Update((UpdateType Type, bool Mutate) env, K change, uint hash, Sec section)\n        {\n            var index = -1;\n            for (var i = 0; i < Items.Length; i++)\n            {\n                if (EqK.Equals(Items[i], change))\n                {\n                    index = i;\n                    break;\n                }\n            }\n\n            if (index >= 0)\n            {\n                if (env.Type == UpdateType.Add)\n                {\n                    // Key already exists - so it's an error to add again\n                    throw new ArgumentException($\"Key already exists in map: {change}\");\n                }\n                else if (env.Type == UpdateType.TryAdd)\n                {\n                    // Already added, so we don't continue to try\n                    return (0, this);\n                }\n\n                var newArr = SetItem(Items, index, change, false);\n                return (0, new Collision(newArr, hash));\n            }\n            else\n            {\n                if (env.Type == UpdateType.SetItem)\n                {\n                    // Key must already exist to set it\n                    throw new ArgumentException($\"Key doesn't exist in map: {change}\");\n                }\n                else if (env.Type == UpdateType.TrySetItem)\n                {\n                    // Key doesn't exist, so there's nothing to set\n                    return (0, this);\n                }\n\n                var nitems = new K[Items.Length + 1];\n                System.Array.Copy(Items, nitems, Items.Length);\n                nitems[Items.Length] = change;\n                return (1, new Collision(nitems, hash));\n            }\n        }\n\n        public IEnumerator<K> GetEnumerator() =>\n            Items.AsEnumerable().GetEnumerator();\n\n        IEnumerator IEnumerable.GetEnumerator() =>\n            Items.AsEnumerable().GetEnumerator();\n    }\n\n    /// <summary>\n    /// Empty node\n    /// </summary>\n    internal class EmptyNode : Node\n    {\n        public static readonly EmptyNode Default = new EmptyNode();\n\n        public Tag Type => Tag.Empty;\n\n        public (bool Found, K Key) Read(K key, uint hash, Sec section) =>\n            default;\n\n        public (int CountDelta, Node Node) Remove(K key, uint hash, Sec section) =>\n            (0, this);\n\n        public (int CountDelta, Node Node) Update((UpdateType Type, bool Mutate) env, K change, uint hash, Sec section)\n        {\n            if (env.Type == UpdateType.SetItem)\n            {\n                // Key must already exist to set it\n                throw new ArgumentException($\"Key doesn't exist in map: {change}\");\n            }\n            else if (env.Type == UpdateType.TrySetItem)\n            {\n                // Key doesn't exist, so there's nothing to set\n                return (0, this);\n            }\n\n            var dataMap = Mask(Bit.Get(hash, section));\n            return (1, new Entries(dataMap, 0, [change], System.Array.Empty<Node>()));\n        }\n\n        public IEnumerator<K> GetEnumerator()\n        {\n            yield break;\n        }\n\n        IEnumerator IEnumerable.GetEnumerator()\n        {\n            yield break;\n        }\n    }\n\n    /// <summary>\n    /// Merges two keys into a single Node\n    /// </summary>\n    static Node Merge(K key1, K key2, uint pair1Hash, uint pair2Hash, Sec section)\n    {\n        if (section.Offset >= 25)\n        {\n            return new Collision([key1, key2], pair1Hash);\n        }\n        else\n        {\n            var nextLevel  = section.Next();\n            var pair1Index = Bit.Get(pair1Hash, nextLevel);\n            var pair2Index = Bit.Get(pair2Hash, nextLevel);\n            if (pair1Index == pair2Index)\n            {\n                var node    = Merge(key1, key2, pair1Hash, pair2Hash, nextLevel);\n                var nodeMap = Mask(pair1Index);\n                return new Entries(0, nodeMap, System.Array.Empty<K>(), new[] { node });\n            }\n            else\n            {\n                var dataMap = Mask(pair1Index);\n                dataMap = Bit.Set(dataMap, Mask(pair2Index), true);\n                return new Entries(dataMap, 0, pair1Index < pair2Index\n                                                   ? new[] { key1, key2 }\n                                                   : new[] { key2, key1 }, System.Array.Empty<Node>());\n            }\n        }\n    }\n\n    public Iterable<K> AsEnumerable() =>\n        Root.AsIterable();\n\n    public IEnumerator<K> GetEnumerator() =>\n        Root.GetEnumerator();\n\n    IEnumerator IEnumerable.GetEnumerator() =>\n        Root.GetEnumerator();\n\n    /// <summary>\n    /// Counts the number of 1-bits in bitmap\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static int BitCount(int bits)\n    {\n        var c2 = bits - ((bits >> 1) & 0x55555555);\n        var c4 = (c2                 & 0x33333333) + ((c2 >> 2) & 0x33333333);\n        var c8 = (c4 + (c4                                >> 4)) & 0x0f0f0f0f;\n        return (c8 * 0x01010101) >> 24;\n    }\n\n    /// <summary>\n    /// Finds the number of set bits below the bit at `location`\n    /// This function is used to find where in the array of entries or nodes \n    /// the item should be inserted\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static int Index(uint bits, int location) =>\n        BitCount((int)bits & (location - 1));\n\n    /// <summary>\n    /// Finds the number of 1-bits below the bit at `location`\n    /// This function is used to find where in the array of entries or nodes \n    /// the item should be inserted\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static int Index(uint bitmap, uint location) =>\n        BitCount((int)bitmap & ((int)location - 1));\n\n    /// <summary>\n    /// Returns the value used to index into the bit vector\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static uint Mask(int index) =>\n        (uint)(1 << index);\n\n    /// <summary>\n    /// Sets the item at index. If mutate is true it sets the \n    /// value without copying the array, otherwise the operation is pure\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] SetItem<A>(A[] items, int index, A value, bool mutate)\n    {\n        if (mutate)\n        {\n            items[index] = value;\n            return items;\n        }\n        else\n        {\n            var nitems = new A[items.Length];\n            System.Array.Copy(items, nitems, items.Length);\n            nitems[index] = value;\n            return nitems;\n        }\n    }\n\n    /// <summary>\n    /// Clones part of an existing array\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] Clone<A>(A[] items, int count)\n    {\n        var nitems = new A[count];\n        System.Array.Copy(items, nitems, count);\n        return nitems;\n    }\n\n    /// <summary>\n    /// Clones an existing array\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] Clone<A>(A[] items)\n    {\n        var len    = items.Length;\n        var nitems = new A[len];\n        System.Array.Copy(items, nitems, len);\n        return nitems;\n    }\n\n    /// <summary>\n    /// Inserts a new item in the array (immutably)\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] Insert<A>(A[] array, int index, A value)\n    {\n        var narray = new A[array.Length + 1];\n        System.Array.Copy(array, 0, narray, 0, index);\n        System.Array.Copy(array, index, narray, index + 1, array.Length - index);\n        narray[index] = value;\n        return narray;\n    }\n\n    /// <summary>\n    /// Returns a new array with the item at index removed\n    /// </summary>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static A[] RemoveAt<A>(A[] array, int index)\n    {\n        if (array.Length == 0)\n        {\n            return array;\n        }\n\n        var narray = new A[array.Length - 1];\n        if (index > 0)\n        {\n            System.Array.Copy(array, 0, narray, 0, index);\n        }\n        if (index + 1 < array.Length)\n        {\n            System.Array.Copy(array, index + 1, narray, index, array.Length - index - 1);\n        }\n        return narray;\n    }\n\n    public override string ToString() =>\n        count < 50\n            ? $\"[{ string.Join(\", \", AsEnumerable()) }]\"\n            : $\"[{ string.Join(\", \", AsEnumerable().Take(50)) } ... ]\";\n\n    public bool TryGetValue(K key, out K value)\n    {\n        var ov = Find(key);\n        if (ov.IsSome)\n        {\n            value = (K)ov;\n            return true;\n        }\n        else\n        {\n            value = default!;\n            return false;\n        }\n    }\n\n    IEnumerator<K> IEnumerable<K>.GetEnumerator() =>\n        AsEnumerable().GetEnumerator();\n}\n"
  },
  {
    "path": "LanguageExt.Core/LanguageExt.Core.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)'=='Debug'\">\n    <DefineConstants>TRACE;DEBUG</DefineConstants>\n  </PropertyGroup>\n  <PropertyGroup Label=\"Configuration\">\n    <NoWarn>1701;1702;1705;IDE1006;CS1591;CS1573;CS1712;CS1711;CS1572;CS1587;CA2260</NoWarn>\n    <DefineConstants>CONTRACTS_FULL</DefineConstants>\n    <TargetFramework>net10.0</TargetFramework>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n  <PropertyGroup>\n    <PackageVersion>5.0.0-beta-77</PackageVersion>\n    <PackageId>LanguageExt.Core</PackageId>\n    <Title>LanguageExt.Core</Title>\n    <Authors>Paul Louth</Authors>\n    <Summary>Functional language extensions for C#</Summary>\n    <PackageReadmeFile>README.nuget.md</PackageReadmeFile>\n    <Copyright>Copyright (c) Paul Louth. All rights reserved.</Copyright>\n    <Description>This framework uses and abuses the features of C# to provide a functional 'Base class library', that, if you squint, can look like extensions to the language itself.</Description>\n    <PackageTags>C#, Functional, Language Extension, Monad, Option, Either, Reader, Writer, State, List, Set, Map, Queue, Memo, Memoization, Immutable, Lambda, Pattern Matching, Tuple</PackageTags>\n    <PackageIcon>lang-ext-small.png</PackageIcon>\n    <PackageProjectUrl>https://github.com/louthy/language-ext</PackageProjectUrl>\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\n    <EnableDefaultCompileItems>false</EnableDefaultCompileItems>\n    <DocumentationFile>bin\\$(Configuration)\\$(TargetFramework)\\$(AssemblyName).xml</DocumentationFile>\n    <OutputType>library</OutputType>\n    <AssemblyVersion>5.0.0.0</AssemblyVersion>\n    <FileVersion>5.0.0.0</FileVersion>\n    <LangVersion>default</LangVersion>\n  </PropertyGroup>\n  <ItemGroup>\n    <InternalsVisibleTo Include=\"LanguageExt.Tests\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"README.nuget.md\" Pack=\"true\" PackagePath=\"\\\"/>\n    <None Include=\"..\\Images\\lang-ext-small.png\" Pack=\"true\" PackagePath=\"\\\"/>\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"**\\*.cs\" />\n    <EmbeddedResource Include=\"**\\*.resx\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Remove=\"obj\\**\" />\n    <EmbeddedResource Remove=\"obj\\**\" />\n    <None Remove=\"obj\\**\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"README.md\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "LanguageExt.Core/Lens/Lens.Operators.cs",
    "content": "namespace LanguageExt;\n\npublic static class LensExtensions\n{\n    extension<A, B, C>(Lens<A, B> _)\n    {\n        public static Lens<A, C> operator |(Lens<A, B> lhs, Lens<B, C> rhs) =>\n            Lens<A, C>.New(\n                Get: a => rhs.Get(lhs.Get(a)),\n                Set: v => lhs.Update(rhs.SetF(v)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Lens/Lens.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace LanguageExt;\n\npublic static class Lens\n{\n    /// <summary>\n    /// Pair two lenses\n    /// </summary>\n    public static Lens<(A, B), (C, D)> tuple<A, B, C, D>(Lens<A, C> First, Lens<B, D> Second) =>\n        Lens<(A, B), (C, D)>.New(\n            Get: a => (First.Get(a.Item1), Second.Get(a.Item2)),\n            Set: v => a => (First.Set(v.Item1, a.Item1), Second.Set(v.Item2, a.Item2)));\n\n    /// <summary>\n    /// Triple three lenses\n    /// </summary>\n    public static Lens<(A, B, C), (D, E, F)> tuple<A, B, C, D, E, F>(Lens<A, D> First, Lens<B, E> Second, Lens<C, F> Third) =>\n        Lens<(A, B, C), (D, E, F)>.New(\n            Get: a => (First.Get(a.Item1), Second.Get(a.Item2), Third.Get(a.Item3)),\n            Set: v => a => (First.Set(v.Item1, a.Item1), Second.Set(v.Item2, a.Item2), Third.Set(v.Item3, a.Item3)));\n\n    /// <summary>\n    /// <paramref name=\"pred\"/> is applied to source. \n    /// If true, <paramref name=\"Then\"/> is selected.\n    /// If false, <paramref name=\"Else\"/> is selected.\n    /// </summary>\n    public static Lens<A, B> cond<A, B>(Func<A, bool> pred, Lens<A, B> Then, Lens<A, B> Else)\n    {\n        Lens<A, B> choose(A a) => pred(a) ? Then : Else;\n        return Lens<A, B>.New(\n            Get: a => choose(a).Get(a),\n            Set: v => a => choose(a).Set(v, a));\n    }\n\n    /// <summary>\n    /// Gets/sets the fst element in a pair\n    /// </summary>\n    public static Lens<(A, B), A> fst<A, B>() =>\n        Lens<(A, B), A>.New(\n            Get: ab => ab.Item1,\n            Set: a => ab => (a, ab.Item2));\n\n    /// <summary>\n    /// Gets/sets the fst element in a triple\n    /// </summary>\n    public static Lens<(A, B, C), A> fst<A, B, C>() =>\n        Lens<(A, B, C), A>.New(\n            Get: ab => ab.Item1,\n            Set: a => ab => (a, ab.Item2, ab.Item3));\n\n    /// <summary>\n    /// Gets/sets the fst element in a quad\n    /// </summary>\n    public static Lens<(A, B, C, D), A> fst<A, B, C, D>() =>\n        Lens<(A, B, C, D), A>.New(\n            Get: ab => ab.Item1,\n            Set: a => ab => (a, ab.Item2, ab.Item3, ab.Item4));\n\n    /// <summary>\n    /// Gets/sets the snd element in a pair\n    /// </summary>\n    public static Lens<(A, B), B> snd<A, B>() =>\n        Lens<(A, B), B>.New(\n            Get: ab => ab.Item2,\n            Set: b => ab => (ab.Item1, b));\n\n    /// <summary>\n    /// Gets/sets the snd element in a pair\n    /// </summary>\n    public static Lens<(A, B, C), B> snd<A, B, C>() =>\n        Lens<(A, B, C), B>.New(\n            Get: ab => ab.Item2,\n            Set: b => ab => (ab.Item1, b, ab.Item3));\n\n    /// <summary>\n    /// Gets/sets the snd element in a pair\n    /// </summary>\n    public static Lens<(A, B, C, D), B> snd<A, B, C, D>() =>\n        Lens<(A, B, C, D), B>.New(\n            Get: ab => ab.Item2,\n            Set: b => ab => (ab.Item1, b, ab.Item3, ab.Item4));\n\n\n    /// <summary>\n    /// Gets/sets the thrd element in a pair\n    /// </summary>\n    public static Lens<(A, B, C), C> thrd<A, B, C>() =>\n        Lens<(A, B, C), C>.New(\n            Get: abc => abc.Item3,\n            Set: c => abc => (abc.Item1, abc.Item2, c));\n\n    /// <summary>\n    /// Gets/sets the thrd element in a pair\n    /// </summary>\n    public static Lens<(A, B, C, D), C> thrd<A, B, C, D>() =>\n        Lens<(A, B, C, D), C>.New(\n            Get: abc => abc.Item3,\n            Set: c => abc => (abc.Item1, abc.Item2, c, abc.Item4));\n\n    /// <summary>\n    /// Identity lens\n    /// </summary>\n    public static Lens<A, A> identity<A>() =>\n        Lens<A, A>.New(\n            Get: a => a,\n            Set: a => _ => a);\n\n    /// <summary>\n    /// Creates a lens that maps the given lens in an enumerable\n    /// </summary>\n    public static Lens<IEnumerable<A>, IEnumerable<B>> enumMap<A, B>(Lens<A, B> la) =>\n        Lens<IEnumerable<A>, IEnumerable<B>>.New(\n            Get: lst => lst.Select(la.Get),\n            Set: val => lst => lst.Zip(val).Select(ab => la.Set(ab.Item2, ab.Item1)));\n\n    /// <summary>\n    /// Convert a Lens〈A, B〉 to a Prism〈A, B〉\n    /// </summary>\n    public static Prism<A, B> ToPrism<A, B>(this Lens<A, B> la) => Prism<A, B>.New(la);\n\n    /// <summary>\n    /// Convert a Lens〈A, Option〈B〉〉 to a Prism〈A, B〉\n    /// </summary>\n    public static Prism<A, B> ToPrism<A, B>(this Lens<A, Option<B>> la) => Prism<A, B>.New(la);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Lens/LensAB.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Primitive lens type for creating well-behaved bidirectional transformations\n/// </summary>\npublic readonly struct Lens<A, B>\n{\n    public readonly Func<A, B> Get;\n    public readonly Func<B, Func<A, A>> SetF;\n\n    Lens(Func<A, B> get, Func<B, Func<A, A>> set)\n    {\n        Get = get;\n        SetF = set;\n    }\n\n    public A Set(B value, A cont) =>\n        SetF(value)(cont);\n\n    public static Lens<A, B> New(Func<A, B> Get, Func<B, Func<A, A>> Set) =>\n        new (Get, Set);\n\n    public Func<A, A> Update(Func<B, B> f)\n    {\n        var self = this;\n        return a => self.Set(f(self.Get(a)), a);\n    }\n\n    public A Update(Func<B, B> f, A value) =>\n        Set(f(Get(value)), value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Lens/Prelude.Lens.cs",
    "content": "﻿\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Sequentially composes two lenses\n    /// </summary>\n    public static Lens<A, C> lens<A, B, C>(Lens<A, B> la, Lens<B, C> lb) =>\n        Lens<A, C>.New(\n            Get: a => lb.Get(la.Get(a)),\n            Set: v => la.Update(lb.SetF(v)));\n\n    /// <summary>\n    /// Sequentially composes three lenses\n    /// </summary>\n    public static Lens<A, D> lens<A, B, C, D>(Lens<A, B> la, Lens<B, C> lb, Lens<C, D> lc) =>\n        Lens<A, D>.New(\n            Get: a => lc.Get(lb.Get(la.Get(a))),\n            Set: v => la.Update(lb.Update(lc.SetF(v))));\n\n    /// <summary>\n    /// Sequentially composes four lenses\n    /// </summary>\n    public static Lens<A, E> lens<A, B, C, D, E>(Lens<A, B> la, Lens<B, C> lb, Lens<C, D> lc, Lens<D, E> ld) =>\n        Lens<A, E>.New(\n            Get: a => ld.Get(lc.Get(lb.Get(la.Get(a)))),\n            Set: v => la.Update(lb.Update(lc.Update(ld.SetF(v)))));\n\n    /// <summary>\n    /// Sequentially composes five lenses\n    /// </summary>\n    public static Lens<A, F> lens<A, B, C, D, E, F>(Lens<A, B> la, Lens<B, C> lb, Lens<C, D> lc, Lens<D, E> ld, Lens<E, F> le) =>\n        Lens<A, F>.New(\n            Get: a => le.Get(ld.Get(lc.Get(lb.Get(la.Get(a))))),\n            Set: v => la.Update(lb.Update(lc.Update(ld.Update(le.SetF(v))))));\n\n    /// <summary>\n    /// Sequentially composes six lenses\n    /// </summary>\n    public static Lens<A, G> lens<A, B, C, D, E, F, G>(Lens<A, B> la, Lens<B, C> lb, Lens<C, D> lc, Lens<D, E> ld, Lens<E, F> le, Lens<F, G> lf) =>\n        Lens<A, G>.New(\n            Get: a => lf.Get(le.Get(ld.Get(lc.Get(lb.Get(la.Get(a)))))),\n            Set: v => la.Update(lb.Update(lc.Update(ld.Update(le.Update(lf.SetF(v)))))));\n\n    /// <summary>\n    /// Sequentially composes seven lenses\n    /// </summary>\n    public static Lens<A, H> lens<A, B, C, D, E, F, G, H>(Lens<A, B> la, Lens<B, C> lb, Lens<C, D> lc, Lens<D, E> ld, Lens<E, F> le, Lens<F, G> lf, Lens<G, H> lg) =>\n        Lens<A, H>.New(\n            Get: a => lg.Get(lf.Get(le.Get(ld.Get(lc.Get(lb.Get(la.Get(a))))))),\n            Set: v => la.Update(lb.Update(lc.Update(ld.Update(le.Update(lf.Update(lg.SetF(v))))))));\n\n    /// <summary>\n    /// Sequentially composes eight lenses\n    /// </summary>\n    public static Lens<A, I> lens<A, B, C, D, E, F, G, H, I>(Lens<A, B> la, Lens<B, C> lb, Lens<C, D> lc, Lens<D, E> ld, Lens<E, F> le, Lens<F, G> lf, Lens<G, H> lg, Lens<H, I> lh) =>\n        Lens<A, I>.New(\n            Get: a => lh.Get(lg.Get(lf.Get(le.Get(ld.Get(lc.Get(lb.Get(la.Get(a)))))))),\n            Set: v => la.Update(lb.Update(lc.Update(ld.Update(le.Update(lf.Update(lg.Update(lh.SetF(v)))))))));\n\n    /// <summary>\n    /// Sequentially composes nine lenses\n    /// </summary>\n    public static Lens<A, J> lens<A, B, C, D, E, F, G, H, I, J>(Lens<A, B> la, Lens<B, C> lb, Lens<C, D> lc, Lens<D, E> ld, Lens<E, F> le, Lens<F, G> lf, Lens<G, H> lg, Lens<H, I> lh, Lens<I, J> li) =>\n        Lens<A, J>.New(\n            Get: a => li.Get(lh.Get(lg.Get(lf.Get(le.Get(ld.Get(lc.Get(lb.Get(la.Get(a))))))))),\n            Set: v => la.Update(lb.Update(lc.Update(ld.Update(le.Update(lf.Update(lg.Update(lh.Update(li.SetF(v))))))))));\n\n    /// <summary>\n    /// Sequentially composes ten lenses\n    /// </summary>\n    public static Lens<A, K> lens<A, B, C, D, E, F, G, H, I, J, K>(Lens<A, B> la, Lens<B, C> lb, Lens<C, D> lc, Lens<D, E> ld, Lens<E, F> le, Lens<F, G> lf, Lens<G, H> lg, Lens<H, I> lh, Lens<I, J> li, Lens<J, K> lj) =>\n        Lens<A, K>.New(\n            Get: a => lj.Get(li.Get(lh.Get(lg.Get(lf.Get(le.Get(ld.Get(lc.Get(lb.Get(la.Get(a)))))))))),\n            Set: v => la.Update(lb.Update(lc.Update(ld.Update(le.Update(lf.Update(lg.Update(lh.Update(li.Update(lj.SetF(v)))))))))));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Lens/README.md",
    "content": "Lenses allow you to look inside a structure to access its value and then subsequently \nupdate that value.  But because we don't want to do mutation, the updaters create new\nversions of the underlying structure.\n"
  },
  {
    "path": "LanguageExt.Core/Memo/Extensions/Memo.Extensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class MemoExtensions\n{\n    extension<FF, A>(Memo<K<FF, A>> self)\n    {\n        public Memo<FF, A> Lift() =>\n            (self.acquire, self.state) switch\n            {\n                (null, 2) => new Memo<FF, A>(self.acquire, self.value),\n                (null, _) => new Memo<FF, A>(self.value!),\n                _         => new Memo<FF, A>(self.acquire)\n            };\n    }\n    \n    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Functor extensions\n    //\n\n    extension<FF, A>(Memo<FF, A> self)\n    {\n        public Memo<FF, B> MapM<B>(Func<K<FF, A>, K<FF, B>> f) =>\n            new (() => f(self.Value));\n    }\n    \n    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Functor extensions\n    //\n\n    extension<F, G, A>(Memo<F, A> self)\n        where F : Natural<F, G>\n    {\n        public Memo<G, A> Transform() =>\n            new (() => F.Transform(self.Value));\n    }\n    \n    /// <summary>\n    /// Returns a Func〈T〉 that wraps func.  The first\n    /// call to the resulting Func〈T〉 will cache the result.\n    /// Subsequent calls return the cached item.\n    /// </summary>\n    public static Memo<T> Memo<T>(this Func<T> func) =>\n        memo(func);\n\n    /// <summary>\n    /// Returns a Func〈T, R〉 that wraps func.  Each time the resulting\n    /// Func〈T, R〉 is called with a new value, its result is memoized (cached).\n    /// Subsequent calls use the memoized value.  \n    /// \n    /// Remarks: \n    ///     Thread-safe and memory-leak safe.  \n    /// </summary>\n    public static Func<T, R> Memo<T, R>(this Func<T, R> func) where T : notnull =>\n        memo(func);\n\n    /// <summary>\n    /// Returns a Func〈T, R〉 that wraps func.  Each time the resulting\n    /// Func〈T, R〉 is called with a new value, its result is memoized (cached).\n    /// Subsequent calls use the memoized value.  \n    /// \n    /// Remarks: \n    ///     No mechanism for freeing cached values and therefore can cause a\n    ///     memory leak when holding onto the Func〈T, R〉 reference.\n    ///     Uses a ConcurrentDictionary for the cache and is thread-safe\n    /// </summary>\n    public static Func<T, R> MemoUnsafe<T, R>(this Func<T, R> func) where T : notnull =>\n        Prelude.memoUnsafe(func);\n\n    /// <summary>\n    /// Enumerable memoization.  As an enumerable is enumerated each item is retained\n    /// in an internal list, so that future evaluation of the enumerable isn't done. \n    /// Only items not seen before are evaluated.  \n    /// \n    /// This minimises one of the major problems with the IEnumerable / yield return \n    /// pattern by causing at-most-once evaluation of each item.  \n    /// \n    /// Use the IEnumerable extension method Memo for convenience.\n    /// </summary>\n    /// <remarks>\n    /// Although this allows efficient lazy evaluation, it does come at a memory cost.\n    /// Each item is cached internally, so this method doesn't allow for evaluation of\n    /// infinite sequences.\n    /// </remarks>\n    /// <param name=\"seq\">Enumerable to memoize</param>\n    /// <returns>IEnumerable with caching properties</returns>\n    public static IEnumerable<T> Memo<T>(this IEnumerable<T> seq) =>\n        Prelude.memo(seq);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Memo/Memo.F.cs",
    "content": "using System;\nusing System.Threading;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Makes `K〈F, A〉` lazy\n/// </summary>\n/// <remarks>\n/// This is more of a utility type right now, so it hasn't been fleshed out like other Applicatives\n/// </remarks>\npublic class Memo<F, A>\n{\n    /// <summary>\n    /// Acquired value or null if not yet acquired\n    /// </summary>\n    K<F, A>? value;\n    \n    /// <summary>\n    /// Function to acquire the value\n    /// </summary>\n    Func<K<F, A>>? acquire;\n    \n    /// <summary>\n    /// 0 = unloaded, 1 = loading, 2 = loaded\n    /// </summary>\n    int state;\n    \n    /// <summary>\n    /// Construct a memo\n    /// </summary>\n    /// <param name=\"acq\">Value acquisition function</param>\n    internal Memo(Func<K<F, A>> f)\n    {\n        value = null;\n        acquire = f;\n        state = 0;\n    }\n    \n    /// <summary>\n    /// Construct a memo\n    /// </summary>\n    /// <param name=\"fa\">Already acquired value</param>\n    internal Memo(Func<K<F, A>>? f, K<F, A>? fa)\n    {\n        value = fa;\n        acquire = f;\n        state = 2;\n    }\n    \n    /// <summary>\n    /// Construct a memo\n    /// </summary>\n    /// <param name=\"fa\">Already acquired value</param>\n    internal Memo(K<F, A> fa)\n    {\n        value = fa;\n        acquire = null;\n        state = 2;\n    }\n\n    public Memo<K<F, A>> Lower() =>\n        new (() => Value);\n    \n    /// <summary>\n    /// Acquired value\n    /// </summary>\n    /// <remarks>\n    /// If the value is not yet acquired, it will be acquired within `Value` and cached.\n    /// </remarks>\n    public K<F, A> Value => \n        state == 2\n            ? value!\n            : GetValue();\n\n    /// <summary>\n    /// Create a clone of the memo (without any cached results).  This allows for reacquiring the value.\n    /// </summary>\n    /// <returns>A newly constructed memo structure</returns>\n    public Memo<F, A> Clone() =>\n        acquire is null\n            ? new(value!)\n            : new(acquire);\n    \n    /// <summary>\n    /// Reset the memo.  This clears the cached value. \n    /// </summary>\n    /// <returns>Unit</returns>\n    public Unit Reset()\n    {\n        if(acquire is null) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            switch (Interlocked.CompareExchange(ref state, 1, 2))\n            {\n                case 0:\n                    // unloaded\n                    return default;\n                \n                case 1:\n                    // currently unloading, so wait, then loop around and try again\n                    sw.SpinOnce();\n                    break;\n                \n                case 2:\n                    value = null;\n                    state = 0;\n                    return default;\n\n                default:\n                    throw new InvalidOperationException(\"Invalid state\");\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Acquisition function.  Called only if the value is not yet acquired.\n    /// </summary>\n    K<F, A> GetValue()\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            switch (Interlocked.CompareExchange(ref state, 1, 0))\n            {\n                case 0:\n                    // value is not set yet, so try to set it\n                    try\n                    {\n                        value = acquire!();\n                        state = 2;\n                        return value;\n                    }\n                    catch\n                    {\n                        // if we fail, reset the state to 'not set yet'\n                        state = 0;\n                        throw;\n                    }\n                    \n                case 1:\n                    // currently loading, so wait, then loop around and try again\n                    sw.SpinOnce();\n                    break;\n                    \n                case 2:\n                    // value already set\n                    return value!;\n\n                default:\n                    throw new InvalidOperationException(\"Invalid state\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Memo/Memo.Module.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class Memo\n{\n    /// <summary>\n    /// Natural transformation for memoised higher-kinded structures\n    /// </summary>\n    /// <param name=\"ma\">Structure to transform</param>\n    /// <typeparam name=\"F\">Original structure</typeparam>\n    /// <typeparam name=\"G\">New structure</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Naturally transformed structure</returns>\n    public static Memo<G, A> transform<F, G, A>(Memo<F, A> ma)\n        where F : Natural<F, G> =>\n        new(() => F.Transform(ma.Value));\n    \n    /// <summary>\n    /// Natural transformation for memoised higher-kinded structures\n    /// </summary>\n    /// <param name=\"ma\">Structure to transform</param>\n    /// <typeparam name=\"F\">New structure</typeparam>\n    /// <typeparam name=\"G\">Original structure</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Naturally transformed structure</returns>\n    public static Memo<F, A> cotransform<F, G, A>(Memo<G, A> ma)\n        where F : CoNatural<F, G> =>\n        new(() => F.CoTransform(ma.Value));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Memo/Memo.cs",
    "content": "using System;\nusing System.Threading;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Lazily acquires a value and caches it for repeated use. \n/// </summary>\npublic class Memo<A>\n{\n    /// <summary>\n    /// Acquired value or null if not yet acquired\n    /// </summary>\n    internal A? value;\n\n    /// <summary>\n    /// Function to acquire the value\n    /// </summary>\n    internal Func<A>? acquire;\n    \n    /// <summary>\n    /// 0 = unloaded, 1 = loading, 2 = loaded\n    /// </summary>\n    internal int state;   \n    \n    /// <summary>\n    /// Construct a memo\n    /// </summary>\n    /// <param name=\"acq\">Value acquisition function</param>\n    internal Memo(A value)\n    {\n        this.value = value;\n        acquire = null;\n        state = 2;\n    }\n    \n    /// <summary>\n    /// Construct a memo\n    /// </summary>\n    /// <param name=\"acq\">Value acquisition function</param>\n    internal Memo(Func<A>? acq, A? value)\n    {\n        this.value = value;\n        this.acquire = acq;\n        state = 2;\n    }\n    \n    /// <summary>\n    /// Construct a memo\n    /// </summary>\n    /// <param name=\"acq\">Value acquisition function</param>\n    internal Memo(Func<A> acq)\n    {\n        value = default;\n        acquire = acq;\n        state = 0;\n    }\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public Memo<B> Map<B>(Func<A, B> f) =>\n        new (() => f(Value));\n\n    /// <summary>\n    /// Acquired value\n    /// </summary>\n    /// <remarks>\n    /// If the value is not yet acquired, it will be acquired within `Value` and cached.\n    /// </remarks>\n    public A Value =>\n        state == 2\n            ? value!\n            : GetValue();\n\n    /// <summary>\n    /// Create a clone of the memo (without any cached results).  This allows for reacquiring the value.\n    /// </summary>\n    /// <returns>A newly constructed memo structure</returns>\n    public Memo<A> Clone() =>\n        acquire is null\n            ? new Memo<A>(value!)\n            : new (acquire);\n    \n    /// <summary>\n    /// Reset the memo.  This clears the cached value. \n    /// </summary>\n    /// <returns>Unit</returns>\n    public Unit Reset()\n    {\n        if(acquire == null) return default;\n        SpinWait sw = default;\n        while (true)\n        {\n            switch (Interlocked.CompareExchange(ref state, 1, 2))\n            {\n                case 0:\n                    // unloaded\n                    return default;\n                \n                case 1:\n                    // currently unloading, so wait, then loop around and try again\n                    sw.SpinOnce();\n                    break;\n                \n                case 2:\n                    value = default;\n                    state = 0;\n                    return default;\n\n                default:\n                    throw new InvalidOperationException(\"Invalid state\");\n            }\n        }\n    }\n\n    /// <summary>\n    /// Acquisition function.  Called only if the value is not yet acquired.\n    /// </summary>\n    A GetValue()\n    {\n        SpinWait sw = default;\n        while (true)\n        {\n            switch (Interlocked.CompareExchange(ref state, 1, 0))\n            {\n                case 0:\n                    // value is not set yet, so try to set it\n                    try\n                    {\n                        value = acquire!();\n                        state = 2;\n                        return value;\n                    }\n                    catch\n                    {\n                        // if we fail, reset the state to 'not set yet'\n                        state = 0;\n                        throw;\n                    }\n\n                case 1:\n                    // currently loading, so wait, then loop around and try again\n                    sw.SpinOnce();\n                    break;\n\n                case 2:\n                    // value already set\n                    return value!;\n\n                default:\n                    throw new InvalidOperationException(\"Invalid state\");\n            }\n        }\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Memo/Operators/Memo.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class MemoExtensions\n{\n    extension<F, A>(Memo<F, A> self)\n    {\n        /// <summary>\n        /// Extract the cached value\n        /// </summary>\n        /// <param name=\"ma\">Memoisation structure</param>\n        /// <returns>Cached value</returns>\n        public static K<F, A> operator~(Memo<F, A> ma) =>\n            ma.Value;\n        \n    }\n\n    extension<A>(Memo<A> self)\n    {\n        /// <summary>\n        /// Extract the cached value\n        /// </summary>\n        /// <param name=\"ma\">Memoisation structure</param>\n        /// <returns>Cached value</returns>\n        public static A operator~(Memo<A> ma) =>\n            ma.Value;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Memo/Prelude.Memoize.cs",
    "content": "﻿using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Returns a `Memo〈A〉` that wraps a function.  The first\n    /// call to the resulting `Memo〈A〉` will cache the result.\n    /// Subsequent calls return the cached item.\n    /// </summary>\n    public static Memo<A> memo<A>(Func<A> f) =>\n        new (f);\n\n    /// <summary>\n    /// Create a preloaded memo structure with a pure value.  \n    /// </summary>\n    public static Memo<A> memo<A>(A value) =>\n        new (value);\n\n    /// <summary>\n    /// Returns a `Memo〈F, A〉` that wraps a function that yields a higher-kind `K〈F, A〉`.\n    /// The first call to the resulting `Memo〈F, A〉` will cache the resulting `K〈F, A〉`.\n    /// Subsequent calls return the cached item.\n    /// </summary>\n    /// <remarks>\n    /// NOTE: This does not invoke the `K〈F, A〉` computation, it merely caches the construction\n    /// of the `K〈F, A〉`. If `K〈F, A〉` itself is lazy, then it can be invoked multiple times;\n    /// this memoisation won't affect that.\n    /// </remarks>\n    public static Memo<F, A> memoK<F, A>(Func<K<F, A>> f) =>\n        new(f);\n\n    /// <summary>\n    /// Create a preloaded memo structure with a pure value\n    /// </summary>\n    public static Memo<F, A> memoK<F, A>(A value) \n        where F : Applicative<F> =>\n        new (F.Pure(value));\n\n    /// <summary>\n    /// Create a preloaded memo structure.  \n    /// </summary>\n    public static Memo<F, A> memoK<F, A>(K<F, A> fa) \n        where F : Applicative<F> =>\n        new (fa);\n    \n    /// <summary>\n    /// Returns a `Func〈A, B〉` that wraps func.  Each time the resulting\n    /// `Func〈A, B〉` is called with a new value, its result is memoized (cached).\n    /// Subsequent calls use the memoized value.  \n    /// \n    /// Remarks: \n    ///     Thread-safe and memory-leak safe.  \n    /// </summary>\n    public static Func<A, B> memo<A, B>(Func<A, B> func) where A : notnull\n    {\n        var cache   = new WeakDict<A, B> ();\n        var syncMap = new ConcurrentDictionary<A, object>();\n\n        return inp =>\n               {\n                   if(cache.TryGetValue(inp, out var x))\n                   {\n                       return x;\n                   }\n                   else\n                   {\n                       B   res;\n                       var sync = syncMap.GetOrAdd(inp, new object());\n                       lock (sync)\n                       {\n                           res = cache.GetOrAdd(inp, func);\n                       }\n                       syncMap.TryRemove(inp, out sync);\n                       return res;\n                   }\n               };\n    }\n\n    /// <summary>\n    /// Returns a Func〈T, R〉 that wraps func.  Each time the resulting\n    /// Func〈T, R〉 is called with a new value, its result is memoized (cached).\n    /// Subsequent calls use the memoized value.  \n    /// \n    /// Remarks: \n    ///     No mechanism for freeing cached values and therefore can cause a\n    ///     memory leak when holding onto the Func〈T, R〉 reference.\n    ///     Uses a ConcurrentDictionary for the cache and is thread-safe\n    /// </summary>\n    public static Func<T, R> memoUnsafe<T, R>(Func<T, R> func) where T : notnull\n    {\n        var cache   = new ConcurrentDictionary<T, R>();\n        var syncMap = new ConcurrentDictionary<T, object>();\n        return inp =>\n               {\n                   if (!cache.TryGetValue(inp, out var res))\n                   {\n                       var sync = syncMap.GetOrAdd(inp, new object());\n                       lock (sync)\n                       {\n                           res = cache.GetOrAdd(inp, func);\n                       }\n                       syncMap.TryRemove(inp, out sync);\n                   }\n                   return res;\n               };\n    }\n\n    /// <summary>\n    /// Enumerable memoization.  As an enumerable is enumerated each item is retained\n    /// in an internal list, so that future evalation of the enumerable isn't done. \n    /// Only items not seen before are evaluated.  \n    /// \n    /// This minimises one of the major problems with the IEnumerable / yield return \n    /// pattern by causing at-most-once evaluation of each item.  \n    /// \n    /// Use the IEnumerable extension method Memo for convenience.\n    /// </summary>\n    /// <remarks>\n    /// Although this allows efficient lazy evaluation, it does come at a memory cost.\n    /// Each item is cached internally, so this method doesn't allow for evaluation of\n    /// infinite sequences.\n    /// </remarks>\n    /// <param name=\"seq\">Enumerable to memoize</param>\n    /// <returns>IEnumerable with caching properties</returns>\n    public static Seq<T> memo<T>(IEnumerable<T> seq) =>\n        toSeq(seq);\n\n    /// <summary>\n    /// Used internally by the memo function.  It wraps a concurrent dictionary that has \n    /// its value objects wrapped in a WeakReference〈OnFinalise〈...〉〉\n    /// The OnFinalise type is a private class within WeakDict and does nothing but hold\n    /// the value and an Action to call when its finalised.  So when the WeakReference is\n    /// collected by the GC, it forces the finaliser to be called on the OnFinalise object,\n    /// which in turn executes the action which removes it from the ConcurrentDictionary.  \n    /// That means that both the key and value are collected when the GC fires rather than \n    /// just the value.  Mitigates memory leak of keys.\n    /// </summary>\n    private class WeakDict<T, R> where T : notnull\n    {\n        private class OnFinalise<V>(Action onFinalise, V value)\n        {\n            public readonly V Value = value;\n\n            ~OnFinalise() =>\n                onFinalise.Invoke();\n        }\n\n        ConcurrentDictionary<T, WeakReference<OnFinalise<R>>> dict = new ConcurrentDictionary<T, WeakReference<OnFinalise<R>>>();\n\n        private WeakReference<OnFinalise<R>> NewRef(T key, Func<T, R> addFunc) =>\n            new (new OnFinalise<R>(() => dict.TryRemove(key, out _), addFunc(key)));\n\n        public bool TryGetValue(T key, out R value)\n        {\n            if(dict.TryGetValue(key, out var res) && res.TryGetTarget(out var target))\n            {\n                value = target.Value;\n                return true;\n            }\n            else\n            {\n                value = default!;\n                return false;\n            }\n        }\n\n        public R GetOrAdd(T key, Func<T, R> addFunc)\n        {\n            var res = dict.GetOrAdd(key, _ => NewRef(key, addFunc));\n\n            if (res.TryGetTarget(out var target))\n            {\n                return target.Value;\n            }\n            else\n            {\n                var upd = NewRef(key, addFunc);\n                res = dict.AddOrUpdate(key, upd, (_, _) => upd);\n                if (res.TryGetTarget(out target))\n                {\n                    return target.Value;\n                }\n                else\n                {\n                    // This is a best guess of why the target can't be got.\n                    // It might not be the best approach, perhaps a retry, or a \n                    // better/more-descriptive exception.\n                    throw new OutOfMemoryException();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/ChronicleT.Module.2.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic partial class ChronicleT<Ch, M>\n{\n    /// <summary>\n    /// `dictate` is an action that records the output `value`.\n    /// Equivalent to `tell` for the `Writable` traits.\n    /// </summary>\n    /// <param name=\"value\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> dictate<A>(A value) =>\n        lift(That<Ch, A>(value));\n    \n    /// <summary>\n    /// `confess` is an action that ends with a final output `value`.\n    /// Equivalent to `fail` for the 'Fallible' trait.\n    /// </summary>\n    /// <param name=\"value\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> confess<A>(Ch value) =>\n        lift(This<Ch, A>(value));\n    \n    /// <summary>\n    /// Construct a new chronicle with `this` and `that`.\n    /// </summary>\n    /// <param name=\"@this\">Value to construct with</param>\n    /// <param name=\"that\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> chronicle<A>(Ch @this, A that) =>\n        lift(Both(@this, that));\n    \n    /// <summary>\n    /// Construct a new chronicle with `these`.\n    /// </summary>\n    /// <param name=\"these\">What to chronicle</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> lift<A>(These<Ch, A> these) =>\n        new(_ => M.Pure(these));\n\n    /// <summary>\n    /// Lift a monad `M` into the monad-transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> lift<A>(K<M, A> ma) =>\n        new(_ =>ma.Map(That<Ch, A>));\n    \n    /// <summary>\n    /// Lift an `IO` monad into the monad-transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> liftIO<A>(K<IO, A> ma) =>\n        lift(M.LiftIOMaybe(ma));\n\n    /// <summary>\n    /// `Memento` is an action that executes the action within this structure, returning either\n    /// its record, if it ended with `Confess`, or its final value otherwise, with any record\n    /// added to the current record.\n    ///\n    /// Similar to 'Catch' in the 'Fallible' trait, but with a notion of non-fatal errors (which\n    /// are accumulated) vs. fatal errors (which are caught without accumulating).\n    /// </summary>\n    public static ChronicleT<Ch, M, Either<Ch, A>> memento<A>(K<ChronicleT<Ch, M>, A> ma) =>\n        ma.As().Memento();\n    \n    /// <summary>\n    /// `absolve` is an action that executes this structure and discards any record it had.\n    /// The `defaultValue` will be used if the action ended via `Confess`. \n    /// </summary>\n    /// <param name=\"defaultValue\"></param>\n    public static ChronicleT<Ch, M, A> absolve<A>(A defaultValue, K<ChronicleT<Ch, M>, A> ma) =>\n        ma.As().Absolve(defaultValue);\n\n    /// <summary>\n    /// `Condemn` is an action that executes the structure and keeps its value\n    /// only if it had no record. Otherwise, the value (if any) will be discarded\n    /// and only the record kept.\n    /// \n    /// This can be seen as converting non-fatal errors into fatal ones.\n    /// </summary>\n    public static ChronicleT<Ch, M, A> condemn<A>(K<ChronicleT<Ch, M>, A> ma) =>\n        ma.As().Condemn();\n    \n    /// <summary>\n    /// An action that executes the structure and applies the function `f` to its output, leaving\n    /// the return value unchanged.-\n    /// </summary>\n    /// <remarks>\n    /// Equivalent to `censor` for the 'Writable` trait.\n    /// </remarks>\n    /// <param name=\"f\">Censoring function</param>\n    public static ChronicleT<Ch, M, A> censor<A>(Func<Ch, Ch> f, K<ChronicleT<Ch, M>, A> ma) =>\n        ma.As().Censor(f);\n\n    /// <summary>\n    /// Access to the internal semigroup instance. \n    /// </summary>\n    internal static readonly ChronicleT<Ch, M, SemigroupInstance<Ch>> semigroup = \n        new (semi => M.Pure(That<Ch, SemigroupInstance<Ch>>(semi)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/ChronicleT.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class ChronicleT\n{\n    /// <summary>\n    /// Monoid empty confession\n    /// </summary>\n    /// <typeparam name=\"Ch\">Chronicle type (a monoid)</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ChronicleT<Ch, M, A> empty<Ch, M, A>()\n        where Ch : Monoid<Ch>\n        where M : Monad<M> =>\n        confess<Ch, M, A>(Ch.Empty);\n    \n    /// <summary>\n    /// `dictate` is an action that records the output `value`.\n    /// Equivalent to `tell` for the `Writable` traits.\n    /// </summary>\n    /// <param name=\"value\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> dictate<Ch, M, A>(A value) \n        where M : Monad<M> =>\n        new(_ => M.Pure(That<Ch, A>(value)));\n    \n    /// <summary>\n    /// `confess` is an action that ends with a final output `value`.\n    /// Equivalent to `fail` for the 'Fallible' trait.\n    /// </summary>\n    /// <param name=\"value\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> confess<Ch, M, A>(Ch value) \n        where M : Monad<M> =>\n        new(_ => M.Pure(This<Ch, A>(value)));\n    \n    /// <summary>\n    /// Construct a new chronicle with `this` and `that`.\n    /// </summary>\n    /// <param name=\"@this\">Value to construct with</param>\n    /// <param name=\"that\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> chronicle<Ch, M, A>(Ch @this, A that) \n        where M : Monad<M> =>\n        new(_ => M.Pure(Both(@this, that)));\n    \n    /// <summary>\n    /// Construct a new chronicle with `these`.\n    /// </summary>\n    /// <param name=\"these\">What to chronicle</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> chronicle<Ch, M, A>(These<Ch, A> these) \n        where M : Monad<M> =>\n        new(_ => M.Pure(these));\n\n    /// <summary>\n    /// Lift a monad `M` into the monad-transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> lift<Ch, M, A>(K<M, A> ma)\n        where M : Monad<M> =>\n        new(_ =>ma.Map(That<Ch, A>));\n    \n    /// <summary>\n    /// Lift an `IO` monad into the monad-transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> liftIO<Ch, M, A>(K<IO, A> ma)\n        where M : Monad<M> =>\n        lift<Ch, M, A>(M.LiftIOMaybe(ma));\n\n    /// <summary>\n    /// `Memento` is an action that executes the action within this structure, returning either\n    /// its record, if it ended with `Confess`, or its final value otherwise, with any record\n    /// added to the current record.\n    ///\n    /// Similar to 'Catch' in the 'Fallible' trait, but with a notion of non-fatal errors (which\n    /// are accumulated) vs. fatal errors (which are caught without accumulating).\n    /// </summary>\n    public static ChronicleT<Ch, M, Either<Ch, A>> memento<Ch, M, A>(K<ChronicleT<Ch, M>, A> ma)\n        where M : Monad<M> =>\n        ma.As().Memento();\n    \n    /// <summary>\n    /// `absolve` is an action that executes this structure and discards any record it had.\n    /// The `defaultValue` will be used if the action ended via `Confess`. \n    /// </summary>\n    /// <param name=\"defaultValue\"></param>\n    public static ChronicleT<Ch, M, A> absolve<Ch, M, A>(A defaultValue, K<ChronicleT<Ch, M>, A> ma) \n        where M : Monad<M> =>\n        ma.As().Absolve(defaultValue);\n\n    /// <summary>\n    /// `Condemn` is an action that executes the structure and keeps its value\n    /// only if it had no record. Otherwise, the value (if any) will be discarded\n    /// and only the record kept.\n    /// \n    /// This can be seen as converting non-fatal errors into fatal ones.\n    /// </summary>\n    public static ChronicleT<Ch, M, A> condemn<Ch, M, A>(K<ChronicleT<Ch, M>, A> ma) \n        where M : Monad<M> =>\n        ma.As().Condemn();\n    \n    /// <summary>\n    /// An action that executes the structure and applies the function `f` to its output, leaving\n    /// the return value unchanged.-\n    /// </summary>\n    /// <remarks>\n    /// Equivalent to `censor` for the 'Writable` trait.\n    /// </remarks>\n    /// <param name=\"f\">Censoring function</param>\n    public static ChronicleT<Ch, M, A> censor<Ch, M, A>(Func<Ch, Ch> f, K<ChronicleT<Ch, M>, A> ma) \n        where M : Monad<M> =>\n        ma.As().Censor(f);\n\n    /// <summary>\n    /// Access to the internal semigroup instance. \n    /// </summary>\n    internal static ChronicleT<Ch, M, SemigroupInstance<Ch>> semigroup<Ch, M>()\n        where M : Monad<M> =>\n        ChronicleT<Ch, M>.semigroup;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/ChronicleT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing NSE = System.NotSupportedException;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// The `ChronicleT` monad transformer. \n/// </summary>\n/// <remarks>\n/// Hybrid error/writer monad class that allows both accumulating outputs and aborting computation with a final output.\n/// \n/// The expected use case is for computations with a notion of fatal vs. non-fatal errors.\n/// </remarks>\n/// <remarks>\n/// The 'pure' function produces a computation with no output, and `Bind` combines multiple\n/// outputs with semigroup combine.\n/// </remarks>\n/// <param name=\"runChronicleT\">Composed monadic type</param>\n/// <typeparam name=\"Ch\">Chronicle type</typeparam>\n/// <typeparam name=\"M\">Monad type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record ChronicleT<Ch, M, A>(Func<SemigroupInstance<Ch>, K<M, These<Ch, A>>> runChronicleT) : \n    K<ChronicleT<Ch, M>, A>,\n    K<ChronicleT<M>, Ch, A>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Run the chronicle to yield its inner monad\n    /// </summary>\n    /// <param name=\"f\">Semigroup combine operation</param>\n    public K<M, These<Ch, A>> Run(SemigroupInstance<Ch> trait) =>\n        runChronicleT(trait);    \n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Resulting bound value type</typeparam>\n    /// <returns>Mapped structure</returns>\n    public ChronicleT<Ch, M, B> Map<B>(Func<A, B> f) =>\n        new(c => runChronicleT(c).Map(these => these.Map(f)));\n\n    /// <summary>\n    /// Bifunctor map operation\n    /// </summary>\n    /// <param name=\"This\">Chronicle mapping function</param>\n    /// <param name=\"That\">Dictation mapping function</param>\n    /// <typeparam name=\"Ch1\">Chronicle type to map to</typeparam>\n    /// <returns></returns>\n    public ChronicleT<Ch1, M, B> BiMap<Ch1, B>(Func<Ch, Ch1> This, Func<A, B> That)\n        where Ch1 : Semigroup<Ch1> =>\n        Bifunctor.bimap(This, That, this).As2();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Resulting bound value type</typeparam>\n    /// <returns>Mapped structure</returns>\n    public ChronicleT<Ch, M, B> Select<B>(Func<A, B> f) =>\n        new(c => runChronicleT(c).Map(these => these.Map(f)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Chaining function</param>\n    /// <returns>Chained structure</returns>\n    public ChronicleT<Ch, M, B> Bind<B>(Func<A, K<ChronicleT<Ch, M>, B>> f) =>\n        new(t =>\n                Run(t)\n                   .Bind(cx => cx switch\n                               {\n                                   These<Ch, A>.This (var c) =>\n                                       M.Pure(This<Ch, B>(c)),\n\n                                   These<Ch, A>.That (var x) =>\n                                       f(x).As().Run(t),\n\n                                   These<Ch, A>.Both (var c1, var x) =>\n                                       f(x).As()\n                                           .Run(t)\n                                           .Map(cy => cy switch\n                                                      {\n                                                          These<Ch, B>.This (var c2) => This<Ch, B>(t.Combine(c1, c2)),\n                                                          These<Ch, B>.That (var b)  => Both(c1, b),\n                                                          These<Ch, B>.Both (var c2, var b) => Both(t.Combine(c1, c2), b),\n                                                          _ => throw new NSE()\n                                                      }),\n\n                                   _ => throw new NSE()\n                               }));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Chaining function</param>\n    /// <returns>Chained structure</returns>\n    public ChronicleT<Ch1, M, A> BindFirst<Ch1>(Func<Ch, K<ChronicleT<M>, Ch1, A>> f)\n        where Ch1 : Semigroup<Ch1> =>\n        Bimonad.bindFirst(this, f).As2();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Chaining function</param>\n    /// <returns>Chained structure</returns>\n    public ChronicleT<Ch, M, B> BindSecond<B>(Func<A, K<ChronicleT<M>, Ch, B>> f) =>\n        Bimonad.bindSecond(this, f).As2();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Chaining function</param>\n    /// <typeparam name=\"B\">Resulting bound value type</typeparam>\n    /// <returns>Chained structure</returns>\n    public ChronicleT<Ch, M, C> SelectMany<B, C>(Func<A, K<ChronicleT<Ch, M>, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Chaining function</param>\n    /// <typeparam name=\"B\">Resulting bound value type</typeparam>\n    /// <returns>Chained structure</returns>\n    public ChronicleT<Ch, M, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        Bind(x => ChronicleT.liftIO<Ch, M, B>(bind(x)).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Chaining function</param>\n    /// <typeparam name=\"B\">Resulting bound value type</typeparam>\n    /// <returns>Chained structure</returns>\n    public ChronicleT<Ch, M, C> SelectMany<C>(Func<A, Guard<Ch, Unit>> bind, Func<A, Unit, C> project) =>\n        Bind(x => bind(x).ToChronicleT<Ch, M>().Map(y => project(x, y)));\n\n    /// <summary>\n    /// `Memento` is an action that executes the action within this structure, returning either\n    /// its record, if it ended with `Confess`, or its final value otherwise, with any record\n    /// added to the current record.\n    ///\n    /// Similar to 'Catch' in the 'Fallible' trait, but with a notion of non-fatal errors (which\n    /// are accumulated) vs. fatal errors (which are caught without accumulating).\n    /// </summary>\n    public ChronicleT<Ch, M, Either<Ch, A>> Memento() =>\n        new(combine =>\n            Run(combine).Map(these => these switch\n                                      {\n                                          These<Ch, A>.This (var c)        => That<Ch, Either<Ch, A>>(Either.Left<Ch, A>(c)),\n                                          These<Ch, A>.That (var x)        => That<Ch, Either<Ch, A>>(Either.Right<Ch, A>(x)),\n                                          These<Ch, A>.Both (var c, var x) => Both(c, Either.Right<Ch, A>(x)),\n                                          _                                => throw new NSE()\n                                      }));\n\n    /// <summary>\n    /// `Absolve` is an action that executes this structure and discards any record it had.\n    /// The `defaultValue` will be used if the action ended via `Confess`. \n    /// </summary>\n    /// <param name=\"defaultValue\"></param>\n    public ChronicleT<Ch, M, A> Absolve(A defaultValue) =>\n        new(combine => Run(combine).Map(these => these switch\n                                                 {\n                                                     These<Ch, A>.This            => That<Ch, A>(defaultValue),\n                                                     These<Ch, A>.That (var x)    => That<Ch, A>(x),\n                                                     These<Ch, A>.Both (_, var x) => That<Ch, A>(x),\n                                                     _                            => throw new NSE()\n                                                 }));\n\n    /// <summary>\n    /// This can be seen as converting non-fatal errors into fatal ones.\n    /// \n    /// `Condemn` is an action that executes the structure and keeps its value\n    /// only if it had no record. Otherwise, the value (if any) will be discarded\n    /// and only the record kept.\n    /// </summary>\n    public ChronicleT<Ch, M, A> Condemn() =>\n        new(combine => Run(combine).Map(these => these switch\n                                                 {\n                                                     These<Ch, A>.This (var c)    => This<Ch, A>(c),\n                                                     These<Ch, A>.That (var x)    => That<Ch, A>(x),\n                                                     These<Ch, A>.Both (var c, _) => This<Ch, A>(c),\n                                                     _                            => throw new NSE()\n                                                 }));\n\n    /// <summary>\n    /// An action that executes the structure and applies the function `f` to its output, leaving\n    /// the return value unchanged.-\n    /// </summary>\n    /// <remarks>\n    /// Equivalent to `censor` for the 'Writable` trait.\n    /// </remarks>\n    /// <param name=\"f\">Censoring function</param>\n    public ChronicleT<Ch, M, A> Censor(Func<Ch, Ch> f) =>\n        new(combine => Run(combine).Map(these => these switch\n                                                 {\n                                                     These<Ch, A>.This (var c)        => This<Ch, A>(f(c)),\n                                                     These<Ch, A>.That (var x)        => That<Ch, A>(x),\n                                                     These<Ch, A>.Both (var c, var x) => Both(f(c), x),\n                                                     _                                => throw new NSE()\n                                                 }));\n\n    /// <summary>\n    /// Coalescing operation\n    /// </summary>\n    public ChronicleT<Ch, M, A> Choose(K<ChronicleT<Ch, M>, A> rhs) =>\n        Memento()\n           .Bind(x => x switch\n                      {\n                          Either<Ch, A>.Left         => rhs,\n                          Either<Ch, A>.Right(var r) => dictate<Ch, M, A>(r),\n                          _                          => throw new NSE()\n                      });\n\n    /// <summary>\n    /// Coalescing operation\n    /// </summary>\n    public ChronicleT<Ch, M, A> Choose(Memo<ChronicleT<Ch, M>, A> rhs) =>\n        Memento()\n           .Bind(x => x switch\n                      {\n                          Either<Ch, A>.Left         => rhs.Value,\n                          Either<Ch, A>.Right(var r) => dictate<Ch, M, A>(r),\n                          _                          => throw new NSE()\n                      });\n    \n    /// <summary>\n    /// Fallible error catching operation\n    /// </summary>\n    /// <param name=\"Predicate\"></param>\n    /// <param name=\"Fail\"></param>\n    /// <returns></returns>\n    public ChronicleT<Ch, M, A> Catch(Func<Ch, bool> Predicate, Func<Ch, K<ChronicleT<Ch, M>, A>> Fail) =>\n        Memento()\n           .Bind(x => x switch\n                      {\n                          Either<Ch, A>.Left (var e) => Predicate(e) ? Fail(e) : confess<Ch, M, A>(e),\n                          Either<Ch, A>.Right(var r) => dictate<Ch, M, A>(r),\n                          _                          => throw new NSE()\n                      });\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Extensions/ChronicleT.Extensions.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude; \n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    /// <summary>\n    /// Downcast operator\n    /// </summary>\n    [Pure]\n    public static ChronicleT<Ch, M, A> As<Ch, M, A>(this K<ChronicleT<Ch, M>, A> ma) \n        where M : Monad<M> =>\n        (ChronicleT<Ch, M, A>)ma;\n    \n    /// <summary>\n    /// Downcast operator\n    /// </summary>\n    [Pure]\n    public static ChronicleT<Ch, M, A> As2<Ch, M, A>(this K<ChronicleT<M>, Ch, A> ma) \n        where M : Monad<M> =>\n        (ChronicleT<Ch, M, A>)ma;\n    \n    /// <summary>\n    /// Run the chronicle to yield its inner monad\n    /// </summary>\n    [Pure]\n    public static K<M, These<Ch, A>> Run<Ch, M, A>(this K<ChronicleT<Ch, M>, A> ma)\n        where Ch : Semigroup<Ch>\n        where M : Monad<M> =>\n        ma.As().Run(Ch.Instance);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static ChronicleT<Ch, M, A> Flatten<Ch, M, A>(this ChronicleT<Ch, M, ChronicleT<Ch, M, A>> mma)\n        where M : Monad<M> =>\n        mma.Bind(identity);\n\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <param name=\"f\">Dictation mapping function</param>\n    /// <typeparam name=\"B\">Dictation type to map to</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static ChronicleT<Ch, M, B> BiMap<Ch, M, A, B>(\n        this ChronicleT<Ch, M, A> ma, \n        Func<A, B> f)\n        where Ch : Semigroup<Ch> \n        where M : Monad<M> =>\n        ma.As().Map(f);\n\n    /// <summary>\n    /// Bifunctor map operation\n    /// </summary>\n    /// <param name=\"This\">Chronicle mapping function</param>\n    /// <param name=\"That\">Dictation mapping function</param>\n    /// <typeparam name=\"Ch1\">Chronicle type to map to</typeparam>\n    /// <typeparam name=\"B\">Dictation type to map to</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static ChronicleT<Ch1, M, B> BiMap<Ch, Ch1, M, A, B>(\n        this ChronicleT<Ch, M, A> ma, \n        Func<Ch, Ch1> This, \n        Func<A, B> That)\n        where Ch : Semigroup<Ch> \n        where Ch1 : Semigroup<Ch1> \n        where M : Monad<M> =>\n        Bifunctor.bimap(This, That, ma).As2();\n\n    /// <summary>\n    /// Filtering based on predicate.  \n    /// </summary>\n    /// <remarks>>\n    /// If the predicate returns false, then `ChronicleT.empty()` is yielded and therefore `Ch` must be a monoid.  \n    /// </remarks>\n    [Pure]\n    public static ChronicleT<Ch, M, A> Where<Ch, M, A>(this K<ChronicleT<Ch, M>, A> ma, Func<A, bool> pred)\n        where Ch : Monoid<Ch>\n        where M : Monad<M> =>\n        ma.Filter(pred);\n\n    /// <summary>\n    /// Filtering based on predicate.  \n    /// </summary>\n    /// <remarks>>\n    /// If the predicate returns false, then `ChronicleT.empty()` is yielded and therefore `Ch` must be a monoid.  \n    /// </remarks>\n    [Pure]\n    public static ChronicleT<Ch, M, A> Filter<Ch, M, A>(this K<ChronicleT<Ch, M>, A> ma, Func<A, bool> pred)\n        where Ch : Monoid<Ch>\n        where M : Monad<M> =>\n        ma.As().Bind(x => pred(x) ? ChronicleT.dictate<Ch, M, A>(x) : ChronicleT.empty<Ch, M, A>());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"A\">Source bound value type</typeparam>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    [Pure]\n    public static ChronicleT<Ch, M, C> SelectMany<Ch, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<ChronicleT<Ch, M>, B>> bind, \n        Func<A, B, C> project)\n        where Ch : Semigroup<Ch>\n        where M : Monad<M> =>\n        ChronicleT.lift<Ch, M, A>(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"A\">Source bound value type</typeparam>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    [Pure]\n    public static ChronicleT<Ch, M, C> SelectMany<Ch, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, ChronicleT<Ch, M, B>> bind, \n        Func<A, B, C> project)\n        where Ch : Semigroup<Ch>\n        where M : Monad<M> =>\n        ChronicleT.lift<Ch, M, A>(ma).SelectMany(bind, project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Extensions/ChronicleT.Guard.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class ChronicleTGuardExtensions\n{\n    \n    /// <summary>\n    /// Natural transformation to `ChronicleT`\n    /// </summary>\n    public static ChronicleT<Ch, M, Unit> ToChronicleT<Ch, M>(this Guard<Ch, Unit> guard)\n        where M :  Monad<M> =>\n        guard.Flag\n            ? ChronicleT.dictate<Ch, M, Unit>(default)\n            : ChronicleT.confess<Ch, M, Unit>(guard.OnFalse());\n \n    /// <summary>\n    /// Monadic binding support for `ChronicleT`\n    /// </summary>\n    public static ChronicleT<Ch, M, B> Bind<Ch, M, B>(\n        this Guard<Ch, Unit> guard,\n        Func<Unit, ChronicleT<Ch, M, B>> f) \n        where M : Monad<M> =>\n        guard.Flag\n            ? f(default).As()\n            : ChronicleT.confess<Ch, M, B>(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `ChronicleT`\n    /// </summary>\n    public static ChronicleT<Ch, M, C> SelectMany<Ch, M, B, C>(\n        this Guard<Ch, Unit> guard,\n        Func<Unit, ChronicleT<Ch, M, B>> bind, \n        Func<Unit, B, C> project) \n        where M : Monad<M> =>\n        guard.Flag\n            ? bind(default).Map(b => project(default, b)).As()\n            : ChronicleT.confess<Ch, M, C>(guard.OnFalse());    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Operators/ChronicleT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    extension<Ch, M, A, B>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static ChronicleT<Ch, M, B> operator >>> (K<ChronicleT<Ch, M>, A> ma, K<ChronicleT<Ch, M>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, B> operator * (K<ChronicleT<Ch, M>, Func<A, B>> mf, K<ChronicleT<Ch, M>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, B> operator * (K<ChronicleT<Ch, M>, A> ma, K<ChronicleT<Ch, M>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<Ch, M, A, B, C>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, C>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, C>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<Ch, M, A, B, C, D>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, D>>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C, D>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, D>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<Ch, M, A, B, C, D, E>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<Ch, M, A, B, C, D, E, F>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<Ch, M, A, B, C, D, E, F, G>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<Ch, M, A, B, C, D, E, F, G, H>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<Ch, M, A, B, C, D, E, F, G, H, I>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<Ch, M, A, B, C, D, E, F, G, H, I, J>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<Ch, M, A, B, C, D, E, F, G, H, I, J, K>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<ChronicleT<Ch, M>, A> ma,\n            K<ChronicleT<Ch, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Operators/ChronicleT.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    extension<Ch, M, A>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        public static ChronicleT<Ch, M, A> operator |(K<ChronicleT<Ch, M>, A> lhs, K<ChronicleT<Ch, M>, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static ChronicleT<Ch, M, A> operator |(K<ChronicleT<Ch, M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(ChronicleT.chronicle<Ch, M, A>(rhs.ToThese<Ch>()));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Operators/ChronicleT.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    extension<Ch, M, A>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        public static ChronicleT<Ch, M, A> operator |(K<ChronicleT<Ch, M>, A> lhs, CatchM<Ch, ChronicleT<Ch, M>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static ChronicleT<Ch, M, A> operator |(K<ChronicleT<Ch, M>, A> lhs, Fail<Ch> rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Operators/ChronicleT.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class ChronicleTExtensions\n{\n    extension<X, Ch, M, A>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>, Final<M>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static ChronicleT<Ch, M, A> operator |(K<ChronicleT<Ch, M>, A> lhs, Finally<M, X> rhs) =>\n            new (semi => lhs.As().runChronicleT(semi).Finally(rhs.Operation));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Operators/ChronicleT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    extension<Ch, M, A, B>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, B> operator *(Func<A, B> f, K<ChronicleT<Ch, M>, A> ma) =>\n            ma.Map(f).As();\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, B> operator *(K<ChronicleT<Ch, M>, A> ma, Func<A, B> f) =>\n            ma.Map(f).As();\n    }\n    \n    extension<Ch, M, A, B, C>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, C>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n        \n    }\n        \n    extension<Ch, M, A, B, C, D>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, D>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<Ch, M, A, B, C, D, E>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<Ch, M, A, B, C, D, E, F>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<Ch, M, A, B, C, D, E, F, G>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<Ch, M, A, B, C, D, E, F, G, H>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n        \n    }\n                        \n    extension<Ch, M, A, B, C, D, E, F, G, H, I>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<Ch, M, A, B, C, D, E, F, G, H, I, J>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<Ch, M, A, B, C, D, E, F, G, H, I, J, K>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<ChronicleT<Ch, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ChronicleT<Ch, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<ChronicleT<Ch, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Operators/ChronicleT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    extension<Ch, M, A, B>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static ChronicleT<Ch, M, B> operator >> (K<ChronicleT<Ch, M>, A> ma, Func<A, K<ChronicleT<Ch, M>, B>> f) =>\n            ma.Bind(f).As();\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static ChronicleT<Ch, M, B> operator >> (K<ChronicleT<Ch, M>, A> lhs, K<ChronicleT<Ch, M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<Ch, M, A, B>(K<ChronicleT<Ch, M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static ChronicleT<Ch, M, B> operator >> (K<ChronicleT<Ch, M>, A> ma, Func<A, K<IO, B>> f) =>\n            +ma.Bind(x => +f(x));\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static ChronicleT<Ch, M, B> operator >> (K<ChronicleT<Ch, M>, A> lhs, K<IO, B> rhs) =>\n            lhs >> (_ => rhs);\n    }    \n    \n    extension<Ch, M, A>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static ChronicleT<Ch, M, A> operator >> (K<ChronicleT<Ch, M>, A> lhs, K<ChronicleT<Ch, M>, Unit> rhs) =>\n            lhs >> (x => rhs * (_ => x));\n    }\n    \n    extension<Ch, M, A>(K<ChronicleT<Ch, M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static ChronicleT<Ch, M, A> operator >> (K<ChronicleT<Ch, M>, A> lhs, K<IO, Unit> rhs) =>\n            lhs >> (x => rhs * (_ => x));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Operators/ChronicleT.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    extension<Ch, M, A>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ChronicleT<Ch, M, A> operator +(K<ChronicleT<Ch, M>, A> lhs, K<ChronicleT<Ch, M>, A> rhs) =>\n            new (semi => lhs.As().runChronicleT(semi) + rhs.As().runChronicleT(semi));\n    }\n\n    extension<Ch, M, A>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Applicative<M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ChronicleT<Ch, M, A> operator +(K<ChronicleT<Ch, M>, A> lhs, Pure<A> rhs) =>\n            new(semi => lhs.As().runChronicleT(semi) + M.Pure(These.That<Ch, A>(rhs.Value)));\n    }\n    \n    extension<E, Ch, M, A>(K<ChronicleT<Ch, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Fallible<E, M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ChronicleT<Ch, M, A> operator +(K<ChronicleT<Ch, M>, A> lhs, Fail<E> rhs) =>\n            new (semi => lhs.As().runChronicleT(semi) + M.Fail<These<Ch, A>>(rhs.Value));\n\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Operators/ChronicleT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    extension<Ch, M, A>(K<ChronicleT<Ch, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static ChronicleT<Ch, M, A> operator +(K<ChronicleT<Ch, M>, A> ma) =>\n            (ChronicleT<Ch, M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static ChronicleT<Ch, M, A> operator >> (K<ChronicleT<Ch, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Prelude/ChronicleT.Prelude.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Prelude\n{\n    /// <summary>\n    /// `dictate` is an action that records the output `value`.\n    /// Equivalent to `tell` for the `Writable` traits.\n    /// </summary>\n    /// <remarks>\n    /// This is 'Applicative.Pure'.\n    /// </remarks>\n    /// <param name=\"value\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> dictate<Ch, M, A>(A value) \n        where M : Monad<M> =>\n        ChronicleT.dictate<Ch, M, A>(value);\n    \n    /// <summary>\n    /// `confess` is an action that ends with a final output `value`.\n    /// Equivalent to `fail` for the 'Fallible' trait.\n    /// </summary>\n    /// <remarks>\n    /// This is akin to yielding an error.\n    /// </remarks>\n    /// <param name=\"value\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> confess<Ch, M, A>(Ch value) \n        where M : Monad<M> =>\n        ChronicleT.confess<Ch, M, A>(value);\n    \n    /// <summary>\n    /// Construct a new chronicle with `this` and `that`.\n    /// </summary>\n    /// <param name=\"@this\">Value to construct with</param>\n    /// <param name=\"that\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> chronicle<Ch, M, A>(Ch @this, A that) \n        where M : Monad<M> =>\n        ChronicleT.chronicle<Ch, M, A>(@this, that);\n    \n    /// <summary>\n    /// Construct a new chronicle with `these`.\n    /// </summary>\n    /// <param name=\"these\">What to chronicle</param>\n    /// <returns>Chronicle structure</returns>\n    public static ChronicleT<Ch, M, A> chronicle<Ch, M, A>(These<Ch, A> these) \n        where M : Monad<M> =>\n        ChronicleT.chronicle<Ch, M, A>(these);\n    \n    /// <summary>\n    /// `Memento` is an action that executes the action within this structure, returning either\n    /// its record, if it ended with `Confess`, or its final value otherwise, with any record\n    /// added to the current record.\n    ///\n    /// Similar to 'Catch' in the 'Fallible' trait, but with a notion of non-fatal errors (which\n    /// are accumulated) vs. fatal errors (which are caught without accumulating).\n    /// </summary>\n    public static ChronicleT<Ch, M, Either<Ch, A>> memento<Ch, M, A>(K<ChronicleT<Ch, M>, A> ma)\n        where M : MonadIO<M> =>\n        ma.As().Memento();\n    \n    /// <summary>\n    /// `absolve` is an action that executes this structure and discards any record it had.\n    /// The `defaultValue` will be used if the action ended via `Confess`. \n    /// </summary>\n    /// <param name=\"defaultValue\"></param>\n    public static ChronicleT<Ch, M, A> absolve<Ch, M, A>(A defaultValue, K<ChronicleT<Ch, M>, A> ma) \n        where M : MonadIO<M> =>\n        ma.As().Absolve(defaultValue);\n\n    /// <summary>\n    /// `Condemn` is an action that executes the structure and keeps its value\n    /// only if it had no record. Otherwise, the value (if any) will be discarded\n    /// and only the record kept.\n    /// \n    /// This can be seen as converting non-fatal errors into fatal ones.\n    /// </summary>\n    public static ChronicleT<Ch, M, A> condemn<Ch, M, A>(K<ChronicleT<Ch, M>, A> ma) \n        where M : MonadIO<M> =>\n        ma.As().Condemn();\n    \n    /// <summary>\n    /// An action that executes the structure and applies the function `f` to its output, leaving\n    /// the return value unchanged.-\n    /// </summary>\n    /// <remarks>\n    /// Equivalent to `censor` for the 'Writable` trait.\n    /// </remarks>\n    /// <param name=\"f\">Censoring function</param>\n    public static ChronicleT<Ch, M, A> censor<Ch, M, A>(Func<Ch, Ch> f, K<ChronicleT<Ch, M>, A> ma) \n        where M : MonadIO<M> =>\n        ma.As().Censor(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Trait/ChronicleT.TraitImpl.2.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing NSE = System.NotSupportedException;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `ChronicleT` trait implementations\n/// </summary>\n/// <typeparam name=\"M\">Lifted monad type</typeparam>\npublic class ChronicleT<M> :  \n    CoproductK<ChronicleT<M>>,\n    Bimonad<ChronicleT<M>> \n    where M : Monad<M>\n{\n    static K<ChronicleT<M>, A, B> CoproductCons<ChronicleT<M>>.Left<A, B>(A value) => \n        ChronicleT.confess<A, M, B>(value);\n\n    static K<ChronicleT<M>, A, B> CoproductCons<ChronicleT<M>>.Right<A, B>(B value) => \n        ChronicleT.dictate<A, M, B>(value);\n\n    static K<ChronicleT<M>, A, C> CoproductK<ChronicleT<M>>.Match<A, B, C>(\n        Func<A, C> Left, \n        Func<B, C> Right, \n        K<ChronicleT<M>, A, B> fab) => \n        fab.As2().Memento().Map(ea => ea.Match(Left, Right));\n\n    static K<ChronicleT<M>, Y, B> Bifunctor<ChronicleT<M>>.BiMap<X, A, Y, B>(\n        Func<X, Y> first,\n        Func<A, B> second,\n        K<ChronicleT<M>, X, A> fab) =>\n        new ChronicleT<Y, M, B>(\n            _ => SemigroupInstance<X>.Instance switch\n             {\n                 { IsSome: true, Value: { } t } =>\n                     fab.As2()\n                        .Run(t)\n                        .Map(ch => ch switch\n                                   {\n                                       These<X, A>.This (var x) => This<Y, B>(\n                                           first(x)),\n                                       These<X, A>.That (var a) => That<Y, B>(\n                                           second(a)),\n                                       These<X, A>.Both (var x, var a) => Both(\n                                           first(x), second(a)),\n                                       _ => throw new NSE()\n                                   }),\n                 _ => throw new NSE($\"Type {typeof(X).Name} is not a valid semigroup\")\n             });\n\n    static K<ChronicleT<M>, Y, A> Bimonad<ChronicleT<M>>.BindFirst<X, Y, A>(\n        K<ChronicleT<M>, X, A> ma,\n        Func<X, K<ChronicleT<M>, Y, A>> f) =>\n        new ChronicleT<Y, M, A>(ty => SemigroupInstance<X>.Instance switch\n                                      {\n                                          { IsSome: true, Value: { } tx } =>\n                                              ma.As2()\n                                                .Run(tx)\n                                                .Bind(ch => ch switch\n                                                            {\n                                                                These<X, A>.This (var x) =>\n                                                                    f(x).As2().Run(ty),\n\n                                                                These<X, A>.That (var a) => M.Pure(\n                                                                    That<Y, A>(a)),\n\n                                                                These<X, A>.Both (var x, var a) =>\n                                                                    f(x).As2().Run(ty).Map(ch1 =>\n                                                                                ch1 switch\n                                                                                {\n                                                                                    These<Y, A>.This (var y1) =>\n                                                                                        Both(y1, a),\n\n                                                                                    These<Y, A>.That (var a1) =>\n                                                                                        That<Y, A>(a1),\n\n                                                                                    These<Y, A>.Both (var y1, var a1) =>\n                                                                                        Both(y1, a1),\n\n                                                                                    _ => throw new NSE()\n                                                                                }),\n                                                                _ => throw new NSE()\n                                                            }),\n\n                                          _ => throw new NSE($\"Type {typeof(X).Name} is not a valid semigroup\")\n                                      });\n\n    static K<ChronicleT<M>, X, B> Bimonad<ChronicleT<M>>.BindSecond<X, A, B>(\n        K<ChronicleT<M>, X, A> ma,\n        Func<A, K<ChronicleT<M>, X, B>> f) =>\n        new ChronicleT<X, M, B>(\n            tx => ma.As2()\n                    .Run(tx)\n                    .Bind(ch => ch switch\n                                {\n                                    These<X, A>.This (var x) =>\n                                        M.Pure(This<X, B>(x)),\n\n                                    These<X, A>.That (var a) => \n                                        f(a).As2().Run(tx),\n                                                      \n                                    These<X, A>.Both (var x, var a) =>\n                                        f(a).As2().Run(tx).Map(ch1 =>\n                                                                   ch1 switch\n                                                                   {\n                                                                       These<X, B>.This (var x1) =>\n                                                                           This<X, B>(tx.Combine(x, x1)),\n\n                                                                       These<X, B>.That (var b1) =>\n                                                                           Both(x, b1),\n\n                                                                       These<X, B>.Both (var x1, var b1) =>\n                                                                           Both(tx.Combine(x, x1), b1),\n\n                                                                       _ => throw new NSE()\n                                                                   }),\n                                    _ => throw new NSE()\n                                }));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ChronicleT/Trait/ChronicleT.TraitImpl.cs",
    "content": "using System;\nusing System.Buffers;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `ChronicleT` trait implementations\n/// </summary>\n/// <typeparam name=\"Ch\">Chronicle type (a semigroup)</typeparam>\n/// <typeparam name=\"M\">Lifted monad type</typeparam>\npublic partial class ChronicleT<Ch, M> : \n    MonadT<ChronicleT<Ch, M>, M>,\n    MonadIO<ChronicleT<Ch, M>>,\n    Fallible<Ch, ChronicleT<Ch, M>>,\n    Choice<ChronicleT<Ch, M>>,\n    Chronicaler<ChronicleT<Ch, M>, Ch>\n    where M : Monad<M>\n{\n    static K<ChronicleT<Ch, M>, B> Functor<ChronicleT<Ch, M>>.Map<A, B>(\n        Func<A, B> f,\n        K<ChronicleT<Ch, M>, A> ma) =>\n        ma.As().Map(f);\n\n    static K<ChronicleT<Ch, M>, A> Applicative<ChronicleT<Ch, M>>.Pure<A>(A value) =>\n        ChronicleT.dictate<Ch, M, A>(value);\n\n    static K<ChronicleT<Ch, M>, B> Applicative<ChronicleT<Ch, M>>.Apply<A, B>(\n        K<ChronicleT<Ch, M>, Func<A, B>> mf,\n        K<ChronicleT<Ch, M>, A> ma)\n    {\n        return new ChronicleT<Ch, M, B>(t => Applicative.lift(apply(t.Combine), mf.As().Run(t), ma.As().Run(t)));\n        static Func<These<Ch, Func<A, B>>, These<Ch, A>, These<Ch, B>> apply(Func<Ch, Ch, Ch> combine) =>\n            (mf, mx) =>\n                mf.Apply(mx, combine);\n    }\n\n    static K<ChronicleT<Ch, M>, B> Applicative<ChronicleT<Ch, M>>.Apply<A, B>(\n        K<ChronicleT<Ch, M>, Func<A, B>> mf,\n        Memo<ChronicleT<Ch, M>, A> mma)\n    {\n        return new ChronicleT<Ch, M, B>(\n            semi => Applicative.lift(\n                apply(semi.Combine), \n                memoK(mf.As().Run(semi)),\n                mma.Lower().Map(ma => ma.As().Run(semi)).Lift()));\n        \n        static Func<These<Ch, Func<A, B>>, These<Ch, A>, These<Ch, B>> apply(Func<Ch, Ch, Ch> combine) =>\n            (mf, mx) =>\n                mf.Apply(mx, combine);\n        \n    }\n\n    static K<ChronicleT<Ch, M>, B> Monad<ChronicleT<Ch, M>>.Bind<A, B>(\n        K<ChronicleT<Ch, M>, A> ma,\n        Func<A, K<ChronicleT<Ch, M>, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<ChronicleT<Ch, M>, B> Monad<ChronicleT<Ch, M>>.Recur<A, B>(\n        A value, Func<A, K<ChronicleT<Ch, M>, Next<A, B>>> f) =>\n            new ChronicleT<Ch, M, B>(semi =>\n            M.Recur<(Ch? Chronicle, A Value), These<Ch, B>>(\n                (default, value),\n                pair => f(pair.Value)\n                           .As()\n                           .runChronicleT(semi)\n                           .Map(e => e switch\n                                     {\n                                         These<Ch, Next<A, B>>.This(var ch) => \n                                             Pure(These.This<Ch, B>(ch)),\n                                         \n                                         These<Ch, Next<A, B>>.That({ IsDone: true } n) => \n                                             Pure(These.That<Ch, B>(n.Done)),\n                                         \n                                         These<Ch, Next<A, B>>.That({ IsLoop: true } n) => \n                                             Loop((pair.Chronicle, n.Loop)),\n                                         \n                                         These<Ch, Next<A, B>>.Both(var ch, { IsDone: true } n) => \n                                             Pure(These.Both(Combine(pair.Chronicle, ch, semi), n.Done)),\n                                         \n                                         These<Ch, Next<A, B>>.Both(var ch, { IsLoop: true } n) => \n                                             Next.Loop<(Ch? Chronicle, A Value), These<Ch, B>>((Combine(pair.Chronicle, ch, semi), n.Loop)),\n                                         \n                                         _ => throw new NotSupportedException()\n                                     })));\n\n    static Ch Combine(Ch? fst, Ch snd, SemigroupInstance<Ch> semi) =>\n        fst is null\n            ? snd\n            : semi.Combine(fst, snd);\n    \n    static K<ChronicleT<Ch, M>, A> MonadT<ChronicleT<Ch, M>, M>.Lift<A>(K<M, A> ma) =>\n        ChronicleT.lift<Ch, M, A>(ma);\n\n    static K<ChronicleT<Ch, M>, A> MonadIO<ChronicleT<Ch, M>>.LiftIO<A>(IO<A> ma) => \n        ChronicleT.liftIO<Ch, M, A>(ma);\n\n    static K<ChronicleT<Ch, M>, A> Fallible<Ch, ChronicleT<Ch, M>>.Fail<A>(Ch error) => \n        ChronicleT.confess<Ch, M, A>(error);\n\n    static K<ChronicleT<Ch, M>, A> Fallible<Ch, ChronicleT<Ch, M>>.Catch<A>(\n        K<ChronicleT<Ch, M>, A> fa,\n        Func<Ch, bool> Predicate,\n        Func<Ch, K<ChronicleT<Ch, M>, A>> Fail) =>\n        fa.As().Catch(Predicate, Fail);\n\n    static K<ChronicleT<Ch, M>, A> Choice<ChronicleT<Ch, M>>.Choose<A>(K<ChronicleT<Ch, M>, A> lhs, K<ChronicleT<Ch, M>, A> rhs) => \n        lhs.As().Choose(rhs);\n\n    static K<ChronicleT<Ch, M>, A> Choice<ChronicleT<Ch, M>>.Choose<A>(K<ChronicleT<Ch, M>, A> lhs, Memo<ChronicleT<Ch, M>, A> rhs) => \n        lhs.As().Choose(rhs);\n\n    static K<ChronicleT<Ch, M>, A> Chronicaler<ChronicleT<Ch, M>, Ch>.Dictate<A>(A value) => \n        ChronicleT.dictate<Ch, M, A>(value);\n\n    static K<ChronicleT<Ch, M>, A> Chronicaler<ChronicleT<Ch, M>, Ch>.Confess<A>(Ch c) => \n        ChronicleT.confess<Ch, M, A>(c);\n\n    static K<ChronicleT<Ch, M>, Either<Ch, A>> Chronicaler<ChronicleT<Ch, M>, Ch>.Memento<A>(\n        K<ChronicleT<Ch, M>, A> ma) =>\n        ma.As().Memento();\n\n    static K<ChronicleT<Ch, M>, A> Chronicaler<ChronicleT<Ch, M>, Ch>.Absolve<A>(\n        A defaultValue, \n        K<ChronicleT<Ch, M>, A> ma) => \n        ma.As().Absolve(defaultValue);\n\n    static K<ChronicleT<Ch, M>, A> Chronicaler<ChronicleT<Ch, M>, Ch>.Condemn<A>(K<ChronicleT<Ch, M>, A> ma) => \n        ma.As().Condemn();\n\n    static K<ChronicleT<Ch, M>, A> Chronicaler<ChronicleT<Ch, M>, Ch>.Censor<A>(\n        Func<Ch, Ch> f,\n        K<ChronicleT<Ch, M>, A> ma) => \n        ma.As().Censor(f);\n\n    static K<ChronicleT<Ch, M>, A> Chronicaler<ChronicleT<Ch, M>, Ch>.Chronicle<A>(These<Ch, A> ma) => \n        ChronicleT.chronicle<Ch, M, A>(ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Either.Left.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\npublic abstract partial record Either<L, R>\n{\n    /// <summary>\n    /// Left case type\n    /// </summary>\n    /// <param name=\"Value\">Left value</param>\n    public sealed record Left(L Value) : Either<L, R>\n    {\n        /// <summary>\n        /// Is the Either in a Right state?\n        /// </summary>\n        [Pure]\n        public override bool IsRight =>\n            false;\n\n        /// <summary>\n        /// Is the Either in a Left state?\n        /// </summary>\n        [Pure]\n        public override bool IsLeft =>\n            true;\n\n        /// <summary>\n        /// Invokes the Right or Left function depending on the state of the Either\n        /// </summary>\n        /// <typeparam name=\"B\">Return type</typeparam>\n        /// <param name=\"Left\">Function to invoke if in a Left state</param>\n        /// <param name=\"Right\">Function to invoke if in a Right state</param>\n        /// <returns>The return value of the invoked function</returns>\n        [Pure]\n        public override B Match<B>(Func<L, B> Left, Func<R, B> Right) =>\n            Left(Value);\n\n        /// <summary>\n        /// Show the structure as a string\n        /// </summary>\n        [Pure]\n        public override string ToString() =>\n            Value is null ? \"Left(null)\" : $\"Left({Value})\";\n\n        /// <summary>\n        /// Get a hash code for the structure\n        /// </summary>\n        [Pure]\n        public override int GetHashCode() =>\n            Value is null ? 0 : HashableDefault<L>.GetHashCode(Value);\n\n        /// <summary>\n        /// Span of left value\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<L> LeftSpan() =>\n            new([Value]);\n\n        /// <summary>\n        /// Empty span\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<R> RightSpan() =>\n            ReadOnlySpan<R>.Empty;\n\n        /// <summary>\n        /// Singleton enumerable if in a right state, otherwise empty enumerable\n        /// </summary>\n        [Pure]\n        public override IEnumerable<R> AsEnumerable()\n        {\n            yield break;\n        }\n\n        /// <summary>\n        /// Compare this structure to another to find its relative ordering\n        /// </summary>\n        [Pure]\n        public override int CompareTo<OrdL, OrdR>(Either<L, R> other) =>\n            other switch\n            {\n                Left l => OrdL.Compare(Value, l.Value),\n                _      => -1\n            };\n\n        /// <summary>\n        /// Equality override\n        /// </summary>\n        [Pure]\n        public override bool Equals<EqL, EqR>(Either<L, R> other) =>\n            other switch\n            {\n                Left l => EqL.Equals(Value, l.Value),\n                _      => false\n            };\n\n        /// <summary>\n        /// Unsafe access to the right-value \n        /// </summary>\n        /// <exception cref=\"EitherIsNotRightException\"></exception>\n        internal override R RightValue =>\n            throw new EitherIsNotRightException();\n\n        /// <summary>\n        /// Unsafe access to the left-value \n        /// </summary>\n        /// <exception cref=\"EitherIsNotLeftException\"></exception>\n        internal override L LeftValue =>\n            Value;\n\n        /// <summary>\n        /// Maps the value in the Either if it's in a Right state\n        /// </summary>\n        /// <typeparam name=\"L\">Left</typeparam>\n        /// <typeparam name=\"R\">Right</typeparam>\n        /// <typeparam name=\"B\">Mapped Either type</typeparam>\n        /// <param name=\"f\">Map function</param>\n        /// <returns>Mapped Either</returns>\n        [Pure]\n        public override Either<L, B> Map<B>(Func<R, B> f) =>\n            new Either<L, B>.Left(Value);\n\n        /// <summary>\n        /// Bi-maps the value in the Either if it's in a Right state\n        /// </summary>\n        /// <typeparam name=\"L\">Left</typeparam>\n        /// <typeparam name=\"R\">Right</typeparam>\n        /// <typeparam name=\"L2\">Left return</typeparam>\n        /// <typeparam name=\"R2\">Right return</typeparam>\n        /// <param name=\"Right\">Right map function</param>\n        /// <param name=\"Left\">Left map function</param>\n        /// <returns>Mapped Either</returns>\n        [Pure]\n        public override Either<L2, R2> BiMap<L2, R2>(Func<L, L2> Left, Func<R, R2> Right) =>\n            new Either<L2, R2>.Left(Left(Value));\n\n        /// <summary>\n        /// Monadic bind\n        /// </summary>\n        /// <typeparam name=\"L\">Left</typeparam>\n        /// <typeparam name=\"R\">Right</typeparam>\n        /// <typeparam name=\"B\">Resulting bound value</typeparam>\n        /// <param name=\"f\">Bind function</param>\n        /// <returns>Bound Either</returns>\n        [Pure]\n        public override Either<L, B> Bind<B>(Func<R, Either<L, B>> f) =>\n            new Either<L, B>.Left(Value);\n\n        /// <summary>\n        /// Bi-bind.  Allows mapping of both monad states\n        /// </summary>\n        [Pure]\n        public override Either<L2, R2> BiBind<L2, R2>(\n            Func<L, Either<L2, R2>> Left,\n            Func<R, Either<L2, R2>> Right) =>\n            Left(Value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Either.Module.cs",
    "content": "using System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic partial class Either\n{\n    /// <summary>\n    /// Construct an `Either` value in a `Right` state.\n    /// </summary>\n    /// <remarks>\n    /// `Right` is often synonymous with 'correct', or 'success', although that isn't a requirement for any reason other\n    /// than the default monad bind behaviour.  `Left` shortcuts and 'fails', whereas `Right` means we can successfully\n    /// continue.\n    /// </remarks>\n    /// <param name=\"value\">Value to construct the `Right` state with</param>\n    /// <typeparam name=\"L\">Left value type</typeparam>\n    /// <typeparam name=\"R\">Right value type</typeparam>\n    /// <returns>Constructed `Either` value</returns>\n    [Pure]\n    public static Either<L, R> Right<L, R>(R value) =>\n        new Either<L, R>.Right(value);\n\n    /// <summary>\n    /// Construct an `Either` value in a `Left` state.\n    /// </summary>\n    /// <remarks>\n    /// `Left` is often synonymous with 'failure', or 'error', although that isn't a requirement for any reason other\n    /// than the default monad bind behaviour.  `Left` shortcuts and 'fails', whereas `Right` means we can successfully\n    /// continue.\n    /// </remarks>\n    /// <param name=\"value\">Value to construct the `Right` state with</param>\n    /// <typeparam name=\"L\">Left value type</typeparam>\n    /// <typeparam name=\"R\">Right value type</typeparam>\n    /// <returns>Constructed `Either` value</returns>\n    [Pure]\n    public static Either<L, R> Left<L, R>(L value) =>\n        new Either<L, R>.Left(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Either.Right.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\npublic abstract partial record Either<L, R>\n{\n    /// <summary>\n    /// Right case-type\n    /// </summary>\n    /// <param name=\"Value\">Right value</param>\n    public sealed record Right(R Value) : Either<L, R>\n    {\n        /// <summary>\n        /// Is the Either in a Right state?\n        /// </summary>\n        [Pure]\n        public override bool IsRight =>\n            true;\n\n        /// <summary>\n        /// Is the Either in a Left state?\n        /// </summary>\n        [Pure]\n        public override bool IsLeft =>\n            false;\n\n        /// <summary>\n        /// Invokes the Right or Left function depending on the state of the Either\n        /// </summary>\n        /// <typeparam name=\"B\">Return type</typeparam>\n        /// <param name=\"Left\">Function to invoke if in a Left state</param>\n        /// <param name=\"Right\">Function to invoke if in a Right state</param>\n        /// <returns>The return value of the invoked function</returns>\n        [Pure]\n        public override B Match<B>(Func<L, B> Left, Func<R, B> Right) =>\n            Right(Value);\n\n        /// <summary>\n        /// Show the structure as a string\n        /// </summary>\n        [Pure]\n        public override string ToString() =>\n            Value is null ? \"Right(null)\" : $\"Right({Value})\";\n\n        /// <summary>\n        /// Get a hash code for the structure\n        /// </summary>\n        [Pure]\n        public override int GetHashCode() =>\n            Value is null ? 0 : HashableDefault<R>.GetHashCode(Value);\n\n        /// <summary>\n        /// Empty span\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<L> LeftSpan() =>\n            ReadOnlySpan<L>.Empty;\n\n        /// <summary>\n        /// Span of right value\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<R> RightSpan() =>\n            new([Value]);\n\n        /// <summary>\n        /// Singleton enumerable if in a right state, otherwise empty enumerable\n        /// </summary>\n        [Pure]\n        public override IEnumerable<R> AsEnumerable()\n        {\n            yield return Value;\n        }\n\n        /// <summary>\n        /// Compare this structure to another to find its relative ordering\n        /// </summary>\n        [Pure]\n        public override int CompareTo<OrdL, OrdR>(Either<L, R> other) =>\n            other switch\n            {\n                Right r => OrdR.Compare(Value, r.Value),\n                _       => 1\n            };\n\n        /// <summary>\n        /// Equality override\n        /// </summary>\n        [Pure]\n        public override bool Equals<EqL, EqR>(Either<L, R> other) =>\n            other switch\n            {\n                Right r => EqR.Equals(Value, r.Value),\n                _       => false\n            };\n\n        /// <summary>\n        /// Unsafe access to the right-value \n        /// </summary>\n        /// <exception cref=\"EitherIsNotRightException\"></exception>\n        internal override R RightValue =>\n            Value;\n\n        /// <summary>\n        /// Unsafe access to the left-value \n        /// </summary>\n        /// <exception cref=\"EitherIsNotLeftException\"></exception>\n        internal override L LeftValue =>\n            throw new EitherIsNotLeftException();\n\n        /// <summary>\n        /// Maps the value in the Either if it's in a Right state\n        /// </summary>\n        /// <typeparam name=\"L\">Left</typeparam>\n        /// <typeparam name=\"R\">Right</typeparam>\n        /// <typeparam name=\"B\">Mapped Either type</typeparam>\n        /// <param name=\"f\">Map function</param>\n        /// <returns>Mapped Either</returns>\n        [Pure]\n        public override Either<L, B> Map<B>(Func<R, B> f) =>\n            new Either<L, B>.Right(f(Value));\n\n        /// <summary>\n        /// Bi-maps the value in the Either if it's in a Right state\n        /// </summary>\n        /// <typeparam name=\"L\">Left</typeparam>\n        /// <typeparam name=\"R\">Right</typeparam>\n        /// <typeparam name=\"L2\">Left return</typeparam>\n        /// <typeparam name=\"R2\">Right return</typeparam>\n        /// <param name=\"Right\">Right map function</param>\n        /// <param name=\"Left\">Left map function</param>\n        /// <returns>Mapped Either</returns>\n        [Pure]\n        public override Either<L2, R2> BiMap<L2, R2>(Func<L, L2> Left, Func<R, R2> Right) =>\n            new Either<L2, R2>.Right(Right(Value));\n\n        /// <summary>\n        /// Monadic bind\n        /// </summary>\n        /// <typeparam name=\"L\">Left</typeparam>\n        /// <typeparam name=\"R\">Right</typeparam>\n        /// <typeparam name=\"B\">Resulting bound value</typeparam>\n        /// <param name=\"f\">Bind function</param>\n        /// <returns>Bound Either</returns>\n        [Pure]\n        public override Either<L, B> Bind<B>(Func<R, Either<L, B>> f) =>\n            f(Value);\n\n        /// <summary>\n        /// Bi-bind.  Allows mapping of both monad states\n        /// </summary>\n        [Pure]\n        public override Either<L2, R2> BiBind<L2, R2>(\n            Func<L, Either<L2, R2>> Left,\n            Func<R, Either<L2, R2>> Right) =>\n            Right(Value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Either.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Holds one of two values `Left` or `Right`.  Usually, `Left` is considered _wrong_ or _in-error_, and\n/// `Right` is, well, right - as in correct.  When the `Either` is in a `Left` state, it cancels\n/// computations like `bind` or `map`, etc.  So, you can see `Left` as an _'early out, with a message'_.\n/// Unlike `Option` that has `None` as its alternative value (i.e. it has an _'early out, but no message'_).\n/// </summary>\n/// <remarks>\n/// NOTE: If you use `Filter` or `Where` (or `where` in a LINQ expression) with `Either`, then the `Either` \n/// will be put into a `Bottom` state [if the predicate returns false].  When it's in this state it is \n/// neither `Right` nor `Left`.  And any usage could trigger a `BottomException`.  So be aware of the issue\n/// of filtering `Either`.\n/// \n/// Also note, when the `Either` is in a `Bottom` state, some operations on it will continue to give valid\n/// results or return another `Either` in the `Bottom` state and not throw.  This is so a filtered `Either` \n/// doesn't needlessly break expressions and could be rescued into something useful via `Match`. \n/// </remarks>\n/// <typeparam name=\"L\">Left</typeparam>\n/// <typeparam name=\"R\">Right</typeparam>\npublic abstract partial record Either<L, R> :\n    IEither,\n    IComparable<R>,\n    IComparable,\n    IComparable<Pure<R>>,\n    IEquatable<Pure<R>>,\n    IEquatable<R>,\n    K<Either<L>, R>,\n    K<Either, L, R>\n{\n    /// <summary>\n    /// Stop other types deriving from Either\n    /// </summary>\n    private Either() {}\n    \n    /// <summary>\n    /// Is the Either in a Right state?\n    /// </summary>\n    public abstract bool IsRight { get; }\n\n    /// <summary>\n    /// Is the Either in a Left state?\n    /// </summary>\n    public abstract bool IsLeft { get; }\n    \n    /// <summary>\n    /// Must exist here to make `operator true` work\n    /// </summary>\n    public static Either<L, R> operator |(Either<L, R> lhs, Either<L, R> rhs) =>\n        lhs.Choose(rhs).As();\n    \n    /// <summary>\n    /// Explicit conversion operator from `Either` to `R`\n    /// </summary>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"InvalidCastException\">Value is not in a Right state</exception>\n    [Pure]\n    public static explicit operator R(Either<L, R> ma) =>\n        ma.RightValue;\n\n    /// <summary>\n    /// Explicit conversion operator from `Either` to `L`\n    /// </summary>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"InvalidCastException\">Value is not in a Left state</exception>\n    [Pure]\n    public static explicit operator L(Either<L, R> ma) =>\n        ma.LeftValue;\n\n    /// <summary>\n    /// Implicit conversion operator from R to Either R L\n    /// </summary>\n    /// <param name=\"value\">Value</param>\n    [Pure]\n    public static implicit operator Either<L, R>(R value) =>\n        new Right(value);\n\n    /// <summary>\n    /// Implicit conversion operator from L to Either R L\n    /// </summary>\n    /// <param name=\"value\">Value</param>\n    [Pure]\n    public static implicit operator Either<L, R>(L value) =>\n        new Left(value);\n\n    /// <summary>\n    /// Invokes the Right or Left function depending on the state of the Either\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Left\">Function to invoke if in a Left state</param>\n    /// <param name=\"Right\">Function to invoke if in a Right state</param>\n    /// <returns>The return value of the invoked function</returns>\n    [Pure]\n    public abstract B Match<B>(Func<L, B> Left, Func<R, B> Right);\n\n    /// <summary>\n    /// Invokes the Right or Left action depending on the state of the Either\n    /// </summary>\n    /// <param name=\"Right\">Action to invoke if in a Right state</param>\n    /// <param name=\"Left\">Action to invoke if in a Left state</param>\n    /// <returns>Unit</returns>\n    public Unit Match(Action<L> Left, Action<R> Right) =>\n        Match(Left: l => fun(Left)(l), Right: r => fun(Right)(r));\n\n    /// <summary>\n    /// Executes the Left function if the Either is in a Left state.\n    /// Returns the Right value if the Either is in a Right state.\n    /// </summary>\n    /// <param name=\"Left\">Function to generate a Right value if in the Left state</param>\n    /// <returns>Returns an unwrapped Right value</returns>\n    [Pure]\n    public R IfLeft(Func<R> Left) =>\n        IfLeft(_ => Left());\n\n    /// <summary>\n    /// Executes the leftMap function if the Either is in a Left state.\n    /// Returns the Right value if the Either is in a Right state.\n    /// </summary>\n    /// <param name=\"leftMap\">Function to generate a Right value if in the Left state</param>\n    /// <returns>Returns an unwrapped Right value</returns>\n    [Pure]\n    public R IfLeft(Func<L, R> leftMap) =>\n        Match(Left: leftMap, Right: identity);\n\n    /// <summary>\n    /// Returns the rightValue if the Either is in a Left state.\n    /// Returns the Right value if the Either is in a Right state.\n    /// </summary>\n    /// <param name=\"rightValue\">Value to return if in the Left state</param>\n    /// <returns>Returns an unwrapped Right value</returns>\n    [Pure]\n    public R IfLeft(R rightValue) =>\n        IfLeft(_ => rightValue);\n\n    /// <summary>\n    /// Executes the Left action if the Either is in a Left state.\n    /// </summary>\n    /// <param name=\"Left\">Function to generate a Right value if in the Left state</param>\n    /// <returns>Returns an unwrapped Right value</returns>\n    public Unit IfLeft(Action<L> Left) =>\n        Match(Left: Left, Right: _ => {});\n\n    /// <summary>\n    /// Invokes the Right action if the Either is in a Right state, otherwise does nothing\n    /// </summary>\n    /// <param name=\"Right\">Action to invoke</param>\n    /// <returns>Unit</returns>\n    public Unit IfRight(Action<R> Right) =>\n        Match(Left: _ => { }, Right: Right);\n\n    /// <summary>\n    /// Returns the leftValue if the Either is in a Right state.\n    /// Returns the Left value if the Either is in a Left state.\n    /// </summary>\n    /// <param name=\"leftValue\">Value to return if in the Left state</param>\n    /// <returns>Returns an unwrapped Left value</returns>\n    [Pure]\n    public L IfRight(L leftValue) =>\n        Match(Left: identity, Right: _ => leftValue);\n\n    /// <summary>\n    /// Returns the result of Right() if the Either is in a Right state.\n    /// Returns the Left value if the Either is in a Left state.\n    /// </summary>\n    /// <param name=\"Right\">Function to generate a Left value if in the Right state</param>\n    /// <returns>Returns an unwrapped Left value</returns>\n    [Pure]\n    public L IfRight(Func<L> Right) =>\n        Match(Left: identity, Right: _ => Right());\n\n    /// <summary>\n    /// Returns the result of rightMap if the Either is in a Right state.\n    /// Returns the Left value if the Either is in a Left state.\n    /// </summary>\n    /// <param name=\"rightMap\">Function to generate a Left value if in the Right state</param>\n    /// <returns>Returns an unwrapped Left value</returns>\n    [Pure]\n    public L IfRight(Func<R, L> rightMap) =>\n        Match(Left: identity, Right: rightMap);\n\n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj is Either<L, R> t ? CompareTo(t) : 1;\n\n    /// <summary>\n    /// Span of left value\n    /// </summary>\n    [Pure]\n    public abstract ReadOnlySpan<L> LeftSpan();\n\n    /// <summary>\n    /// Span of right value\n    /// </summary>\n    [Pure]\n    public abstract ReadOnlySpan<R> RightSpan();\n\n    /// <summary>\n    /// Singleton enumerable if in a right state, otherwise empty.\n    /// </summary>\n    [Pure]\n    public abstract IEnumerable<R> AsEnumerable();\n\n    /// <summary>\n    /// Singleton `Iterable` if in a right state, otherwise empty.\n    /// </summary>\n    [Pure]\n    public Iterable<R> ToIterable() =>\n        [..RightSpan()];\n\n    /// <summary>\n    /// Project the Either into a Lst R\n    /// </summary>\n    /// <returns>If the Either is in a Right state, a Lst of R with one item.  A zero length Lst R otherwise</returns>\n    public Lst<R> ToList() =>\n        new(RightSpan());\n\n    /// <summary>\n    /// Project the Either into an ImmutableArray R\n    /// </summary>\n    /// <returns>If the Either is in a Right state, an immutable-array of R with one item.  A zero-length array of R otherwise</returns>\n    public Arr<R> ToArray() =>\n        new(RightSpan());\n\n    /// <summary>\n    /// Convert either to sequence of 0 or 1 right values\n    /// </summary>\n    [Pure]\n    public Seq<R> ToSeq() =>\n        new(RightSpan());\n\n    /// <summary>\n    /// Convert the Either to an Option\n    /// </summary>\n    /// <returns>Some(Right) or None</returns>\n    [Pure]\n    public Option<R> ToOption() =>\n        Match(Left: _ => None, Right: Some);\n\n    /// <summary>\n    /// Convert to an `Eff`\n    /// </summary>\n    /// <param name=\"Left\">Map the `Left` value to the`Fail` state of the `Eff`</param>\n    /// <returns>`Eff` monad</returns>\n    [Pure]\n    public Eff<R> ToEff(Func<L, Error> Left) =>\n        Match(Left: e => Eff<R>.Fail(Left(e)), Right: Eff<R>.Pure);\n\n    /// <summary>\n    /// Convert to an Either transformer with embedded IO\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public EitherT<L, IO, R> ToIO() =>\n        EitherT.lift<L, IO, R>(this);\n    \n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Either<L, R> lhs, Fail<L> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <=(Either<L, R> lhs, Fail<L> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Either<L, R> lhs, Fail<L> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs >= rhs</returns>\n    [Pure]\n    public static bool operator >=(Either<L, R> lhs, Fail<L> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Either<L, R> lhs, Pure<R> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Either<L, R> lhs, Pure<R> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Either<L, R> lhs, Pure<R> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Either<L, R> lhs, Pure<R> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Fail<L> lhs, Either<L, R> rhs) =>\n        ((Either<L, R>)lhs).CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Fail<L>  lhs, Either<L, R> rhs) =>\n        ((Either<L, R>)lhs).CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Fail<L> lhs, Either<L, R>rhs) =>\n        ((Either<L, R>)lhs).CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Fail<L> lhs, Either<L, R>  rhs) =>\n        ((Either<L, R>)lhs).CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Pure<R> lhs, Either<L, R>  rhs) =>\n        ((Either<L, R>)lhs).CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Pure<R> lhs, Either<L, R> rhs) =>\n        ((Either<L, R>)lhs).CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Pure<R> lhs, Either<L, R> rhs) =>\n        ((Either<L, R>)lhs).CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Pure<R> lhs, Either<L, R> rhs) =>\n        ((Either<L, R>)lhs).CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Either<L, R> lhs, Either<L, R> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Either<L, R> lhs, Either<L, R> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Either<L, R> lhs, Either<L, R> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Either<L, R> lhs, Either<L, R> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Either<L, R> lhs, Fail<L> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Either<L, R> lhs, Pure<R> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Fail<L>  lhs, Either<L, R> rhs) =>\n        ((Either<L, R>)lhs).Equals(rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Pure<R> lhs, Either<L, R>  rhs) =>\n        ((Either<L, R>)lhs).Equals(rhs);\n        \n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Either<L, R> lhs, Fail<L> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Either<L, R> lhs, Pure<R> rhs) =>\n        !(lhs == rhs);\n\n\n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Fail<L> lhs, Either<L, R> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Pure<R> lhs, Either<L, R> rhs) =>\n        !(lhs == rhs);\n    \n    /// <summary>\n    /// Override of the True operator to return True if the Either is Right\n    /// </summary>\n    [Pure]\n    public static bool operator true(Either<L, R> value) =>\n        value is Right;\n\n    /// <summary>\n    /// Override of the False operator to return True if the Either is Left\n    /// </summary>\n    [Pure]\n    public static bool operator false(Either<L, R> value) =>\n        value is Left;\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(Either<L, R> other) =>\n        CompareTo<OrdDefault<L>, OrdDefault<R>>(other);\n\n    /// <summary>\n    /// CompareTo\n    /// </summary>\n    [Pure]\n    public int CompareTo<OrdR>(Either<L, R> other)\n        where OrdR : Ord<R> =>\n        CompareTo<OrdDefault<L>, OrdR>(other);\n\n    /// <summary>\n    /// CompareTo\n    /// </summary>\n    [Pure]\n    public abstract int CompareTo<OrdL, OrdR>(Either<L, R> other)\n        where OrdL : Ord<L>\n        where OrdR : Ord<R>;\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(Fail<L> other) =>\n        CompareTo((Either<L, R>)other);\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(Pure<R> other) =>\n        CompareTo((Either<L, R>)other);\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(R? other) =>\n        other switch\n        {\n            null => 1,\n            _    => CompareTo(Right<L, R>(other))\n        };\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(L? other) =>\n        other switch\n        {\n            null => 1,\n            _    => CompareTo(Left<L, R>(other))\n        };\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(R? other) =>\n        other is not null && Equals(Right<L, R>(other));\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(L? other) =>\n        other is not null && Equals(Left<L, R>(other));\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public virtual bool Equals(Either<L, R>? other) =>\n        other is not null && Equals<EqDefault<L>, EqDefault<R>>(other);\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public virtual bool Equals<EqR>(Either<L, R> other) where EqR : Eq<R> =>\n        Equals<EqDefault<L>, EqR>(other);\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public abstract bool Equals<EqL, EqR>(Either<L, R> other) \n        where EqL : Eq<L> \n        where EqR : Eq<R>;\n\n    [Pure]\n    public abstract override int GetHashCode();\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(Fail<L> other) =>\n        Equals((Either<L, R>)other);\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(Pure<R> other) =>\n        Equals((Either<L, R>)other);\n\n    /// <summary>\n    /// Match the Right and Left values but as objects.  This can be useful to avoid reflection.\n    /// </summary>\n    [Pure]\n    public Res MatchUntyped<Res>(Func<object?, Res> Left, Func<object?, Res> Right) =>\n        Match(Left: l => Left(l), Right: r => Right(r));\n\n    /// <summary>\n    /// Find out the underlying Right type\n    /// </summary>\n    [Pure]\n    public Type GetUnderlyingRightType() =>\n        typeof(R);\n\n    /// <summary>\n    /// Find out the underlying Left type\n    /// </summary>\n    [Pure]\n    public Type GetUnderlyingLeftType() =>\n        typeof(L);\n\n    /// <summary>\n    /// Unsafe access to the right-value \n    /// </summary>\n    /// <exception cref=\"EitherIsNotRightException\"></exception>\n    internal abstract R RightValue { get; }\n    \n    /// <summary>\n    /// Unsafe access to the left-value \n    /// </summary>\n    /// <exception cref=\"EitherIsNotLeftException\"></exception>\n    internal abstract L LeftValue { get; }\n\n    [Pure]\n    public Type GetUnderlyingType() => \n        typeof(R);\n\n    /// <summary>\n    /// Flips the left and right tagged values\n    /// </summary>\n    /// <returns>Either with the types swapped</returns>\n    [Pure]\n    public Either<R, L> Swap() =>\n        Match(Left: Either.Right<R, L>, Right: Either.Left<R, L>);\n\n    /// <summary>\n    /// Invokes a predicate on the value of the Either if it's in the Right state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <param name=\"self\">Either to forall</param>\n    /// <param name=\"Right\">Predicate</param>\n    /// <returns>True if the Either is in a Left state.  \n    /// True if the Either is in a Right state and the predicate returns True.  \n    /// False otherwise.</returns>\n    [Pure]\n    public bool ForAll(Func<R, bool> Right) =>\n        Match(Left: _ => true, Right: Right);\n\n    /// <summary>\n    /// Invokes a predicate on the value of the Either if it's in the Right state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <param name=\"self\">Either to forall</param>\n    /// <param name=\"Right\">Predicate</param>\n    /// <param name=\"Left\">Predicate</param>\n    /// <returns>True if either Predicate returns true</returns>\n    [Pure]\n    public bool BiForAll(Func<L, bool> Left, Func<R, bool> Right) =>\n        Match(Left: Left, Right: Right);\n\n    /// <summary>\n    /// <para>\n    /// Either types are like lists of 0 or 1 items, and therefore follow the \n    /// same rules when folding.\n    /// </para><para>\n    /// In the case of lists, 'Fold', when applied to a binary\n    /// operator, a starting value(typically the left-identity of the operator),\n    /// and a list, reduces the list using the binary operator, from left to\n    /// right:\n    /// </para>\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"Right\">Folder function, applied if structure is in a Right state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, R, S> Right) =>\n        Match(Left: _ => state, Right: curry(Right)(state));\n\n    /// <summary>\n    /// <para>\n    /// Either types are like lists of 0 or 1 items, and therefore follow the \n    /// same rules when folding.\n    /// </para><para>\n    /// In the case of lists, 'Fold', when applied to a binary\n    /// operator, a starting value(typically the left-identity of the operator),\n    /// and a list, reduces the list using the binary operator, from left to\n    /// right:\n    /// </para>\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"Right\">Folder function, applied if Either is in a Right state</param>\n    /// <param name=\"Left\">Folder function, applied if Either is in a Left state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    public S BiFold<S>(S state, Func<S, L, S> Left, Func<S, R, S> Right) =>\n        Match(Left: curry(Left)(state), Right: curry(Right)(state));\n\n    /// <summary>\n    /// Invokes a predicate on the value of the Either if it's in the Right state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <param name=\"self\">Either to check existence of</param>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if the Either is in a Right state and the predicate returns True.  False otherwise.</returns>\n    [Pure]\n    public bool Exists(Func<R, bool> pred) =>\n        Match(Left: _ => false, Right: pred);\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Either<L, R> Do(Action<R> f) =>\n        Map(r => { f(r); return r; });\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Either<L, B>> Traverse<F, B>(Func<R, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n\n    /// <summary>\n    /// Maps the value in the Either if it's in a Right state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <typeparam name=\"B\">Mapped Either type</typeparam>\n    /// <param name=\"f\">Map function</param>\n    /// <returns>Mapped Either</returns>\n    [Pure]\n    public abstract Either<L, B> Map<B>(Func<R, B> f);\n\n    /// <summary>\n    /// Maps the value in the Either if it's in a Left state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <typeparam name=\"B\">Mapped Either type</typeparam>\n    /// <param name=\"f\">Map function</param>\n    /// <returns>Mapped Either</returns>\n    [Pure]\n    public Either<B, R> MapLeft<B>(Func<L, B> f) =>\n        BiMap(Left: f, Right: identity);\n\n    /// <summary>\n    /// Bi-maps the value in the Either if it's in a Right state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <typeparam name=\"LRet\">Left return</typeparam>\n    /// <typeparam name=\"RRet\">Right return</typeparam>\n    /// <param name=\"Right\">Right map function</param>\n    /// <param name=\"Left\">Left map function</param>\n    /// <returns>Mapped Either</returns>\n    [Pure]\n    public abstract Either<L2, R2> BiMap<L2, R2>(Func<L, L2> Left, Func<R, R2> Right);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <typeparam name=\"B\">Resulting bound value</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Bound Either</returns>\n    [Pure]\n    public abstract Either<L, B> Bind<B>(Func<R, Either<L, B>> f);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\"></param>\n    /// <returns>Bound Either</returns>\n    [Pure]\n    public Either<L, B> Bind<B>(Func<R, K<Either<L>, B>> f) =>\n        Bind(x => (Either<L, B>)f(x));\n\n    /// <summary>\n    /// Bi-bind.  Allows mapping of both monad states\n    /// </summary>\n    [Pure]\n    public abstract Either<L2, R2> BiBind<L2, R2>(Func<L, Either<L2, R2>> Left, Func<R, Either<L2, R2>> Right);\n\n    /// <summary>\n    /// Bind left.  Binds the left path of the monad only\n    /// </summary>\n    [Pure]\n    public Either<L2, R> BindLeft<L2>(Func<L, Either<L2, R>> f) =>\n        BiBind(f, Right<L2, R>);\n\n    /// <summary>\n    /// Maps the value in the Either if it's in a Right state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"TR\">Right</typeparam>\n    /// <typeparam name=\"UR\">Mapped Either type</typeparam>\n    /// <param name=\"f\">Map function</param>\n    /// <returns>Mapped Either</returns>\n    [Pure]\n    public Either<L, U> Select<U>(Func<R, U> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Monadic bind function\n    /// </summary>\n    [Pure]\n    public Either<L, T> SelectMany<S, T>(Func<R, Either<L, S>> bind, Func<R, S, T> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    /// <summary>\n    /// Monadic bind function\n    /// </summary>\n    public Either<L, Unit> SelectMany(Func<R, Guard<L, Unit>> f) =>\n        Bind(a => f(a).ToEither());\n\n    /// <summary>\n    /// Monadic bind function\n    /// </summary>\n    public Either<L, C> SelectMany<C>(Func<R, Guard<L, Unit>> bind, Func<R, Unit, C> project) =>\n        Bind(a => bind(a).ToEither().Map(_ => project(a, default)));    \n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    // `Pure` and `Fail` support\n    //\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    [Pure]\n    public Either<L, B> Bind<B>(Func<R, Pure<B>> f) =>\n        Bind(x => (Either<L, B>)f(x));\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    [Pure]\n    public Either<L, R> Bind(Func<R, Fail<L>> f) =>\n        Bind(x => (Either<L, R>)f(x));\n\n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    [Pure]\n    public Either<L, C> SelectMany<B, C>(Func<R, Pure<B>> bind, Func<R, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    [Pure]\n    public Either<L, C> SelectMany<B, C>(Func<R, Fail<L>> bind, Func<R, B, C> _) =>\n        Bind(x => bind(x).ToEither<C>());\n\n    [Pure]\n    public static implicit operator Either<L, R>(Pure<R> mr) =>\n        new Right(mr.Value);\n\n    [Pure]\n    public static implicit operator Either<L, R>(Fail<L> mr) =>\n        new Left(mr.Value);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Obsolete\n    //\n\n    /// <summary>\n    /// Project the Either into a Lst R\n    /// </summary>\n    /// <returns>If the Either is in a Right state, a Lst of R with one item.  A zero length Lst R otherwise</returns>\n    [Pure]\n    [Obsolete(Change.UseToListInstead)]\n    public Lst<R> RightToList() =>\n        ToList();\n\n    /// <summary>\n    /// Project the Either into an ImmutableArray R\n    /// </summary>\n    /// <returns>If the Either is in a Right state, a ImmutableArray of R with one item.  A zero length ImmutableArray of R otherwise</returns>\n    [Pure]\n    [Obsolete(Change.UseToArrayInstead)]\n    public Arr<R> RightToArray() =>\n        ToArray();\n\n    /// <summary>\n    /// Convert either to sequence of 0 or 1 right values\n    /// </summary>\n    [Pure]\n    [Obsolete(Change.UseToSeqInstead)]\n    public Seq<R> RightToSeq() =>\n        ToSeq();\n}\n\n/// <summary>\n/// Context for the fluent Either matching\n/// </summary>\npublic readonly struct EitherContext<L, R, Ret>\n{\n    readonly Either<L, R> either;\n    readonly Func<R, Ret> rightHandler;\n\n    internal EitherContext(Either<L, R> either, Func<R, Ret> rightHandler)\n    {\n        this.either = either;\n        this.rightHandler = rightHandler;\n    }\n\n    /// <summary>\n    /// Left match\n    /// </summary>\n    /// <param name=\"left\"></param>\n    /// <returns>Result of the match</returns>\n    [Pure]\n    public Ret Left(Func<L, Ret> left) =>\n        either.Match(left, rightHandler);\n}\n\n/// <summary>\n/// Context for the fluent Either matching\n/// </summary>\npublic readonly struct EitherUnitContext<L, R>\n{\n    readonly Either<L, R> either;\n    readonly Action<R> rightHandler;\n\n    internal EitherUnitContext(Either<L, R> either, Action<R> rightHandler)\n    {\n        this.either = either;\n        this.rightHandler = rightHandler;\n    }\n\n    public Unit Left(Action<L> leftHandler) =>\n        either.Match(leftHandler, rightHandler);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Extensions/Either.Extensions.Apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherExtensions\n{\n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Either<L, B> Action<L, A, B>(this Either<L, A> ma, K<Either<L>, B> mb) =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Either<L, B> Action<L, A, B>(this K<Either<L>, A> ma, K<Either<L>, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Either<L, B> Apply<L, A, B>(this Either<L, Func<A, B>> mf, K<Either<L>, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Either<L, B> Apply<L, A, B>(this K<Either<L>, Func<A, B>> mf, K<Either<L>, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Extensions/Either.Extensions.Map.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Either<L, B> Map<L, A, B>(this Func<A, B> f, K<Either<L>, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Either<L, B> Map<L, A, B>(this Func<A, B> f, Either<L, A> ma) =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Extensions/Either.Extensions.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing NSE = System.NotSupportedException;\nusing LanguageExt.Traits;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Extension methods for Either\n/// </summary>\npublic static partial class EitherExtensions\n{\n    public static Either<L, R> As<L, R>(this K<Either<L>, R> ma) =>\n        (Either<L, R>)ma;\n \n    public static Either<L, R> As2<L, R>(this K<Either, L, R> ma) =>\n        (Either<L, R>)ma;\n\n    /// <summary>\n    /// Match Right and return a context.  You must follow this with .Left(...) to complete the match\n    /// </summary>\n    /// <param name=\"right\">Action to invoke if the Either is in a Right state</param>\n    /// <returns>Context that must have Left() called upon it.</returns>\n    [Pure]\n    public static EitherUnitContext<L, R> Right<L, R>(this K<Either<L>, R> ma, Action<R> right) =>\n        new (ma.As(), right);\n\n    /// <summary>\n    /// Match Right and return a context.  You must follow this with .Left(...) to complete the match\n    /// </summary>\n    /// <param name=\"right\">Action to invoke if the Either is in a Right state</param>\n    /// <returns>Context that must have Left() called upon it.</returns>\n    [Pure]\n    public static EitherContext<L, R, R2> Right<L, R, R2>(this K<Either<L>, R> ma, Func<R, R2> right) =>\n        new (ma.As(), right);\n \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Either<L, R> Flatten<L, R>(this K<Either<L>, Either<L, R>> ma) =>\n        ma.As().Bind(x => x);\n \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Either<L, R> Flatten<L, R>(this K<Either<L>, K<Either<L>, R>> ma) =>\n        ma.As().Bind(x => x);\n\n    /// <summary>\n    /// Filtering based on predicate.  \n    /// </summary>\n    /// <remarks>>\n    /// If the predicate returns false, then `Left(L.Empty)` is yielded and therefore `L` must be a monoid.  \n    /// </remarks>\n    [Pure]\n    public static Either<L, A> Where<L, A>(this K<Either<L>, A> ma, Func<A, bool> pred)\n        where L : Monoid<L> =>\n        ma.Filter(pred);\n\n    /// <summary>\n    /// Filtering based on predicate.  \n    /// </summary>\n    /// <remarks>>\n    /// If the predicate returns false, then `Left(L.Empty)` is yielded and therefore `L` must be a monoid.  \n    /// </remarks>\n    [Pure]\n    public static Either<L, A> Filter<L, A>(this K<Either<L>, A> ma, Func<A, bool> pred)\n        where L : Monoid<L> =>\n        ma.As().Bind(x => pred(x) ? Either.Right<L, A>(x) : Either.Left<L, A>(L.Empty));\n\n    /*\n    /// <summary>\n    /// Partitions a foldable of `Either` into two sequences.\n    /// \n    /// All the `Left` elements are extracted, in order, to the first component of the output.\n    /// Similarly, the `Right` elements are extracted to the second component of the output.\n    /// </summary>\n    /// <returns>A pair containing the sequences of partitioned values</returns>\n    [Pure]\n    public static (Seq<L> Lefts, Seq<R> Rights) Partition<F, L, R>(this K<F, Either<L, R>> self)\n        where F : Foldable<F> =>\n        self.Fold((Left: Seq<L>.Empty, Right: Seq<R>.Empty),\n                  (s, ma) =>\n                      ma switch\n                      {\n                          Either.Right<L, R> (var r) => (s.Left, s.Right.Add(r)),\n                          Either.Left<L, R> (var l)  => (s.Left.Add(l), s.Right),\n                          _                          => throw new NSE()\n                      });\n\n    /// <summary>\n    /// Partitions a foldable of `Either` into two lists and returns the `Left` items only.\n    /// </summary>\n    /// <returns>A sequence of partitioned items</returns>\n    [Pure]\n    public static Seq<L> Lefts<F, L, R>(this K<F, Either<L, R>> self)\n        where F : Foldable<F> =>\n        self.Fold(Seq<L>.Empty,\n                  (s, ma) =>\n                      ma switch\n                      {\n                          Either.Left<L, R> (var l) => s.Add(l),\n                          _                         => throw new NSE()\n                      });\n\n    /// <summary>\n    /// Partitions a foldable of `Either` into two lists and returns the `Right` items only.\n    /// </summary>\n    /// <returns>A sequence of partitioned items</returns>\n    [Pure]\n    public static Seq<R> Rights<F, L, R>(this K<F, Either<L, R>> self)\n        where F : Foldable<F> =>\n        self.Fold(Seq<R>.Empty,\n                  (s, ma) =>\n                      ma switch\n                      {\n                          Either.Right<L, R> (var r) => s.Add(r),\n                          _                          => throw new NSE()\n                      });\n                      */\n    \n    [Pure]\n    public static Validation<L, R> ToValidation<L, R>(this Either<L, R> ma)\n        where L : Monoid<L> =>\n        ma switch\n        {\n            Either<L, R>.Right => Pure(ma.RightValue),\n            Either<L, R>.Left  => Fail(ma.LeftValue),\n            _                  => throw new BottomException()\n        };\n\n    /// <summary>\n    /// Convert to an Eff\n    /// </summary>\n    /// <returns>Eff monad</returns>\n    [Pure]\n    public static Eff<R> ToEff<R>(this Either<Error, R> ma) =>\n        ma switch\n        {\n            Either<Error, R>.Right => Pure(ma.RightValue),\n            Either<Error, R>.Left  => Fail(ma.LeftValue),\n            _                      => throw new BottomException()\n        };\n\n    /// <summary>\n    /// Convert to an Eff\n    /// </summary>\n    /// <returns>Eff monad</returns>\n    [Pure]\n    public static Eff<R> ToEff<R>(this Either<Exception, R> ma) =>\n        ma switch\n        {\n            Either<Exception, R>.Right => Pure(ma.RightValue),\n            Either<Exception, R>.Left  => Fail<Error>(ma.LeftValue),\n            _                          => throw new BottomException()\n        };\n\n    /// <summary>\n    /// Convert to an Eff\n    /// </summary>\n    /// <returns>Eff monad</returns>\n    [Pure]\n    public static Eff<R> ToEff<R>(this Either<string, R> ma) =>\n        ma switch\n        {\n            Either<string, R>.Right => Pure(ma.RightValue),\n            Either<string, R>.Left  => Fail(Error.New(ma.LeftValue)),\n            _                       => throw new BottomException()\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Extensions/Either.Guard.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\npublic static class EitherGuardExtensions\n{\n    /// <summary>\n    /// Natural transformation to `Either`\n    /// </summary>\n    public static Either<L, Unit> ToEither<L>(this Guard<L, Unit> guard) =>\n        guard.Flag\n            ? new Either<L, Unit>.Right(default)\n            : new Either<L, Unit>.Left(guard.OnFalse());\n \n    /// <summary>\n    /// Monadic binding support for `Either`\n    /// </summary>\n    public static Either<L, B> Bind<L, B>(\n        this Guard<L, Unit> guard,\n        Func<Unit, Either<L, B>> f)  =>\n        guard.Flag\n            ? f(default).As()\n            : new Either<L, B>.Left(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `Either`\n    /// </summary>\n    public static Either<L, C> SelectMany<L, B, C>(\n        this Guard<L, Unit> guard,\n        Func<Unit, Either<L, B>> bind, \n        Func<Unit, B, C> project) =>\n        guard.Flag\n            ? bind(default).As().Map(b => project(default, b))\n            : new Either<L, C>.Left(guard.OnFalse());\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/IEither.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\npublic interface IEither\n{\n    bool IsRight\n    {\n        get;\n    }\n\n    bool IsLeft\n    {\n        get;\n    }\n\n    R MatchUntyped<R>(Func<object?, R> Left, Func<object?, R> Right);\n\n    Type GetUnderlyingRightType();\n    Type GetUnderlyingLeftType();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Operators/Either.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EitherExtensions\n{\n    extension<L, A, B>(K<Either<L>, A> self)\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Either<L, B> operator >>> (K<Either<L>, A> ma, K<Either<L>, B> mb) =>\n            ma.Action(mb).As();\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, B> operator * (K<Either<L>, Func<A, B>> mf, K<Either<L>, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, B> operator * (K<Either<L>, A> ma, K<Either<L>, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<L, A, B, C>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, C>> operator * (\n            K<Either<L>, Func<A, B, C>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, C>> operator * (\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<L, A, B, C, D>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, D>>> operator * (\n            K<Either<L>, Func<A, B, C, D>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, D>>> operator * (\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<L, A, B, C, D, E>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Either<L>, Func<A, B, C, D, E>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<L, A, B, C, D, E, F>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Either<L>, Func<A, B, C, D, E, F>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<L, A, B, C, D, E, F, G>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Either<L>, Func<A, B, C, D, E, F, G>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<L, A, B, C, D, E, F, G, H>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Either<L>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<L, A, B, C, D, E, F, G, H, I>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Either<L>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<L, A, B, C, D, E, F, G, H, I, J>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Either<L>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<L, A, B, C, D, E, F, G, H, I, J, K>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Either<L>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Either<L>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Either<L>, A> ma,\n            K<Either<L>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Operators/Either.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherExtensions\n{\n    extension<L, A>(Either<L, A> self)\n    {\n        public static Either<L, A> operator |(Either<L, A> lhs, Either<L, A> rhs) =>\n            lhs.Choose(rhs).As();\n\n        public static Either<L, A> operator |(Either<L, A> lhs, Pure<A> rhs) =>\n            lhs.Choose(rhs.ToEither<L>()).As();\n    }\n    \n    extension<L, A>(K<Either<L>, A> self)\n    {\n        public static Either<L, A> operator |(K<Either<L>, A> lhs, K<Either<L>, A> rhs) =>\n            lhs.Choose(rhs).As();\n\n        public static Either<L, A> operator |(K<Either<L>, A> lhs, Pure<A> rhs) =>\n            lhs.Choose(rhs.ToEither<L>()).As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Operators/Either.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherExtensions\n{\n    extension<L, A>(Either<L, A> self)\n    {\n        public static Either<L, A> operator |(Either<L, A> lhs, CatchM<L, Either<L>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Either<L, A> operator |(Either<L, A> lhs, Fail<L> rhs) =>\n            +lhs.Catch(rhs);\n    }    \n    \n    extension<L, A>(K<Either<L>, A> self)\n    {\n        public static Either<L, A> operator |(K<Either<L>, A> lhs, CatchM<L, Either<L>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Either<L, A> operator |(K<Either<L>, A> lhs, Fail<L> rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Operators/Either.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EitherExtensions\n{\n    extension<L, A, B>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, B> operator *(Func<A, B> f, K<Either<L>, A> ma) =>\n            ma.Map(f).As();\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, B> operator *(K<Either<L>, A> ma, Func<A, B> f) =>\n            ma.Map(f).As();\n    }\n    \n    extension<L, A, B, C>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, C>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<L, A, B, C, D>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, D>>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<L, A, B, C, D, E>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<L, A, B, C, D, E, F>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<L, A, B, C, D, E, F, G>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<L, A, B, C, D, E, F, G, H>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<L, A, B, C, D, E, F, G, H, I>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<L, A, B, C, D, E, F, G, H, I, J>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<L, A, B, C, D, E, F, G, H, I, J, K>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Either<L>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Either<L, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Either<L>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Operators/Either.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherExtensions\n{\n    extension<L, A, B>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Either<L, B> operator >> (K<Either<L>, A> ma, Func<A, K<Either<L>, B>> f) =>\n            ma.Bind(f).As();\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Either<L, B> operator >> (K<Either<L>, A> lhs, K<Either<L>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<L, A>(K<Either<L>, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Either<L, A> operator >> (K<Either<L>, A> lhs, K<Either<L>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Operators/Either.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherExtensions\n{\n    extension<L, A>(K<Either<L>, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Either<L, A> operator +(K<Either<L>, A> ma) =>\n            (Either<L, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Either<L, A> operator >> (K<Either<L>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Prelude/Either.Prelude.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Either constructor\n    /// Constructs an Either in a Right state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <param name=\"value\">Right value</param>\n    /// <returns>A new Either instance</returns>\n    [Pure]\n    public static Either<L, R> Right<L, R>(R value) =>\n        new Either<L, R>.Right(value);\n\n    /// <summary>\n    /// Constructs an `Pure` which can be implicitly cast to an \n    /// Either〈_, R〉\n    /// </summary>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <param name=\"value\">Right value</param>\n    /// <returns>A new EitherRight instance</returns>\n    [Pure]\n    public static Pure<R> Right<R>(R value) =>\n        new (value);\n    \n    /// <summary>\n    /// Either constructor\n    /// Constructs an Either in a Left state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <param name=\"value\">Left value</param>\n    /// <returns>A new Either instance</returns>\n    [Pure]\n    public static Either<L, R> Left<L, R>(L value) =>\n        new Either<L, R>.Left(value);\n\n    /// <summary>\n    /// Constructs a `Fail` which can be implicitly cast to an \n    /// Either〈L, _〉\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <param name=\"value\">Right value</param>\n    /// <returns>A new EitherLeft instance</returns>\n    [Pure]\n    public static Fail<L> Left<L>(L value) =>\n        new (value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Prelude/Either.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Either<L, B> map<L, A, B>(Func<A, B> f, K<Either<L>, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Either<L, B> action<L, A, B>(K<Either<L>, A> ma, K<Either<L>, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Either<L, B> apply<L, A, B>(K<Either<L>, Func<A, B>> mf, K<Either<L>, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/README.md",
    "content": "`Either` monads support either a `L` (left) or a `R` (right) value.  `L` is traditionally used as an error carrier, and any `Either` monad\ncarrying an `L` will short-cut any bind operations and return the `L` (kinda like an `Exception`).  However, they're not only for that, \nand can be used to carry an alternative value which could be mapped using `BiMap`, or `MapLeft`.\n\nYou can construct an `Either` using the constructor functions in the `Prelude`:\n\n    Either<string, int> ma = Left<string, int>(\"this is an error\");\n    Either<string, int> mb = Right<string, int>(123);\n\nThere are also convenience types called `Left` and `Right`, that don't need both generics providing.  They can often make it a little \neasier to work with `Either`:\n\n    Either<string, int> ma = Left(\"this is an error\");\n    Either<string, int> mb = Right(123);\n\nIt uses implicit casts to work out what the type should be.  Note, if you're having trouble getting the types resolved, just specify the \ntype parameters.\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Trait/Either.TraitImpl.2.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Coproduct trait implementation for `Either〈L, R〉`\n/// </summary>\npublic partial class Either :\n    Coproduct<Either>,\n    Bimonad<Either>\n{\n    static K<Either, L1, R1> Bifunctor<Either>.BiMap<L, R, L1, R1>(\n        Func<L, L1> first,\n        Func<R, R1> second,\n        K<Either, L, R> fab) =>\n        fab switch\n        {\n            Either<L, R>.Right(var value) => new Either<L1, R1>.Right(second(value)),\n            Either<L, R>.Left(var value)  => new Either<L1, R1>.Left(first(value)),\n            _                             => throw new NotSupportedException()\n        };\n\n    static K<Either, A, B> CoproductCons<Either>.Left<A, B>(A value) =>\n        new Either<A, B>.Left(value);\n\n    static K<Either, A, B> CoproductCons<Either>.Right<A, B>(B value) =>\n        new Either<A, B>.Right(value);\n\n    public static C Match<A, B, C>(\n        Func<A, C> Left,\n        Func<B, C> Right,\n        K<Either, A, B> fab) =>\n        fab switch\n        {\n            Either<A, B>.Right(var value) => Right(value),\n            Either<A, B>.Left(var value)  => Left(value),\n            _                             => throw new NotSupportedException()\n        };\n\n    public static K<Either, Y, A> BindFirst<X, Y, A>(K<Either, X, A> ma, Func<X, K<Either, Y, A>> f) =>\n        ma switch\n        {\n            Either<X, A>.Right (var a) => new Either<Y, A>.Right(a),\n            Either<X, A>.Left (var l)  => f(l),\n            _                          => throw new NotSupportedException()\n        };\n\n    public static K<Either, X, B> BindSecond<X, A, B>(K<Either, X, A> ma, Func<A, K<Either, X, B>> f) =>\n        ma switch\n        {\n            Either<X, A>.Right (var a) => f(a),\n            Either<X, A>.Left (var l)  => new Either<X, B>.Left(l),\n            _                          => throw new NotSupportedException()\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Either/Trait/Either.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Monad trait implementation for `Either〈L, R〉`\n/// </summary>\n/// <typeparam name=\"L\">Left type parameter</typeparam>\npublic class Either<L> :\n    Either,\n    Monad<Either<L>>,\n    Fallible<L, Either<L>>,\n    Traversable<Either<L>>,\n    Natural<Either<L>, Option>,\n    Choice<Either<L>>\n{\n    static K<Either<L>, B> Applicative<Either<L>>.Apply<A, B>(\n        K<Either<L>, Func<A, B>> mf,\n        K<Either<L>, A> ma) =>\n        (mf, ma) switch\n        {\n            (Either<L, Func<A, B>>.Right (var f), Either<L, A>.Right (var a)) => Right(f(a)),\n            (Either<L, Func<A, B>>.Left (var e1), _)                          => Left<B>(e1),\n            (_, Either<L, A>.Left (var e2))                                   => Left<B>(e2),\n            _                                                                 => throw new NotSupportedException()\n        };\n\n    static K<Either<L>, B> Applicative<Either<L>>.Apply<A, B>(\n        K<Either<L>, Func<A, B>> mf,\n        Memo<Either<L>, A> ma) =>\n        mf switch\n        {\n            Either<L, Func<A, B>>.Right         => mf.Apply(ma.Value),\n            Either<L, Func<A, B>>.Left (var e1) => Left<B>(e1),\n            _                                   => throw new NotSupportedException()\n        };\n    \n    static K<Either<L>, B> Monad<Either<L>>.Bind<A, B>(K<Either<L>, A> ma, Func<A, K<Either<L>, B>> f) =>\n        ma switch\n        {\n            Either<L, A>.Right (var r) => f(r),\n            Either<L, A>.Left (var l)  => Left<B>(l),\n            _                          => throw new NotSupportedException()\n        };\n\n    static K<Either<L>, B> Monad<Either<L>>.Recur<A, B>(A value, Func<A, K<Either<L>, Next<A, B>>> f) \n    {\n        while (true)\n        {\n            var mr = +f(value);\n            if (mr.IsLeft) return Either.Left<L, B>(mr.LeftValue);\n            var next = (Next<A, B>)mr;\n            if(next.IsDone) return Either.Right<L, B>(next.Done);\n            value = next.Loop;\n        }\n    }\n\n    static K<Either<L>, A> Applicative<Either<L>>.Pure<A>(A value) => \n        new Either<L, A>.Right(value);\n\n    static K<F, K<Either<L>, B>> Traversable<Either<L>>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Either<L>, A> ta) =>\n        ta switch\n        {\n            Either<L, A>.Right (var r) => F.Map(Right, f(r)),\n            Either<L, A>.Left (var l)  => F.Pure(Left<B>(l)),\n            _                          => throw new NotSupportedException()\n        };\n\n    static S Foldable<Either<L>>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Either<L>, A> ta) =>\n        ta switch\n        {\n            Either<L, A>.Right (var r) => predicate((state, r)) ? f(r)(state) : state,\n            _                          => state\n        };\n\n    static S Foldable<Either<L>>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Either<L>, A> ta) =>\n        ta switch\n        {\n            Either<L, A>.Right (var r) => predicate((state, r)) ? f(state)(r) : state,\n            _                          => state\n        };\n\n    static K<Either<L>, B> Functor<Either<L>>.Map<A, B>(Func<A, B> f, K<Either<L>, A> ma) =>\n        ma switch\n        {\n            Either<L, A>.Right (var r) => Right(f(r)),\n            Either<L, A>.Left (var l)  => Left<B>(l),\n            _                          => throw new NotSupportedException()\n        };\n\n    static K<Either<L>, A> Right<A>(A value) =>\n        new Either<L, A>.Right(value);\n\n    static K<Either<L>, A> Left<A>(L value) =>\n        new Either<L, A>.Left(value);\n\n    static K<Either<L>, A> Choice<Either<L>>.Choose<A>(K<Either<L>, A> ma, K<Either<L>, A> mb) =>\n        ma is Either<L, A>.Right ? ma : mb;\n\n    static K<Either<L>, A> Choice<Either<L>>.Choose<A>(K<Either<L>, A> ma, Memo<Either<L>, A> mb) => \n        ma is Either<L, A>.Right ? ma : mb.Value;\n\n    static K<Either<L>, A> Fallible<L, Either<L>>.Fail<A>(L error) => \n        new Either<L, A>.Left(error);\n\n    static K<Either<L>, A> Fallible<L, Either<L>>.Catch<A>(\n        K<Either<L>, A> fa, Func<L, bool> Predicate,\n        Func<L, K<Either<L>, A>> Fail) =>\n        fa.As().BindLeft(l => Predicate(l) ? Fail(l).As() : Either.Left<L, A>(l));\n\n    static K<Option, A> Natural<Either<L>, Option>.Transform<A>(K<Either<L>, A> fa) =>\n        fa switch\n        {\n            Either<L, A>.Right (var r) => Option.Some(r),\n            _                          => Option<A>.None\n        };\n    \n    static Fold<A, S> Foldable<Either<L>>.FoldStep<A, S>(K<Either<L>, A> ta, S initialState)\n    {\n        var ma = ta.As();\n        return ma.IsRight\n                   ? Fold.Loop(initialState, ma.RightValue, Fold.Done<A, S>)\n                   : Fold.Done<A, S>(initialState);\n    }    \n        \n    static Fold<A, S> Foldable<Either<L>>.FoldStepBack<A, S>(K<Either<L>, A> ta, S initialState) =>\n        ta.FoldStep(initialState);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/EitherT.Module.cs",
    "content": "﻿using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class EitherT\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> Right<L, M, A>(A value)  \n        where M : Monad<M> =>\n        lift<L, M, A>(M.Pure(value));\n\n    /// <summary>\n    /// Lift a fail value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> Left<L, M, A>(L value)  \n        where M : Monad<M> =>\n        lift<L, M, A>(Either.Left<L, A>(value));\n\n    /// <summary>\n    /// Lifts a given `Either` value into the transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> lift<L, M, A>(Either<L, A> value)  \n        where M : Monad<M> =>\n        new(M.Pure(value));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> lift<L, M, A>(K<M, A> ma)  \n        where M : Monad<M> =>\n        new(M.Map(Either.Right<L, A>, ma));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> lift<L, M, A>(K<M, Either<L, A>> ma) \n        where M : Monad<M> =>\n        new(ma);\n\n    /// <summary>\n    /// Lifts a given value into the transformer\n    /// </summary>\n    /// <param name=\"pure\">Value to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> lift<L, M, A>(Pure<A> ma)  \n        where M : Monad<M> =>\n        Right<L, M, A>(ma.Value);\n\n    /// <summary>\n    /// Lifts a given value into the transformer\n    /// </summary>\n    /// <param name=\"fail\">Value to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> lift<L, M, A>(Fail<L> ma)  \n        where M : Monad<M> =>\n        lift<L, M, A>(Either.Left<L, A>(ma.Value));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> liftIO<L, M, A>(K<IO, A> ma)  \n        where M : MonadIO<M> =>\n        lift<L, M, A>(M.LiftIO(ma));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, A> liftIO<L, M, A>(IO<Either<L, A>> ma)  \n        where M : MonadIO<M> =>\n        lift(M.LiftIO(ma));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`EitherT`</returns>\n    internal static EitherT<L, M, A> liftIOMaybe<L, M, A>(K<IO, A> ma)  \n        where M : Monad<M> =>\n        lift<L, M, A>(M.LiftIOMaybe(ma));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`EitherT`</returns>\n    internal static EitherT<L, M, A> liftIOMaybe<L, M, A>(IO<Either<L, A>> ma)  \n        where M : Monad<M> =>\n        lift(M.LiftIOMaybe(ma));    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/EitherT.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `EitherT` monad transformer, which allows for either an `L` or `R` result value to be carried. \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"L\">Left value type</typeparam>\n/// <typeparam name=\"R\">Bound value type</typeparam>\npublic record EitherT<L, M, R>(K<M, Either<L, R>> runEither) : \n    K<EitherT<L, M>, R>,\n    K<EitherT<M>, L, R>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Is the `EitherT` in a Right state?\n    /// </summary>\n    public K<M, bool> IsRight =>\n        Match(Left: _ => false, Right: _ => true);\n\n    /// <summary>\n    /// Is the `EitherT` in a Left state?\n    /// </summary>\n    public K<M, bool> IsLeft =>\n        Match(Left: _ => true, Right: _ => false);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Match\n    //\n\n    /// <summary>\n    /// Invokes the Right or Left function depending on the state of the Either\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Left\">Function to invoke if in a Left state</param>\n    /// <param name=\"Right\">Function to invoke if in a Right state</param>\n    /// <returns>The return value of the invoked function</returns>\n    [Pure]\n    public K<M, B> Match<B>(Func<L, B> Left, Func<R, B> Right) =>\n        M.Map(mx => mx.Match(Left: Left, Right: Right), runEither);\n\n    /// <summary>\n    /// Invokes the Right or Left action depending on the state of the Either\n    /// </summary>\n    /// <param name=\"Right\">Action to invoke if in a Right state</param>\n    /// <param name=\"Left\">Action to invoke if in a Left state</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public K<M, Unit> Match(Action<L> Left, Action<R> Right) =>\n        M.Map(mx => mx.Match(Left: Left, Right: Right), runEither);\n \n    /// <summary>\n    /// Executes the Left function if the Either is in a Left state.\n    /// Returns the Right value if the Either is in a Right state.\n    /// </summary>\n    /// <param name=\"Left\">Function to generate a Right value if in the Left state</param>\n    /// <returns>Returns an unwrapped Right value</returns>\n    [Pure]\n    public K<M, R> IfLeft(Func<R> Left) =>\n        IfLeft(_ => Left());\n\n    /// <summary>\n    /// Executes the leftMap function if the Either is in a Left state.\n    /// Returns the Right value if the Either is in a Right state.\n    /// </summary>\n    /// <param name=\"leftMap\">Function to generate a Right value if in the Left state</param>\n    /// <returns>Returns an unwrapped Right value</returns>\n    [Pure]\n    public K<M, R> IfLeft(Func<L, R> leftMap) =>\n        Match(Left: leftMap, Right: identity);\n\n    /// <summary>\n    /// Returns the rightValue if the Either is in a Left state.\n    /// Returns the Right value if the Either is in a Right state.\n    /// </summary>\n    /// <param name=\"rightValue\">Value to return if in the Left state</param>\n    /// <returns>Returns an unwrapped Right value</returns>\n    [Pure]\n    public K<M, R> IfLeft(R rightValue) =>\n        IfLeft(_ => rightValue);\n\n    /// <summary>\n    /// Executes the Left action if the Either is in a Left state.\n    /// </summary>\n    /// <param name=\"Left\">Function to generate a Right value if in the Left state</param>\n    /// <returns>Returns an unwrapped Right value</returns>\n    public K<M, Unit> IfLeft(Action<L> Left) =>\n        Match(Left: Left, Right: _ => {});\n\n    /// <summary>\n    /// Invokes the Right action if the Either is in a Right state, otherwise does nothing\n    /// </summary>\n    /// <param name=\"Right\">Action to invoke</param>\n    /// <returns>Unit</returns>\n    public K<M, Unit> IfRight(Action<R> Right) =>\n        Match(Left: _ => { }, Right: Right);\n\n    /// <summary>\n    /// Returns the leftValue if the Either is in a Right state.\n    /// Returns the Left value if the Either is in a Left state.\n    /// </summary>\n    /// <param name=\"leftValue\">Value to return if in the Left state</param>\n    /// <returns>Returns an unwrapped Left value</returns>\n    [Pure]\n    public K<M, L> IfRight(L leftValue) =>\n        Match(Left: identity, Right: _ => leftValue);\n\n    /// <summary>\n    /// Returns the result of Right() if the Either is in a Right state.\n    /// Returns the Left value if the Either is in a Left state.\n    /// </summary>\n    /// <param name=\"Right\">Function to generate a Left value if in the Right state</param>\n    /// <returns>Returns an unwrapped Left value</returns>\n    [Pure]\n    public K<M, L> IfRight(Func<L> Right) =>\n        Match(Left: identity, Right: _ => Right());\n\n    /// <summary>\n    /// Returns the result of rightMap if the Either is in a Right state.\n    /// Returns the Left value if the Either is in a Left state.\n    /// </summary>\n    /// <param name=\"rightMap\">Function to generate a Left value if in the Right state</param>\n    /// <returns>Returns an unwrapped Left value</returns>\n    [Pure]\n    public K<M, L> IfRight(Func<R, L> rightMap) =>\n        Match(Left: identity, Right: rightMap);\n \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M1\">Target monad type</typeparam>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Mapped monad</returns>\n    public EitherT<L, M1, B> MapT<M1, B>(Func<K<M, Either<L, R>>, K<M1, Either<L, B>>> f)\n        where M1 : Monad<M1> =>\n        new (f(runEither));\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    public EitherT<L, M, B> MapM<B>(Func<K<M, R>, K<M, B>> f) =>\n        new(runEither\n               .Bind(fv => fv switch\n                           {\n                               Either<L, R>.Right (var v) => f(M.Pure(v)).Map(Either.Right<L, B>),\n                               Either<L, R>.Left (var e)  => M.Pure<Either<L, B>>(e),\n                               _                          => throw new NotSupportedException()\n                           }));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Mapped structure</returns>\n    public EitherT<L, M, B> Map<B>(Func<R, B> f) =>\n        new(M.Map(mx => mx.Map(f), runEither));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Mapped structure</returns>\n    public EitherT<L, M, B> Select<B>(Func<R, B> f) =>\n        new(M.Map(mx => mx.Map(f), runEither));\n    \n    /// <summary>\n    /// Maps the left value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Mapped structure</returns>\n    public EitherT<B, M, R> MapLeft<B>(Func<L, B> f) =>\n        new(M.Map(mx => mx.MapLeft(f), runEither));\n\n    /// <summary>\n    /// Bifunctor map operation\n    /// </summary>\n    /// <param name=\"Left\">Left map function</param>\n    /// <param name=\"Right\">Right map function</param>\n    /// <typeparam name=\"L1\">Target left type</typeparam>\n    /// <typeparam name=\"R1\">Target right type</typeparam>\n    /// <returns>Mapped structure</returns>\n    public EitherT<L1, M, R1> BiMap<L1, R1>(\n        Func<L, L1> Left, \n        Func<R, R1> Right) => \n        Bifunctor.bimap(Left, Right, this).As2();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, B> Bind<B>(Func<R, K<EitherT<L, M>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, B> Bind<B>(Func<R, Either<L, B>> f) =>\n        Bind(x => EitherT.lift<L, M, B>(f(x)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, B> Bind<B>(Func<R, EitherT<L, M, B>> f) =>\n        new(M.Bind(runEither, \n                   ex => ex.Match(\n                       Right: x => f(x).runEither,\n                       Left: e => M.Pure(Either.Left<L, B>(e)))));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, B> Bind<B>(Func<R, Pure<B>> f) =>\n        Map(a => f(a).Value);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, B> Bind<B>(Func<R, Fail<L>> f) =>\n        Bind(a => EitherT.lift<L, M, B>(f(a).Value));\n\n    /// <summary>\n    /// Bimonad bind left\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <typeparam name=\"L1\"></typeparam>\n    /// <returns></returns>\n    public EitherT<L1, M, R> BindLeft<L1>(Func<L, K<EitherT<M>, L1, R>> f) =>\n        Bimonad.bindFirst(this, f).As2();\n\n    /// <summary>\n    /// Bimonad bind right\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <typeparam name=\"L1\"></typeparam>\n    /// <returns></returns>\n    public EitherT<L, M, R1> BindRight<R1>(Func<R, K<EitherT<M>, L, R1>> f) =>\n        Bimonad.bindSecond(this, f).As2();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, C> SelectMany<B, C>(Func<R, K<EitherT<L, M>, B>> bind, Func<R, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, C> SelectMany<B, C>(Func<R, EitherT<L, M, B>> bind, Func<R, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, C> SelectMany<B, C>(Func<R, K<M, B>> bind, Func<R, B, C> project) =>\n        SelectMany(x => EitherT.lift<L, M, B>(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, C> SelectMany<B, C>(Func<R, Either<L, B>> bind, Func<R, B, C> project) =>\n        SelectMany(x => EitherT.lift<L, M, B>(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, C> SelectMany<B, C>(Func<R, Pure<B>> bind, Func<R, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, C> SelectMany<B, C>(Func<R, IO<B>> bind, Func<R, B, C> project) =>\n        SelectMany(x => M.LiftIOMaybe(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public EitherT<L, M, C> SelectMany<C>(Func<R, Guard<L, Unit>> bind, Func<R, Unit, C> project) =>\n        SelectMany(x => bind(x).ToEither(), project);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n\n    public static implicit operator EitherT<L, M, R>(Either<L, R> ma) =>\n        EitherT.lift<L, M, R>(ma);\n    \n    public static implicit operator EitherT<L, M, R>(Pure<R> ma) =>\n        EitherT.Right<L, M, R>(ma.Value);\n\n    public static implicit operator EitherT<L, M, R>(Fail<L> ma) =>\n        EitherT.lift<L, M, R>(ma);\n\n    public static implicit operator EitherT<L, M, R>(L fail) =>\n        EitherT.Left<L, M, R>(fail);\n\n    public static implicit operator EitherT<L, M, R>(IO<R> ma) =>\n        EitherT.liftIOMaybe<L, M, R>(ma);\n    \n    public static implicit operator EitherT<L, M, R>(Lift<R> ma) =>\n        EitherT.liftIOMaybe<L, M, R>(ma.ToIO());\n    \n    public static implicit operator EitherT<L, M, R>(Lift<EnvIO, R> ma) =>\n        EitherT.liftIOMaybe<L, M, R>(ma.ToIO());\n    \n    public static implicit operator EitherT<L, M, R>(IO<Either<L, R>> ma) =>\n        EitherT.liftIOMaybe<L, M, R>(ma);\n\n    public OptionT<M, R> ToOption() =>\n        new(runEither.Map(ma => ma.ToOption()));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Extensions/EitherT.Extensions.Apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static EitherT<L, M, B> Action<L, M, A, B>(this EitherT<L, M, A> ma, K<EitherT<L, M>, B> mb)\n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static EitherT<L, M, B> Action<L, M, A, B>(this K<EitherT<L, M>, A> ma, K<EitherT<L, M>, B> mb)\n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static EitherT<L, M, B> Apply<L, M, A, B>(this EitherT<L, M, Func<A, B>> mf, K<EitherT<L, M>, A> ma) \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static EitherT<L, M, B> Apply<L, M, A, B>(this K<EitherT<L, M>, Func<A, B>> mf, K<EitherT<L, M>, A> ma) \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Extensions/EitherT.Extensions.Map.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static EitherT<L, M, B> Map<L, M, A, B>(this Func<A, B> f, K<EitherT<L, M>, A> ma) \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static EitherT<L, M, B> Map<L, M, A, B>(this Func<A, B> f, EitherT<L, M, A> ma)\n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Extensions/EitherT.Extensions.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing NSE = System.NotSupportedException;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// EitherT monad-transformer extensions\n/// </summary>\npublic static partial class EitherTExtensions\n{\n    public static EitherT<L, M, R> As<L, M, R>(this K<EitherT<L, M>, R> ma)\n        where M : Monad<M> =>\n        (EitherT<L, M, R>)ma;\n \n    public static EitherT<L, M, R> As2<L, M, R>(this K<EitherT<M>, L, R> ma) \n        where M : Monad<M> =>\n        (EitherT<L, M, R>)ma;\n\n    public static FinT<M, R> ToFin<M, R>(this K<EitherT<Error, M>, R> ma) \n        where M : Monad<M> =>\n        new(ma.As().runEither.Map(ma => ma.ToFin()));\n\n    /// <summary>\n    /// Runs the EitherT exposing the outer monad with an inner wrapped `Either`\n    /// </summary>\n    public static K<M, Either<L, A>> Run<L, M, A>(this K<EitherT<L, M>, A> ma)\n        where M : Monad<M> =>\n        ma.As().runEither;\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    public static EitherT<L, M, B> Bind<L, M, A, B>(this K<EitherT<L, M>, A> ma, Func<A, IO<B>> f) \n        where M : MonadIO<M> =>\n        ma.As().Bind(a => EitherT.liftIO<L, M, B>(f(a)));\n    \n    /// <summary>\n    /// Get the outer task and wrap it up in a new IO within the EitherT IO\n    /// </summary>\n    public static EitherT<L, IO, A> Flatten<L, A>(this Task<EitherT<L, IO, A>> tma) =>\n        EitherT\n           .lift<L, IO, EitherT<L, IO, A>>(IO.liftAsync(async () => await tma.ConfigureAwait(false)))\n           .Flatten();\n\n    /// <summary>\n    /// Lift the task\n    /// </summary>\n    public static EitherT<L, IO, A> ToIO<L, A>(this Task<Either<L, A>> ma) =>\n        liftIO(ma);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static EitherT<L, M, A> Flatten<L, M, A>(this EitherT<L, M, EitherT<L, M, A>> mma)\n        where M : Monad<M> =>\n        mma.Bind(identity);\n\n    /// <summary>\n    /// Filtering based on predicate.  \n    /// </summary>\n    /// <remarks>>\n    /// If the predicate returns false, then `Left(L.Empty)` is yielded and therefore `L` must be a monoid.  \n    /// </remarks>\n    [Pure]\n    public static EitherT<L, M, A> Where<L, M, A>(this K<EitherT<L, M>, A> ma, Func<A, bool> pred)\n        where L : Monoid<L>\n        where M : Monad<M> =>\n        ma.Filter(pred);\n\n    /// <summary>\n    /// Filtering based on predicate.  \n    /// </summary>\n    /// <remarks>>\n    /// If the predicate returns false, then `Left(L.Empty)` is yielded and therefore `L` must be a monoid.  \n    /// </remarks>\n    [Pure]\n    public static EitherT<L, M, A> Filter<L, M, A>(this K<EitherT<L, M>, A> ma, Func<A, bool> pred)\n        where L : Monoid<L>\n        where M : Monad<M> =>\n        ma.As().Bind(x => pred(x) ? EitherT.Right<L, M, A>(x) : EitherT.Left<L, M, A>(L.Empty));    \n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    [Pure]\n    public static EitherT<L, M, C> SelectMany<L, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<EitherT<L, M>, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        EitherT.lift<L, M, A>(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`EitherT`</returns>\n    [Pure]\n    public static EitherT<L, M, C> SelectMany<L, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, EitherT<L, M, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        EitherT.lift<L, M, A>(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Partitions a foldable of `EitherT` into two sequences.\n    /// \n    /// All the `Left` elements are extracted, in order, to the first component of the output.\n    /// Similarly, the `Right` elements are extracted to the second component of the output.\n    /// </summary>\n    /// <returns>A pair containing the sequences of partitioned values</returns>\n    [Pure]\n    public static K<M, (Seq<L> Lefts, Seq<R> Rights)> Partition<F, L, M, R>(this K<F, EitherT<L, M, R>> self)\n        where F : Foldable<F>\n        where M : Monad<M> =>\n        self.Fold(M.Pure((Left: Seq<L>.Empty, Right: Seq<R>.Empty)),\n                  (ms, ma) =>\n                      ms.Bind(s => ma.Run().Map(a => a switch\n                                                     {\n                                                         Either<L, R>.Right (var r) => (s.Left, s.Right.Add(r)),\n                                                         Either<L, R>.Left (var l)  => (s.Left.Add(l), s.Right),\n                                                         _                          => throw new NSE()\n                                                     })));\n\n    /// <summary>\n    /// Partitions a foldable of `EitherT` into two lists and returns the `Left` items only.\n    /// </summary>\n    /// <returns>A sequence of partitioned items</returns>\n    [Pure]\n    public static K<M, Seq<L>> Lefts<F, L, M, R>(this K<F, EitherT<L, M, R>> self)\n        where F : Foldable<F>\n        where M : Monad<M> =>\n        self.Fold(M.Pure(Seq<L>.Empty),\n                  (ms, ma) =>\n                      ms.Bind(s => ma.Run().Map(a => a switch\n                                                     {\n                                                         Either<L, R>.Left (var l)  => s.Add(l),\n                                                         _                          => throw new NSE()\n                                                     })));\n\n    /// <summary>\n    /// Partitions a foldable of `EitherT` into two lists and returns the `Right` items only.\n    /// </summary>\n    /// <returns>A sequence of partitioned items</returns>\n    [Pure]\n    public static K<M, Seq<R>> Rights<F, L, M, R>(this K<F, EitherT<L, M, R>> self)\n        where F : Foldable<F>\n        where M : Monad<M> =>\n        self.Fold(M.Pure(Seq<R>.Empty),\n                  (ms, ma) =>\n                      ms.Bind(s => ma.Run().Map(a => a switch\n                                                     {\n                                                         Either<L, R>.Right (var r) => s.Add(r),\n                                                         _                          => throw new NSE()\n                                                     })));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Extensions/EitherT.Guard.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class EitherTGuardExtensions\n{\n    /// <summary>\n    /// Natural transformation to `EitherT`\n    /// </summary>\n    public static EitherT<L, M, Unit> ToEitherT<L, M>(this Guard<L, Unit> guard)\n        where M : Monad<M> =>\n        guard.Flag\n            ? EitherT.Right<L, M, Unit>(default)\n            : EitherT.Left<L, M, Unit>(guard.OnFalse());\n\n    /// <summary>\n    /// Monadic binding support for `EitherT`\n    /// </summary>\n    public static EitherT<L, M, B> Bind<L, M, B>(\n        this Guard<L, Unit> guard,\n        Func<Unit, EitherT<L, M, B>> f)\n        where M : Monad<M> =>\n        guard.Flag\n            ? f(default).As()\n            : EitherT.Left<L, M, B>(guard.OnFalse());\n\n    /// <summary>\n    /// Monadic binding support for `EitherT`\n    /// </summary>\n    public static EitherT<L, M, C> SelectMany<L, M, B, C>(\n        this Guard<L, Unit> guard,\n        Func<Unit, EitherT<L, M, B>> bind,\n        Func<Unit, B, C> project)\n        where M : Monad<M> =>\n        guard.Flag\n            ? bind(default).As().Map(b => project(default, b))\n            : EitherT.Left<L, M, C>(guard.OnFalse());\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Operators/EitherT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    extension<L, M, A, B>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static EitherT<L, M, B> operator >>> (K<EitherT<L, M>, A> ma, K<EitherT<L, M>, B> mb) =>\n            ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, B> operator * (K<EitherT<L, M>, Func<A, B>> mf, K<EitherT<L, M>, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, B> operator * (K<EitherT<L, M>, A> ma, K<EitherT<L, M>, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<L, M, A, B, C>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, C>> operator * (\n            K<EitherT<L, M>, Func<A, B, C>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, C>> operator * (\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<L, M, A, B, C, D>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, D>>> operator * (\n            K<EitherT<L, M>, Func<A, B, C, D>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, D>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<L, M, A, B, C, D, E>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<EitherT<L, M>, Func<A, B, C, D, E>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<L, M, A, B, C, D, E, F>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<EitherT<L, M>, Func<A, B, C, D, E, F>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<L, M, A, B, C, D, E, F, G>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<L, M, A, B, C, D, E, F, G, H>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<L, M, A, B, C, D, E, F, G, H, I>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<L, M, A, B, C, D, E, F, G, H, I, J>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<L, M, A, B, C, D, E, F, G, H, I, J, K>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<EitherT<L, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<EitherT<L, M>, A> ma,\n            K<EitherT<L, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Operators/EitherT.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    extension<L, M, A>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        public static EitherT<L, M, A> operator |(K<EitherT<L, M>, A> lhs, K<EitherT<L, M>, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static EitherT<L, M, A> operator |(K<EitherT<L, M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(EitherT.lift<L, M, A>(rhs.ToEither<L>()));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Operators/EitherT.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    extension<L, M, A>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        public static EitherT<L, M, A> operator |(K<EitherT<L, M>, A> lhs, CatchM<L, EitherT<L, M>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static EitherT<L, M, A> operator |(K<EitherT<L, M>, A> lhs, Fail<L> rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Operators/EitherT.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class EitherTExtensions\n{\n    extension<X, L, M, A>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>, Final<M>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static EitherT<L, M, A> operator |(K<EitherT<L, M>, A> lhs, Finally<M, X> rhs) =>\n            new (lhs.As().runEither.Finally(rhs.Operation));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Operators/EitherT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    extension<L, M, A, B>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, B> operator *(Func<A, B> f, K<EitherT<L, M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, B> operator *(K<EitherT<L, M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<L, M, A, B, C>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, C>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<L, M, A, B, C, D>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, D>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<L, M, A, B, C, D, E>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<L, M, A, B, C, D, E, F>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<L, M, A, B, C, D, E, F, G>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<L, M, A, B, C, D, E, F, G, H>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<L, M, A, B, C, D, E, F, G, H, I>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<L, M, A, B, C, D, E, F, G, H, I, J>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<L, M, A, B, C, D, E, F, G, H, I, J, K>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<EitherT<L, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static EitherT<L, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<EitherT<L, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Operators/EitherT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    extension<L, M, A, B>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static EitherT<L, M, B> operator >> (K<EitherT<L, M>, A> ma, Func<A, K<EitherT<L, M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static EitherT<L, M, B> operator >> (K<EitherT<L, M>, A> lhs, K<EitherT<L, M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<L, M, A, B>(K<EitherT<L, M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static EitherT<L, M, B> operator >> (K<EitherT<L, M>, A> ma, Func<A, K<IO, B>> f) =>\n            +ma.Bind(x => +f(x));\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static EitherT<L, M, B> operator >> (K<EitherT<L, M>, A> lhs, K<IO, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<L, M, A>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static EitherT<L, M, A> operator >> (K<EitherT<L, M>, A> lhs, K<EitherT<L, M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n        \n    extension<L, M, A>(K<EitherT<L, M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static EitherT<L, M, A> operator >> (K<EitherT<L, M>, A> lhs, K<IO, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Operators/EitherT.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    extension<L, M, A>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>\n    {\n        public static EitherT<L, M, A> operator +(K<EitherT<L, M>, A> lhs, K<EitherT<L, M>, A> rhs) =>\n            new(lhs.As().runEither.Combine(rhs.As().runEither));\n\n        public static EitherT<L, M, A> operator +(K<EitherT<L, M>, A> lhs, Pure<A> rhs) =>\n            new(lhs.As().runEither.Combine(M.Pure(Either.Right<L, A>(rhs.Value))));\n    }\n    \n    extension<E, L, M, A>(K<EitherT<L, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Fallible<E, M>\n    {\n        public static EitherT<L, M, A> operator +(K<EitherT<L, M>, A> lhs, Fail<E> rhs) =>\n            new(lhs.As().runEither.Combine(M.Fail<Either<L, A>>(rhs.Value)));\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Operators/EitherT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class EitherTExtensions\n{\n    extension<L, M, A>(K<EitherT<L, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static EitherT<L, M, A> operator +(K<EitherT<L, M>, A> ma) =>\n            (EitherT<L, M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static EitherT<L, M, A> operator >> (K<EitherT<L, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Trait/EitherT.TraitImpl.2.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class EitherT<M> :\n    CoproductK<EitherT<M>>,\n    Bimonad<EitherT<M>>\n    where M : Monad<M>\n{\n    static K<EitherT<M>, A, B> CoproductCons<EitherT<M>>.Left<A, B>(A value) => \n        EitherT.Left<A, M, B>(value);\n\n    static K<EitherT<M>, A, B> CoproductCons<EitherT<M>>.Right<A, B>(B value) => \n        EitherT.Right<A, M, B>(value);\n\n    static K<EitherT<M>, A, C> CoproductK<EitherT<M>>.Match<A, B, C>(\n        Func<A, C> Left, \n        Func<B, C> Right,\n        K<EitherT<M>, A, B> fab) => \n        EitherT.lift<A, M, C>(fab.As2().Match(Left, Right));\n\n    static K<EitherT<M>, L1, B> Bifunctor<EitherT<M>>.BiMap<L, A, L1, B>(\n        Func<L, L1> first, \n        Func<A, B> second, \n        K<EitherT<M>, L, A> fab) => \n        new EitherT<L1, M, B>(fab.As2().runEither.Map(e => e.BiMap(first, second)));\n\n    static K<EitherT<M>, L1, A> Bimonad<EitherT<M>>.BindFirst<L, L1, A>(\n        K<EitherT<M>, L, A> ma,\n        Func<L, K<EitherT<M>, L1, A>> f) =>\n        new EitherT<L1, M, A>(ma.As2()\n                                .runEither\n                                .Bind(e => e switch\n                                           {\n                                               Either<L, A>.Right(var r) => M.Pure(Either.Right<L1, A>(r)),\n                                               Either<L, A>.Left(var l)  => f(l).As2().runEither,\n                                               _                         => throw new NotSupportedException()\n                                           }));\n\n    static K<EitherT<M>, L, B> Bimonad<EitherT<M>>.BindSecond<L, A, B>(\n        K<EitherT<M>, L, A> ma,\n        Func<A, K<EitherT<M>, L, B>> f) =>\n        new EitherT<L, M, B>(ma.As2()\n                               .runEither\n                               .Bind(e => e switch\n                                          {\n                                              Either<L, A>.Right(var r) => f(r).As2().runEither,\n                                              Either<L, A>.Left(var l)  => M.Pure(Either.Left<L, B>(l)),\n                                              _                         => throw new NotSupportedException()\n                                          }));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/EitherT/Trait/EitherT.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `EitherT` \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class EitherT<L, M> : \n    MonadT<EitherT<L, M>, M>, \n    Fallible<L, EitherT<L, M>>,\n    Choice<EitherT<L, M>>,\n    Natural<EitherT<L, M>, OptionT<M>>,\n    MonadIO<EitherT<L, M>>\n    where M : Monad<M>\n{\n    static K<EitherT<L, M>, B> Monad<EitherT<L, M>>.Bind<A, B>(K<EitherT<L, M>, A> ma, Func<A, K<EitherT<L, M>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<EitherT<L, M>, B> Monad<EitherT<L, M>>.Recur<A, B>(A value, Func<A, K<EitherT<L, M>, Next<A, B>>> f) =>\n        new EitherT<L, M, B>(\n            M.Recur<A, Either<L, B>>(\n                value,\n                a => f(a).As()\n                         .runEither\n                         .Map(e => e switch\n                                   {\n                                       Either<L, Next<A, B>>.Left(var l)               => Next.Done<A, Either<L, B>>(l), \n                                       Either<L, Next<A, B>>.Right({ IsDone: true } n) => Next.Done<A, Either<L, B>>(n.Done), \n                                       Either<L, Next<A, B>>.Right({ IsLoop: true } n) => Next.Loop<A, Either<L, B>>(n.Loop),\n                                       _ => throw new NotSupportedException()\n                                   })));\n\n    static K<EitherT<L, M>, B> Functor<EitherT<L, M>>.Map<A, B>(Func<A, B> f, K<EitherT<L, M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<EitherT<L, M>, A> Applicative<EitherT<L, M>>.Pure<A>(A value) => \n        EitherT.Right<L, M, A>(value);\n\n    static K<EitherT<L, M>, B> Applicative<EitherT<L, M>>.Apply<A, B>(K<EitherT<L, M>, Func<A, B>> mf, K<EitherT<L, M>, A> ma) =>\n        mf.As().Bind(x => ma.As().Map(x));\n\n    static K<EitherT<L, M>, B> Applicative<EitherT<L, M>>.Apply<A, B>(K<EitherT<L, M>, Func<A, B>> mf, Memo<EitherT<L, M>, A> ma) =>\n        mf.As().Bind(x => ma.Value.As().Map(x));\n\n    static K<EitherT<L, M>, A> MonadT<EitherT<L, M>, M>.Lift<A>(K<M, A> ma) => \n        EitherT.lift<L, M, A>(ma);\n        \n    static K<EitherT<L, M>, A> MonadIO<EitherT<L, M>>.LiftIO<A>(IO<A> ma) => \n        EitherT.lift<L, M, A>(M.LiftIOMaybe(ma));\n\n    static K<EitherT<L, M>, A> Choice<EitherT<L, M>>.Choose<A>(K<EitherT<L, M>, A> ma, K<EitherT<L, M>, A> mb) =>\n        new EitherT<L, M, A>(\n            M.Bind(ma.As().runEither,\n                   ea => ea switch\n                         {\n                             Either<L, A>.Right => M.Pure(ea),\n                             Either<L, A>.Left  => mb.As().runEither,\n                             _                  => M.Pure(ea)\n                         }));\n\n    static K<EitherT<L, M>, A> Choice<EitherT<L, M>>.Choose<A>(K<EitherT<L, M>, A> ma, Memo<EitherT<L, M>, A> mb) =>\n        new EitherT<L, M, A>(\n            M.Bind(ma.As().runEither,\n                   ea => ea switch\n                         {\n                             Either<L, A>.Right => M.Pure(ea),\n                             Either<L, A>.Left  => mb.Value.As().runEither,\n                             _                  => M.Pure(ea)\n                         }));\n\n    static K<EitherT<L, M>, A> Fallible<L, EitherT<L, M>>.Fail<A>(L error) =>\n        EitherT.Left<L, M, A>(error);\n\n    static K<EitherT<L, M>, A> Fallible<L, EitherT<L, M>>.Catch<A>(\n        K<EitherT<L, M>, A> fa, Func<L, bool> Predicate,\n        Func<L, K<EitherT<L, M>, A>> Fail) =>\n        fa.As().BindLeft(l => Predicate(l) ? Fail(l).As() : EitherT.Left<L, M, A>(l));\n\n    static K<OptionT<M>, A> Natural<EitherT<L, M>, OptionT<M>>.Transform<A>(K<EitherT<L, M>, A> fa) => \n        new OptionT<M, A>(fa.As().runEither.Map(Natural.transform<Either<L>, Option, A>).Map(ma => ma.As()));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Extensions/Fin.Extensions.Apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Fin<B> Action<A, B>(this Fin<A> ma, K<Fin, B> mb) =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Fin<B> Action<A, B>(this K<Fin, A> ma, K<Fin, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Fin<B> Apply<A, B>(this Fin<Func<A, B>> mf, K<Fin, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Fin<B> Apply<A, B>(this K<Fin, Func<A, B>> mf, K<Fin, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Extensions/Fin.Extensions.Map.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Fin<B> Map<A, B>(this Func<A, B> f, K<Fin, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Fin<B> Map<A, B>(this Func<A, B> f, Fin<A> ma) =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Extensions/Fin.Extensions.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing LanguageExt.Common;\nusing NSE = System.NotSupportedException;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Extension methods for Fin\n/// </summary>\npublic static partial class FinExtensions\n{\n    public static Fin<A> As<A>(this K<Fin, A> ma) =>\n        (Fin<A>)ma;\n    \n    /// <summary>\n    /// Natural transformation from `Either` to `Fin`\n    /// </summary>\n    public static Fin<A> ToFin<A>(this Either<Error, A> ma) =>\n        ma.Match(Right: Fin.Succ, Left: Fin.Fail<A>);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Fin<R> Flatten<R>(this Fin<Fin<R>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Add the bound values of x and y, uses an Add trait to provide the add\n    /// operation for type A.  For example x.Add〈TInteger, int〉(y)\n    /// </summary>\n    /// <typeparam name=\"NUM\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"x\">Left hand side of the operation</param>\n    /// <param name=\"y\">Right hand side of the operation</param>\n    /// <returns>Fin with y added to x</returns>\n    [Pure]\n    public static Fin<R> Plus<NUM, R>(this Fin<R> x, Fin<R> y) where NUM : Arithmetic<R> =>\n        from a in x\n        from b in y\n        select NUM.Add(a, b);\n\n    /// <summary>\n    /// Find the difference between the two bound values of x and y, uses a Subtract trait \n    /// to provide the subtract operation for type A.  For example x.Subtract〈TInteger, int〉(y)\n    /// </summary>\n    /// <typeparam name=\"NUM\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"x\">Left hand side of the operation</param>\n    /// <param name=\"y\">Right hand side of the operation</param>\n    /// <returns>Fin with the difference between x and y</returns>\n    [Pure]\n    public static Fin<R> Subtract<NUM, R>(this Fin<R> x, Fin<R> y) where NUM : Arithmetic<R> =>\n        from a in x\n        from b in y\n        select NUM.Subtract(a, b);\n\n    /// <summary>\n    /// Find the product between the two bound values of x and y, uses a Product trait \n    /// to provide the product operation for type A.  For example x.Product〈TInteger, int〉(y)\n    /// </summary>\n    /// <typeparam name=\"NUM\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"x\">Left hand side of the operation</param>\n    /// <param name=\"y\">Right hand side of the operation</param>\n    /// <returns>Fin with the product of x and y</returns>\n    [Pure]\n    public static Fin<R> Product<NUM, R>(this Fin<R> x, Fin<R> y) where NUM : Arithmetic<R> =>\n        from a in x\n        from b in y\n        select NUM.Multiply(a, b);\n\n    /// <summary>\n    /// Divide the two bound values of x and y, uses a Divide trait to provide the divide\n    /// operation for type A.  For example x.Divide〈TDouble, double〉(y)\n    /// </summary>\n    /// <typeparam name=\"NUM\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"x\">Left hand side of the operation</param>\n    /// <param name=\"y\">Right hand side of the operation</param>\n    /// <returns>Fin x / y</returns>\n    [Pure]\n    public static Fin<R> Divide<NUM, R>(this Fin<R> x, Fin<R> y) where NUM : Num<R> =>\n        from a in x\n        from b in y\n        select NUM.Divide(a, b);\n\n    extension<F, A>(K<F, Fin<A>> self) where F : Foldable<F>\n    {\n        /// <summary>\n        /// Partitions a foldable of `Fin` into two sequences.\n        /// \n        /// All the `Fail` elements are extracted, in order, to the first component of the output.\n        /// Similarly, the `Succ` elements are extracted to the second component of the output.\n        /// </summary>\n        /// <returns>A pair containing the sequences of partitioned values</returns>\n        [Pure]\n        public (Seq<Error> Fails, Seq<A> Succs) Partition() =>\n            self.Fold((Fail: Seq<Error>.Empty, Succ: Seq<A>.Empty),\n                      (s, ma) =>\n                          ma switch\n                          {\n                              Fin<A>.Succ (var r) => (s.Fail, s.Succ.Add(r)),\n                              Fin<A>.Fail (var l) => (s.Fail.Add(l), s.Succ),\n                              _                   => throw new NSE()\n                          });\n\n        /// <summary>\n        /// Partitions a foldable of `Fin` into two lists and returns the `Fail` items only.\n        /// </summary>\n        /// <returns>A sequence of partitioned items</returns>\n        [Pure]\n        public Seq<Error> Fails() =>\n            self.Fold(Seq<Error>.Empty,\n                      (s, ma) =>\n                          ma switch\n                          {\n                              Fin<A>.Fail (var l) => s.Add(l),\n                              _                   => throw new NSE()\n                          });\n\n        /// <summary>\n        /// Partitions a foldable of `Fin` into two lists and returns the `Succ` items only.\n        /// </summary>\n        /// <returns>A sequence of partitioned items</returns>\n        [Pure]\n        public Seq<A> Succs() =>\n            self.Fold(Seq<A>.Empty,\n                      (s, ma) =>\n                          ma switch\n                          {\n                              Fin<A>.Succ (var r) => s.Add(r),\n                              _                   => throw new NSE()\n                          });\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Extensions/Fin.Guard.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class FinGuardExtensions\n{\n    /// <summary>\n    /// Natural transformation to `Fin`\n    /// </summary>\n    public static Fin<Unit> ToFin(this Guard<Error, Unit> ma) =>\n        ma.Flag\n            ? Fin.Succ(unit)\n            : Fin.Fail<Unit>(ma.OnFalse());\n    \n    /// <summary>\n    /// Monadic binding support for `Fin`\n    /// </summary>\n    public static Fin<B> Bind<B>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, Fin<B>> f)  =>\n        guard.Flag\n            ? f(default).As()\n            : Fin.Fail<B>(guard.OnFalse());\n        \n    /// <summary>\n    /// Monadic binding support for `Fin`\n    /// </summary>\n    public static Fin<B> SelectMany<B>(this Guard<Error, Unit> ma, Func<Unit, Fin<B>> f) =>\n        ma.Flag\n            ? f(default)\n            : Fin.Fail<B>(ma.OnFalse());\n\n    /// <summary>\n    /// Monadic binding support for `Fin`\n    /// </summary>\n    public static Fin<C> SelectMany<B, C>(\n        this Guard<Error, Unit> ma, \n        Func<Unit, Fin<B>> bind, \n        Func<Unit, B, C> project) =>\n        ma.Flag\n            ? bind(default).Map(b => project(default, b))\n            : Fin.Fail<C>(ma.OnFalse());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Fin.Fail.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\npublic partial class Fin<A>\n{\n    /// <summary>\n    /// Fail case for the `Fin` union-type\n    /// </summary>\n    /// <param name=\"Error\">Error value</param>\n    public sealed class Fail(Error Error) : Fin<A>\n    {\n        /// <summary>\n        /// Value accessor\n        /// </summary>\n        public Error Error { get; } = Error;\n\n        /// <summary>\n        /// Is the structure in a Success state?\n        /// </summary>\n        [Pure]\n        public override bool IsSucc =>\n            false;\n\n        /// <summary>\n        /// Is the structure in a Fail state?\n        /// </summary>\n        [Pure]\n        public override bool IsFail =>\n            true;\n\n        /// <summary>\n        /// Invokes the Succ or Fail function depending on the state of the structure\n        /// </summary>\n        /// <typeparam name=\"B\">Return type</typeparam>\n        /// <param name=\"Succ\">Function to invoke if in a Succ state</param>\n        /// <param name=\"Fail\">Function to invoke if in a Fail state</param>\n        /// <returns>The return value of the invoked function</returns>\n        [Pure]\n        public override B Match<B>(Func<A, B> Succ, Func<Error, B> Fail) =>\n            Fail(Error);\n\n        /// <summary>\n        /// Show the structure as a string\n        /// </summary>\n        [Pure]\n        public override string ToString() =>\n            $\"Fail({Error})\";\n\n        [Pure]\n        public override int GetHashCode<HashA>() =>\n            -1;\n\n        /// <summary>\n        /// Empty span\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<Error> FailSpan() =>\n            new([Error]);\n\n        /// <summary>\n        /// Span of right value\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<A> SuccSpan() =>\n            ReadOnlySpan<A>.Empty;\n\n        /// <summary>\n        /// Compare this structure to another to find its relative ordering\n        /// </summary>\n        [Pure]\n        public override int CompareTo<OrdA>(Fin<A> other) =>\n            other is Fail\n                ? 0\n                : -1;    \n\n        /// <summary>\n        /// Equality override\n        /// </summary>\n        [Pure]\n        public override bool Equals<EqA>(Fin<A> other) =>\n            other is Fail;\n\n        /// <summary>\n        /// Unsafe access to the success value \n        /// </summary>\n        internal override A SuccValue =>\n            throw new InvalidCastException();\n\n        /// <summary>\n        /// Unsafe access to the fail value \n        /// </summary>\n        /// <exception cref=\"InvalidCastException\"></exception>\n        internal override Error FailValue =>\n            Error;\n\n        /// <summary>\n        /// Maps the value in the structure\n        /// </summary>\n        /// <param name=\"f\">Map function</param>\n        /// <returns>Mapped structure</returns>\n        [Pure]\n        public override Fin<B> Map<B>(Func<A, B> f) =>\n            new Fin<B>.Fail(Error);\n\n        /// <summary>\n        /// Maps the value in the structure\n        /// </summary>\n        /// <param name=\"f\">Map function</param>\n        /// <returns>Mapped structure</returns>\n        [Pure]\n        public override Fin<A> MapFail(Func<Error, Error> f) =>\n            new Fail(f(Error));\n\n        /// <summary>\n        /// Bi-maps the structure\n        /// </summary>\n        /// <returns>Mapped Either</returns>\n        [Pure]\n        public override Fin<B> BiMap<B>(Func<A, B> Succ, Func<Error, Error> Fail) =>\n            new Fin<B>.Fail(Fail(Error));\n\n        /// <summary>\n        /// Monadic bind\n        /// </summary>\n        /// <typeparam name=\"B\">Resulting bound value</typeparam>\n        /// <param name=\"f\">Bind function</param>\n        /// <returns>Bound structure</returns>\n        [Pure]\n        public override Fin<B> Bind<B>(Func<A, Fin<B>> f) =>\n            new Fin<B>.Fail(Error);\n\n        /// <summary>\n        /// Bi-bind.  Allows mapping of both monad states\n        /// </summary>\n        [Pure]\n        public override Fin<B> BiBind<B>(\n            Func<A, Fin<B>> Succ,\n            Func<Error, Fin<B>> Fail) =>\n            Fail(Error);\n\n        public void Deconstruct(out Error value) =>\n            value = Error;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Fin.Module.cs",
    "content": "using LanguageExt.Common;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic partial class Fin\n{\n    /// <summary>\n    /// Construct a `Fin` value in a `Succ` state (success)\n    /// </summary>\n    /// <param name=\"value\">Value to construct the `Succ` state with</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed `Fin` value</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Fin<A> Succ<A>(A value) => \n        new Fin<A>.Succ(value);\n\n    /// <summary>\n    /// Construct a `Fin` value in a `Fail` state\n    /// </summary>\n    /// <param name=\"value\">Value to construct the `Fail` state with</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed `Fin` value</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Fin<A> Fail<A>(Error error) => \n        new Fin<A>.Fail(error);\n\n    /// <summary>\n    /// Construct a `Fin` value in a `Fail` state\n    /// </summary>\n    /// <param name=\"value\">Value to construct the `Fail` state with</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed `Fin` value</returns>\n    [Pure, MethodImpl(Opt.Default)]\n    public static Fin<A> Fail<A>(string error) => \n        new Fin<A>.Fail(Error.New(error));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Fin.Succ.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\npublic partial class Fin<A>\n{\n    /// <summary>\n    /// Success case for the `Fin` union-type\n    /// </summary>\n    /// <param name=\"Value\">Success value</param>\n    public sealed class Succ(A Value) : Fin<A>\n    {\n        /// <summary>\n        /// Value accessor\n        /// </summary>\n        public A Value { get; } = Value;\n\n        /// <summary>\n        /// Is the structure in a Success state?\n        /// </summary>\n        [Pure]\n        public override bool IsSucc =>\n            true;\n\n        /// <summary>\n        /// Is the structure in a Fail state?\n        /// </summary>\n        [Pure]\n        public override bool IsFail =>\n            false;\n\n        /// <summary>\n        /// Invokes the Succ or Fail function depending on the state of the structure\n        /// </summary>\n        /// <typeparam name=\"B\">Return type</typeparam>\n        /// <param name=\"Succ\">Function to invoke if in a Succ state</param>\n        /// <param name=\"Fail\">Function to invoke if in a Fail state</param>\n        /// <returns>The return value of the invoked function</returns>\n        [Pure]\n        public override B Match<B>(Func<A, B> Succ, Func<Error, B> Fail) =>\n            Succ(Value);\n\n        /// <summary>\n        /// Show the structure as a string\n        /// </summary>\n        [Pure]\n        public override string ToString() =>\n            Value is null ? \"Succ(null)\" : $\"Succ({Value})\";\n\n        /// <summary>\n        /// Get a hash code for the structure\n        /// </summary>\n        public override int GetHashCode<HashA>() =>\n            Value is null ? 0 :  HashA.GetHashCode(Value);\n\n        /// <summary>\n        /// Empty span\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<Error> FailSpan() =>\n            ReadOnlySpan<Error>.Empty;\n\n        /// <summary>\n        /// Span of right value\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<A> SuccSpan() =>\n            new([Value]);\n\n        /// <summary>\n        /// Compare this structure to another to find its relative ordering\n        /// </summary>\n        [Pure]\n        public override int CompareTo<OrdA>(Fin<A>? other) =>\n            other switch\n            {\n                Succ r => OrdA.Compare(Value, r.Value),\n                _      => 1\n            };\n\n        /// <summary>\n        /// Equality override\n        /// </summary>\n        [Pure]\n        public override bool Equals<EqA>(Fin<A> other) =>\n            other switch\n            {\n                Succ r => EqA.Equals(Value, r.Value),\n                _      => false\n            };\n\n        /// <summary>\n        /// Unsafe access to the success value \n        /// </summary>\n        internal override A SuccValue =>\n            Value;\n\n        /// <summary>\n        /// Unsafe access to the fail value \n        /// </summary>\n        /// <exception cref=\"InvalidCastException\"></exception>\n        internal override Error FailValue =>\n            throw new InvalidCastException();\n\n        /// <summary>\n        /// Maps the value in the structure\n        /// </summary>\n        /// <param name=\"f\">Map function</param>\n        /// <returns>Mapped structure</returns>\n        [Pure]\n        public override Fin<B> Map<B>(Func<A, B> Succ) =>\n            new Fin<B>.Succ(Succ(Value));\n\n        /// <summary>\n        /// Maps the value in the structure\n        /// </summary>\n        /// <param name=\"f\">Map function</param>\n        /// <returns>Mapped structure</returns>\n        [Pure]\n        public override Fin<A> MapFail(Func<Error, Error> f) =>\n            this;\n\n        /// <summary>\n        /// Bi-maps the structure\n        /// </summary>\n        /// <returns>Mapped Either</returns>\n        [Pure]\n        public override Fin<B> BiMap<B>(Func<A, B> Succ, Func<Error, Error> Fail) =>\n            new Fin<B>.Succ(Succ(Value));\n\n        /// <summary>\n        /// Monadic bind\n        /// </summary>\n        /// <typeparam name=\"B\">Resulting bound value</typeparam>\n        /// <param name=\"f\">Bind function</param>\n        /// <returns>Bound structure</returns>\n        [Pure]\n        public override Fin<B> Bind<B>(Func<A, Fin<B>> f) =>\n            f(Value);\n\n        /// <summary>\n        /// Bi-bind.  Allows mapping of both monad states\n        /// </summary>\n        [Pure]\n        public override Fin<B> BiBind<B>(\n            Func<A, Fin<B>> Succ,\n            Func<Error, Fin<B>> Fail) =>\n            Succ(Value);\n\n        public void Deconstruct(out A value) =>\n            value = Value;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Fin.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Equivalent of `Either〈Error, A〉`\n/// Called `Fin` because it is expected to be used as the concrete result of a computation\n/// </summary>\npublic abstract partial class Fin<A> : \n    IComparable<Fin<A>>, \n    IEquatable<Fin<A>>,\n    IComparable, \n    K<Fin, A>\n{\n    /// <summary>\n    /// Stop other types deriving from Fin\n    /// </summary>\n    private Fin() {}\n    \n    /// <summary>\n    /// Is the structure in a Success state?\n    /// </summary>\n    [Pure]\n    public abstract bool IsSucc { get; }\n\n    /// <summary>\n    /// Is the structure in a Fail state?\n    /// </summary>\n    [Pure]\n    public abstract bool IsFail { get; }\n\n    /// <summary>\n    /// Invokes the Succ or Fail function depending on the state of the structure\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Succ\">Function to invoke if in a Succ state</param>\n    /// <param name=\"Fail\">Function to invoke if in a Fail state</param>\n    /// <returns>The return value of the invoked function</returns>\n    [Pure]\n    public abstract B Match<B>(Func<A, B> Succ, Func<Error, B> Fail);\n\n    /// <summary>\n    /// Empty span\n    /// </summary>\n    [Pure]\n    public abstract ReadOnlySpan<Error> FailSpan();\n\n    /// <summary>\n    /// Span of right value\n    /// </summary>\n    [Pure]\n    public abstract ReadOnlySpan<A> SuccSpan();\n\n    /// <summary>\n    /// Compare this structure to another to find its relative ordering\n    /// </summary>\n    [Pure]\n    public abstract int CompareTo<OrdA>(Fin<A> other)\n        where OrdA : Ord<A>;    \n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public abstract bool Equals<EqA>(Fin<A> other)\n        where EqA : Eq<A>;\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(Fin<A>? other) =>\n        other is not null && Equals<EqDefault<A>>(other);\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public override bool Equals(object? other) =>\n        other is Fin<A> f && Equals(f);\n\n    [Pure]\n    public abstract int GetHashCode<HashA>()\n        where HashA : Hashable<A>;\n\n    [Pure]\n    public override int GetHashCode() =>\n        GetHashCode<HashableDefault<A>>();\n\n    /// <summary>\n    /// Unsafe access to the success value \n    /// </summary>\n    internal abstract A SuccValue { get; }\n\n    /// <summary>\n    /// Unsafe access to the fail value \n    /// </summary>\n    internal abstract Error FailValue { get; }\n\n    /// <summary>\n    /// Maps the value in the structure\n    /// </summary>\n    /// <param name=\"f\">Map function</param>\n    /// <returns>Mapped structure</returns>\n    [Pure]\n    public abstract Fin<B> Map<B>(Func<A, B> f);\n\n    /// <summary>\n    /// Maps the value in the structure\n    /// </summary>\n    /// <param name=\"f\">Map function</param>\n    /// <returns>Mapped structure</returns>\n    [Pure]\n    public abstract Fin<A> MapFail(Func<Error, Error> f);\n\n    /// <summary>\n    /// Bi-maps the structure\n    /// </summary>\n    /// <returns>Mapped Either</returns>\n    [Pure]\n    public abstract Fin<B> BiMap<B>(Func<A, B> Succ, Func<Error, Error> Fail);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <typeparam name=\"B\">Resulting bound value</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Bound structure</returns>\n    [Pure]\n    public abstract Fin<B> Bind<B>(Func<A, Fin<B>> f);\n\n    /// <summary>\n    /// Bi-bind.  Allows mapping of both monad states\n    /// </summary>\n    [Pure]\n    public abstract Fin<B> BiBind<B>(Func<A, Fin<B>> Succ, Func<Error, Fin<B>> Fail);\n\n    /// <summary>\n    /// Bind if in a fail state  \n    /// </summary>\n    [Pure]\n    public Fin<A> BindFail(Func<Error, Fin<A>> Fail) =>\n        BiBind(Fin.Succ, Fail);\n\n    /// <summary>\n    /// Monoid empty\n    /// </summary>\n    [Pure]\n    public static Fin<A> Empty { get; } = \n        new Fail(Errors.None);\n    \n    /// <summary>\n    /// Must exist here to make `operator true` work\n    /// </summary>\n    public static Fin<A> operator |(Fin<A> lhs, Fin<A> rhs) =>\n        lhs.Choose(rhs).As();\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Fin<A>(A value) =>\n        new Succ(value);\n        \n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Fin<A>(Error error) =>\n        new Fail(error);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Fin<A>(Either<Error, A> either) =>\n        either switch\n        {\n            Either<Error, A>.Right (var r) => new Succ(r),\n            Either<Error, A>.Left (var l)  => new Fail(l),\n            _                              => throw new InvalidCastException()\n        };\n        \n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Fin<A>(Pure<A> value) =>\n        new Succ(value.Value);\n        \n    [Pure, MethodImpl(Opt.Default)]\n    public static implicit operator Fin<A>(Fail<Error> value) =>\n        new Fail(value.Value);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static explicit operator A(Fin<A> ma) =>\n        ma.SuccValue;\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static explicit operator Error(Fin<A> ma) =>\n        ma.FailValue;\n    \n    [Pure, MethodImpl(Opt.Default)]\n    public static bool operator true(Fin<A> ma) =>\n        ma.IsSucc;\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static bool operator false(Fin<A> ma) =>\n        ma.IsFail;\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static bool operator ==(Fin<A> ma, Fin<A> mb) =>\n        ma.Equals(mb);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public static bool operator !=(Fin<A> ma, Fin<A> mb) =>\n        !ma.Equals(mb);\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Fin<A> lhs, A rhs) =>\n        lhs < (Fin<A>)rhs;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Fin<A> lhs, A rhs) =>\n        lhs <= (Fin<A>)rhs;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Fin<A> lhs, A rhs) =>\n        lhs > (Fin<A>)rhs;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Fin<A> lhs, A rhs) =>\n        lhs >= (Fin<A>)rhs;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(A lhs, Fin<A> rhs) =>\n        (Fin<A>)lhs < rhs;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(A lhs, Fin<A> rhs) =>\n        (Fin<A>)lhs <= rhs;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(A lhs, Fin<A>rhs) =>\n        (Fin<A>)lhs > rhs;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(A lhs, Fin<A>  rhs) =>\n        (Fin<A>)lhs >= rhs;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Fin<A> lhs, Fin<A> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Fin<A> lhs, Fin<A> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs > rhs</returns>\n    [Pure]\n    public static bool operator >(Fin<A> lhs, Fin<A> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs >= rhs</returns>\n    [Pure]\n    public static bool operator >=(Fin<A> lhs, Fin<A> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Fin<A> lhs, Error rhs) =>\n        lhs.Equals((Fin<A>)rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Fin<A> lhs, A rhs) =>\n        lhs.Equals((Fin<A>)rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(A lhs, Fin<A> rhs) =>\n        ((Fin<A>)lhs).Equals(rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Error lhs, Fin<A> rhs) =>\n        Fin.Fail<A>(lhs).Equals(rhs);\n\n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Fin<A> lhs, Error rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Error lhs, Fin<A> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Fin<A> lhs, A rhs) =>\n        !(lhs == rhs!);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(A lhs, Fin<A> rhs) =>\n        !(lhs! == rhs);\n\n    [Pure, MethodImpl(Opt.Default)]\n    static Option<T> convert<T>(in object? value)\n    {\n        if (value == null)\n        {\n            return None;\n        }\n\n        try\n        {\n            return (T)Convert.ChangeType(value, typeof(T));\n        }\n        catch\n        {\n            return None;\n        }\n    }\n\n    [Pure, MethodImpl(Opt.Default)]\n    internal Fin<B> Cast<B>() =>\n        Bind(x => convert<B>(x)\n                    .Map(Fin.Succ)\n                    .IfNone(() => Fin.Fail<B>(Error.New($\"Can't cast success value of `{nameof(A)}` to `{nameof(B)}` \"))));\n\n    [Pure, MethodImpl(Opt.Default)]\n    public int CompareTo(Fin<A>? other) =>\n        other is null\n            ? 1\n            : CompareTo<OrdDefault<A>>(other);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public int CompareTo(object? obj) =>\n        obj is Fin<A> t ? CompareTo(t) : 1;\n\n    [MethodImpl(Opt.Default)]\n    public Unit Match(Action<A> Succ, Action<Error> Fail) =>\n        Match(fun(Succ), fun(Fail));\n\n    [Pure, MethodImpl(Opt.Default)]\n    public A IfFail(Func<Error, A> Fail) =>\n        Match(identity, Fail);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public A IfFail(A alternative) =>\n        Match(identity, _ => alternative);\n\n    [MethodImpl(Opt.Default)]\n    public Unit IfFail(Action<Error> Fail) =>\n        Match(_ => { }, Fail);\n\n    [MethodImpl(Opt.Default)]\n    public Unit IfSucc(Action<A> Succ) =>\n        Match(Succ, _ => { });\n\n    [MethodImpl(Opt.Default)]\n    public Unit Iter(Action<A> Succ) =>\n        Match(Succ, _ => { });\n\n    [Pure, MethodImpl(Opt.Default)]\n    public S Fold<S>(S state, Func<S, A, S> f) =>\n        Match(curry(f)(state), _ => state);    \n\n    [Pure, MethodImpl(Opt.Default)]\n    public S BiFold<S>(in S state, Func<S, A, S> Succ, Func<S, Error, S> Fail) =>\n        Match(curry(Succ)(state), curry(Fail)(state));    \n\n    [Pure, MethodImpl(Opt.Default)]\n    public bool Exists(Func<A, bool> f) =>\n        Match(f, _ => false);    \n\n    [Pure, MethodImpl(Opt.Default)]\n    public bool ForAll(Func<A, bool> f) =>\n        Match(f, _ => true);    \n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Fin<B>> Traverse<F, B>(Func<A, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, Fin<B>> TraverseM<M, B>(Func<A, K<M, B>> f) \n        where M : Monad<M> =>\n        M.Map(x => x.As(), Traversable.traverseM(f, this));\n    \n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<B> Bind<B>(Func<A, K<Fin, B>> f) =>\n        Bind(x => f(x).As());\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(x => f(x).Value);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<A> Bind(Func<A, Fail<Error>> f) =>\n        Bind(x => Fail(f(x).Value));\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<C> SelectMany<B, C>(Func<A, Fin<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<C> SelectMany<B, C>(Func<A, K<Fin, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<Unit> SelectMany(Func<A, Fail<Error>> bind, Func<A, Error, Unit> project) =>\n        Map(x => ignore(bind(x)));\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<Unit> SelectMany(Func<A, Guard<Error, Unit>> f) =>\n        Bind(a => f(a).ToFin());\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Fin<C> SelectMany<C>(Func<A, Guard<Error, Unit>> bind, Func<A, Unit, C> project) =>\n        Bind(a => bind(a).ToFin().Map(_ => project(a, default)));    \n    \n    [Pure, MethodImpl(Opt.Default)]\n    public IEnumerable<A> AsEnumerable()\n    {\n        if(IsSucc) yield return SuccValue;\n    }\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Iterable<A> ToIterable() =>\n        Iterable.createRange(AsEnumerable());\n    \n    [Pure, MethodImpl(Opt.Default)]\n    public Lst<A> ToList() =>\n        new(SuccSpan());\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Seq<A> ToSeq() =>\n        new(SuccSpan());\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Arr<A> ToArray() =>\n        new(SuccSpan());\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Option<A> ToOption() =>\n        IsSucc\n            ? Option.Some(SuccValue)\n            : Option<A>.None;\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Either<Error, A> ToEither() =>\n        IsSucc\n            ? Either.Right<Error, A>(SuccValue)\n            : Either.Left<Error, A>(FailValue);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Validation<Error, A> ToValidation() =>\n        IsSucc\n            ? Validation.Success<Error, A>(SuccValue)\n            : Validation.Fail<Error, A>(FailValue);\n\n    [Pure, MethodImpl(Opt.Default)]\n    public Eff<A> ToEff() =>\n        IsSucc\n            ? Eff<A>.Pure(SuccValue)\n            : Eff<A>.Fail(FailValue);\n\n    public A ThrowIfFail()\n    {\n        if (IsFail)\n        {\n            FailValue.Throw();\n        }\n        return SuccValue;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Operators/Fin.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    extension<A, B>(K<Fin, A> self)\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Fin<B> operator >>> (K<Fin, A> ma, K<Fin, B> mb) =>\n            ma.Action(mb).As();\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<B> operator * (K<Fin, Func<A, B>> mf, K<Fin, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<B> operator * (K<Fin, A> ma, K<Fin, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<A, B, C>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, C>> operator * (\n            K<Fin, Func<A, B, C>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, C>> operator * (\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<A, B, C, D>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, D>>> operator * (\n            K<Fin, Func<A, B, C, D>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, D>>> operator * (\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Fin, Func<A, B, C, D, E>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Fin, Func<A, B, C, D, E, F>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Fin, Func<A, B, C, D, E, F, G>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G, H>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Fin, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Fin, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Fin, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Fin, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Fin, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Fin, A> ma,\n            K<Fin, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Operators/Fin.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    extension<A>(Fin<A> self)\n    {\n        public static Fin<A> operator |(Fin<A> lhs, Fin<A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static Fin<A> operator |(Fin<A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(rhs.ToFin());\n    }\n    \n    extension<A>(K<Fin, A> self)\n    {\n        public static Fin<A> operator |(K<Fin, A> lhs, K<Fin, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static Fin<A> operator |(K<Fin, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(rhs.ToFin());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Operators/Fin.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    extension<A>(Fin<A> self)\n    {\n        public static Fin<A> operator |(Fin<A> lhs, CatchM<Error, Fin, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Fin<A> operator |(Fin<A> lhs, Fail<Error> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Fin<A> operator |(Fin<A> lhs, Error rhs) =>\n            +lhs.Catch(rhs);\n    }    \n    \n    extension<A>(K<Fin, A> self)\n    {\n        public static Fin<A> operator |(K<Fin, A> lhs, CatchM<Error, Fin, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Fin<A> operator |(K<Fin, A> lhs, Fail<Error> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Fin<A> operator |(K<Fin, A> lhs, Error rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Operators/Fin.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    extension<A, B>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<B> operator *(Func<A, B> f, K<Fin, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<B> operator *(K<Fin, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<A, B, C>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, C>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<A, B, C, D>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, D>>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Fin, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Fin<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Fin, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Operators/Fin.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    extension<A, B>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Fin<B> operator >> (K<Fin, A> ma, Func<A, K<Fin, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Fin<B> operator >> (K<Fin, A> lhs, K<Fin, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<A>(K<Fin, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Fin<A> operator >> (K<Fin, A> lhs, K<Fin, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Operators/Fin.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    extension<A>(K<Fin, A> _) \n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Fin<A> operator +(K<Fin, A> lhs, K<Fin, A> rhs) =>\n            +lhs.Combine(rhs);\n        \n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Fin<A> operator +(K<Fin, A> lhs, Pure<A> rhs) =>\n            +lhs.Combine(rhs.ToFin());\n        \n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Fin<A> operator +(K<Fin, A> lhs, Fail<Error> rhs) =>\n            +lhs.Combine(Fin.Fail<A>(rhs.Value));\n        \n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Fin<A> operator +(K<Fin, A> lhs, Error rhs) =>\n            +lhs.Combine(Fin.Fail<A>(rhs));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Operators/Fin.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    extension<A>(K<Fin, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Fin<A> operator +(K<Fin, A> ma) =>\n            (Fin<A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Fin<A> operator >> (K<Fin, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/README.md",
    "content": "The `Fin` monad supports either an `Error` or an `A` (success) value.  It is functionally exactly the same as `Either<Error, A>`, it is a \nconvenience type to avoid the generics pain of `Either`.  \n\nTo construct a `Fin`:\n\n    Fin<int> ma = Pure(123);\n    Fin<int> mb = Fail(Error.New(\"Error!\"));\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Fin/Trait/Fin.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Fin : \n    Monad<Fin>, \n    MonoidK<Fin>, \n    Fallible<Fin>,\n    Traversable<Fin>, \n    Alternative<Fin>,\n    Natural<Fin, Either<Error>>,\n    Natural<Fin, Option>,\n    Natural<Fin, Eff>,\n    Natural<Fin, Try>,\n    Natural<Fin, IO>\n{\n    static K<Fin, B> Monad<Fin>.Bind<A, B>(K<Fin, A> ma, Func<A, K<Fin, B>> f) =>\n        ma switch\n        {\n            Fin<A>.Succ (var r) => f(r),\n            Fin<A>.Fail (var l) => Fail<B>(l),\n            _                   => throw new NotSupportedException()\n        };\n\n    static K<Fin, B> Monad<Fin>.Recur<A, B>(A value, Func<A, K<Fin, Next<A, B>>> f)\n    {\n        while (true)\n        {\n            var mr = +f(value);\n            if (mr.IsFail) return Fail<B>(mr.FailValue);\n            var next = (Next<A, B>)mr;\n            if(next.IsDone) return Succ(next.Done);\n            value = next.Loop;\n        }\n    }\n\n    static K<Fin, B> Functor<Fin>.Map<A, B>(Func<A, B> f, K<Fin, A> ma) =>\n        ma switch\n        {\n            Fin<A>.Succ (var r) => Succ(f(r)),\n            Fin<A>.Fail (var l) => Fail<B>(l),\n            _                      => throw new NotSupportedException()\n        };\n\n    static K<Fin, A> Applicative<Fin>.Pure<A>(A value) =>\n        Succ(value);\n\n    static K<Fin, B> Applicative<Fin>.Apply<A, B>(K<Fin, Func<A, B>> mf, K<Fin, A> ma) =>\n        (mf, ma) switch\n        {\n            (Fin<Func<A, B>>.Succ (var f), Fin<A>.Succ (var a))   => Succ(f(a)),\n            (Fin<Func<A, B>>.Fail (var e1), Fin<A>.Fail (var e2)) => Fail<B>(e1 + e2),\n            (Fin<Func<A, B>>.Fail (var e1), _)                    => Fail<B>(e1),\n            (_, Fin<A>.Fail (var e2))                             => Fail<B>(e2),\n            _                                                     => throw new NotSupportedException()\n        };\n\n    static K<Fin, B> Applicative<Fin>.Apply<A, B>(K<Fin, Func<A, B>> mf, Memo<Fin, A> ma) =>\n        (mf, ma.Value) switch\n        {\n            (Fin<Func<A, B>>.Succ (var f), Fin<A>.Succ (var a))   => Succ(f(a)),\n            (Fin<Func<A, B>>.Fail (var e1), Fin<A>.Fail (var e2)) => Fail<B>(e1 + e2),\n            (Fin<Func<A, B>>.Fail (var e1), _)                    => Fail<B>(e1),\n            (_, Fin<A>.Fail (var e2))                             => Fail<B>(e2),\n            _                                                     => throw new NotSupportedException()\n        };\n\n    static S Foldable<Fin>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Fin, A> ta) =>\n        ta switch\n        {\n            Fin<A>.Succ (var r) => predicate((state, r)) ? f(r)(state) : state,\n            _                   => state\n        };\n\n    static S Foldable<Fin>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S state,\n        K<Fin, A> ta) =>\n        ta switch\n        {\n            Fin<A>.Succ (var r) => predicate((state, r)) ? f(state)(r) : state,\n            _                   => state\n        };\n\n    static K<F, K<Fin, B>> Traversable<Fin>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Fin, A> ta) =>\n        ta switch\n        {\n            Fin<A>.Succ (var r) => F.Map(ConsSucc, f(r)),\n            Fin<A>.Fail (var l) => F.Pure(ConsFail<B>(l)),\n            _                   => throw new NotSupportedException()\n        };        \n\n    static K<Fin, A> MonoidK<Fin>.Empty<A>() =>\n        Fail<A>(Errors.None);\n\n    static K<Fin, A> Alternative<Fin>.Empty<A>() =>\n        Fail<A>(Errors.None);\n\n    static K<Fin, A> SemigroupK<Fin>.Combine<A>(K<Fin, A> ma, K<Fin, A> mb) =>\n        ma switch\n        {\n            Fin<A>.Succ => ma,\n            Fin<A>.Fail (var e1) => mb switch\n                                    {\n                                        Fin<A>.Succ          => mb,\n                                        Fin<A>.Fail (var e2) => Fail<A>(e1 + e2),\n                                        _                    => mb\n                                    },\n            _ => ma\n        };\n\n    static K<Fin, A> Choice<Fin>.Choose<A>(K<Fin, A> ma, K<Fin, A> mb) =>\n        ma switch\n        {\n            Fin<A>.Succ => ma,\n            _           => mb\n        };\n\n    static K<Fin, A> Choice<Fin>.Choose<A>(K<Fin, A> ma, Memo<Fin, A> mb) =>\n        ma switch\n        {\n            Fin<A>.Succ => ma,\n            _           => mb.Value\n        };\n\n    static K<Fin, A> ConsSucc<A>(A value) =>\n        Succ(value);\n\n    static K<Fin, A> ConsFail<A>(Error value) =>\n        Fail<A>(value);\n\n    static K<Fin, A> Fallible<Error, Fin>.Fail<A>(Error error) => \n        Fail<A>(error);\n\n    static K<Fin, A> Fallible<Error, Fin>.Catch<A>(\n        K<Fin, A> fa, Func<Error, bool> Predicate,\n        Func<Error, K<Fin, A>> Fail) =>\n        fa.As().BindFail(e => Predicate(e) ? Fail(e).As() : Fail<A>(e));\n\n    static K<Either<Error>, A> Natural<Fin, Either<Error>>.Transform<A>(K<Fin, A> fa) =>\n        fa switch\n        {\n            Fin<A>.Succ (var x) => Either.Right<Error, A>(x),\n            Fin<A>.Fail (var e) => Either.Left<Error, A>(e),\n            _                   => throw new NotSupportedException()\n        };\n\n    static K<Option, A> Natural<Fin, Option>.Transform<A>(K<Fin, A> fa) =>\n        fa switch\n        {\n            Fin<A>.Succ (var x) => Option.Some(x),\n            Fin<A>.Fail         => Option<A>.None,\n            _                   => throw new NotSupportedException()\n        };\n\n    static K<Try, A> Natural<Fin, Try>.Transform<A>(K<Fin, A> fa) =>\n        fa switch\n        {\n            Fin<A>.Succ (var x) => Try.Succ(x),\n            Fin<A>.Fail (var e) => Try.Fail<A>(e),\n            _                   => throw new NotSupportedException()\n        };\n\n    static K<Eff, A> Natural<Fin, Eff>.Transform<A>(K<Fin, A> fa) =>\n        fa switch\n        {\n            Fin<A>.Succ (var x) => Eff<A>.Pure(x),\n            Fin<A>.Fail (var e) => Eff<A>.Fail(e),\n            _                   => throw new NotSupportedException()\n        };\n\n    static K<IO, A> Natural<Fin, IO>.Transform<A>(K<Fin, A> fa) =>\n        fa switch\n        {\n            Fin<A>.Succ (var x) => IO.pure(x),\n            Fin<A>.Fail (var e) => IO.fail<A>(e),\n            _                   => throw new NotSupportedException()\n        };\n    \n    static Fold<A, S> Foldable<Fin>.FoldStep<A, S>(K<Fin, A> ta, S initialState)\n    {\n        var ma = ta.As();\n        return ma.IsSucc\n                   ? Fold.Loop(initialState, ma.SuccValue, Fold.Done<A, S>)\n                   : Fold.Done<A, S>(initialState);\n    }    \n        \n    static Fold<A, S> Foldable<Fin>.FoldStepBack<A, S>(K<Fin, A> ta, S initialState) =>\n        ta.FoldStep(initialState);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Extensions/FinT.Extensions.Apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static FinT<M, B> Action<M, A, B>(this FinT<M, A> ma, FinT<M, B> mb) \n        where M : Monad<M> =>\n        ma.Kind().Action(mb).As();    \n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static FinT<M, B> Apply<M, A, B>(this FinT<M, Func<A, B>> mf, K<FinT<M>, A> ma) \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static FinT<M, B> Apply<M, A, B>(this K<FinT<M>, Func<A, B>> mf, K<FinT<M>, A> ma)\n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Extensions/FinT.Extensions.Map.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static FinT<M, B> Map<M, A, B>(this Func<A, B> f, K<FinT<M>, A> ma)\n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static FinT<M, B> Map<M, A, B>(this Func<A, B> f, FinT<M, A> ma) \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Extensions/FinT.Extensions.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing NSE = System.NotSupportedException;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    public static FinT<M, A> As<M, A>(this K<FinT<M>, A> ma)\n        where M : Monad<M> =>\n        (FinT<M, A>)ma;\n\n    /// <summary>\n    /// Runs the FinT exposing the outer monad with an inner wrapped `Fin`\n    /// </summary>\n    public static K<M, Fin<A>> Run<M, A>(this K<FinT<M>, A> ma)\n        where M : Monad<M> =>\n        ma.As().runFin;\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, B> Bind<M, A, B>(this K<FinT<M>, A> ma, Func<A, IO<B>> f) \n        where M : MonadIO<M> =>\n        ma.As().Bind(a => FinT.liftIO<M, B>(f(a)));\n    \n    /// <summary>\n    /// Get the outer task and wrap it up in a new IO within the FinT IO\n    /// </summary>\n    public static FinT<IO, A> Flatten<A>(this Task<FinT<IO, A>> tma) =>\n        FinT.lift(IO.liftAsync(async () => await tma.ConfigureAwait(false)))\n            .Flatten();\n\n    /// <summary>\n    /// Lift the task\n    /// </summary>\n    public static FinT<IO, A> ToIO<M, A>(this Task<Fin<A>> ma) \n        where M : Monad<M> =>\n        liftIO(ma);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static FinT<M, A> Flatten<M, A>(this FinT<M, FinT<M, A>> mma)\n        where M : Monad<M> =>\n        mma.Bind(identity);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    [Pure]\n    public static FinT<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<FinT<M>, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        FinT.lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    [Pure]\n    public static FinT<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, FinT<M, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        FinT.lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, C> SelectMany<M, A, B, C>(this K<FinT<M>, A> ma, Func<A, IO<B>> bind, Func<A, B, C> project) \n        where M : MonadIO<M> =>\n        ma.As().SelectMany(x => M.LiftIO(bind(x)), project);\n\n    /// <summary>\n    /// Partitions a foldable of `FinT` into two sequences.\n    /// \n    /// All the `Fail` elements are extracted, in order, to the first component of the output.\n    /// Similarly, the `Succ` elements are extracted to the second component of the output.\n    /// </summary>\n    /// <returns>A pair containing the sequences of partitioned values</returns>\n    [Pure]\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> Partition<F, M, A>(this K<F, FinT<M, A>> self)\n        where F : Foldable<F>\n        where M : Monad<M> =>\n        self.Fold(M.Pure((Fail: Seq<Error>.Empty, Succ: Seq<A>.Empty)),\n                  (ms, ma) =>\n                      ms.Bind(s => ma.Run().Map(a => a switch\n                                                     {\n                                                         Fin<A>.Succ (var r) => (s.Fail, s.Succ.Add(r)),\n                                                         Fin<A>.Fail (var l) => (s.Fail.Add(l), s.Succ),\n                                                         _                   => throw new NSE()\n                                                     })));\n\n    /// <summary>\n    /// Partitions a foldable of `FinT` into two lists and returns the `Fail` items only.\n    /// </summary>\n    /// <returns>A sequence of partitioned items</returns>\n    [Pure]\n    public static K<M, Seq<Error>> Fails<F, M, A>(this K<F, FinT<M, A>> self)\n        where F : Foldable<F>\n        where M : Monad<M> =>\n        self.Fold(M.Pure(Seq<Error>.Empty),\n                  (ms, ma) =>\n                      ms.Bind(s => ma.Run().Map(a => a switch\n                                                     {\n                                                         Fin<A>.Fail(var l) => s.Add(l),\n                                                         _                  => throw new NSE()\n                                                     })));\n\n    /// <summary>\n    /// Partitions a foldable of `FinT` into two lists and returns the `Succ` items only.\n    /// </summary>\n    /// <returns>A sequence of partitioned items</returns>\n    [Pure]\n    public static K<M, Seq<A>> Succs<F, M, A>(this K<F, FinT<M, A>> self)\n        where F : Foldable<F>\n        where M : Monad<M> =>\n        self.Fold(M.Pure(Seq<A>.Empty),\n                  (ms, ma) =>\n                      ms.Bind(s => ma.Run().Map(a => a switch\n                                                     {\n                                                         Fin<A>.Succ (var r) => s.Add(r),\n                                                         _                   => throw new NSE()\n                                                     })));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Extensions/FinT.Guard.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class FinTGuardExtensions\n{\n    /// <summary>\n    /// Natural transformation to `FinT`\n    /// </summary>\n    public static FinT<M, Unit> ToFinT<M>(this Guard<Error, Unit> guard)\n        where M : Monad<M> =>\n        guard.Flag\n            ? FinT.Succ<M, Unit>(default)\n            : FinT.Fail<M, Unit>(guard.OnFalse());\n \n    /// <summary>\n    /// Monadic binding support for `FinT`\n    /// </summary>\n    public static FinT<M, B> Bind<M, B>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, FinT<M, B>> f) \n        where M : Monad<M> =>\n        guard.Flag\n            ? f(default).As()\n            : FinT.Fail<M, B>(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `FinT`\n    /// </summary>\n    public static FinT<M, C> SelectMany<M, B, C>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, FinT<M, B>> bind, \n        Func<Unit, B, C> project) \n        where M : Monad<M> =>\n        guard.Flag\n            ? bind(default).As().Map(b => project(default, b))\n            : FinT.Fail<M, C>(guard.OnFalse());\n\n    /// <summary>\n    /// Monadic binding support for `FinT`\n    /// </summary>\n    public static FinT<M, Unit> SelectMany<M, A>(\n        this FinT<M, A> ma, \n        Func<A, Guard<Error, Unit>> f) \n        where M : Monad<M> =>\n        ma.Bind(a => f(a).ToFinT<M>());\n\n    /// <summary>\n    /// Monadic binding support for `FinT`\n    /// </summary>\n    public static FinT<M, C> SelectMany<M, A, C>(\n        this FinT<M, A> ma, \n        Func<A, Guard<Error, Unit>> bind, \n        Func<A, Unit, C> project) \n        where M : Monad<M> =>\n        ma.Bind(a => bind(a).ToFinT<M>().Map(_ => project(a, default)));    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/FinT.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class FinT\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> Succ<M, A>(A value)  \n        where M : Monad<M> =>  \n        lift(M.Pure(value));\n\n    /// <summary>\n    /// Lift a fail value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> Fail<M, A>(Error value)  \n        where M : Monad<M> =>  \n        lift<M, A>(Fin.Fail<A>(value));\n\n    /// <summary>\n    /// Lifts a given `Fin` value into the transformer \n    /// </summary>\n    /// <param name=\"ma\">`Fin` value</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> lift<M, A>(Fin<A> ma)  \n        where M : Monad<M> =>  \n        new(M.Pure(ma));\n\n    /// <summary>\n    /// Lifts a given pure value into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> lift<M, A>(Pure<A> value)  \n        where M : Monad<M> =>\n        lift<M, A>(Fin.Succ(value.Value));\n\n    /// <summary>\n    /// Lifts a given failure value into the transformer\n    /// </summary>\n    /// <param name=\"fail\">Value to lift</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> lift<M, A>(Fail<Error> value)  \n        where M : Monad<M> =>  \n        lift<M, A>(Fin.Fail<A>(value.Value));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> lift<M, A>(K<M, A> monad) \n        where M : Monad<M> =>  \n        new(M.Map(Fin.Succ, monad));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> lift<M, A>(K<M, Fin<A>> ma) \n        where M : Monad<M> =>  \n        new(ma);\n\n    /// <summary>\n    /// Lifts a given `IO` monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> liftIO<M, A>(IO<A> ma)\n        where M : MonadIO<M> =>  \n        lift(M.LiftIO(ma));\n\n    /// <summary>\n    /// Lifts a given `IO` monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`FinT`</returns>\n    public static FinT<M, A> liftIO<M, A>(IO<Fin<A>> ma)\n        where M : MonadIO<M> =>  \n        lift(M.LiftIO(ma));    \n\n    /// <summary>\n    /// Lifts a given `IO` monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`FinT`</returns>\n    internal static FinT<M, A> liftIOMaybe<M, A>(IO<A> ma)\n        where M : Monad<M> =>  \n        lift(M.LiftIOMaybe(ma));\n\n    /// <summary>\n    /// Lifts a given `IO` monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`FinT`</returns>\n    internal static FinT<M, A> liftIOMaybe<M, A>(IO<Fin<A>> ma)\n        where M : Monad<M> =>  \n        lift(M.LiftIOMaybe(ma));    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/FinT.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `FinT` monad transformer, which allows for either an `Error` or `R` result value to be carried. \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record FinT<M, A>(K<M, Fin<A>> runFin) : \n    K<FinT<M>, A>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Is the `FinT` in a `Succ` state?\n    /// </summary>\n    public K<M, bool> IsSucc =>\n        runFin.Map(f => f.IsSucc);\n\n    /// <summary>\n    /// Is the `FinT` in a `Fail` state?\n    /// </summary>\n    public K<M, bool> IsFail =>\n        runFin.Map(f => f.IsFail);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Match\n    //\n\n    /// <summary>\n    /// Invokes the `Succ` or `Fail` function depending on the state of the `FinT`\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Fail\">Function to invoke if in a Fail state</param>\n    /// <param name=\"Succ\">Function to invoke if in a Succ state</param>\n    /// <returns>The return value of the invoked function</returns>\n    [Pure]\n    public K<M, B> Match<B>(Func<A, B> Succ, Func<Error, B> Fail) =>\n        M.Map(mx => mx.Match(Fail: Fail, Succ: Succ), runFin);\n\n    /// <summary>\n    /// Invokes the `Succ` or `Fail` function depending on the state of the `FinT`\n    /// </summary>\n    /// <param name=\"Succ\">Action to invoke if in a `Succ` state</param>\n    /// <param name=\"Fail\">Action to invoke if in a `Fail` state</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public K<M, Unit> Match(Action<A> Succ, Action<Error> Fail) =>\n        M.Map(mx => mx.Match(Fail: Fail, Succ: Succ), runFin);\n \n    /// <summary>\n    /// Executes the `Fail` function if the `Fin` is in a `Fail` state.\n    /// Returns the `Succ` value if the Fin is in a `Succ` state.\n    /// </summary>\n    /// <param name=\"Fail\">Function to generate a `Succ` value if in the `Fail` state</param>\n    /// <returns>Returns an unwrapped `Succ` value</returns>\n    [Pure]\n    public K<M, A> IfFail(Func<A> Fail) =>\n        IfFail(_ => Fail());\n\n    /// <summary>\n    /// Executes the `f` function if the `Fin` is in a `Fail` state.\n    /// Returns the `Succ` value if the `Fin` is in a `Succ` state.\n    /// </summary>\n    /// <param name=\"f\">Function to generate a `Succ` value if in the `Fail` state</param>\n    /// <returns>Returns an unwrapped `Succ` value</returns>\n    [Pure]\n    public K<M, A> IfFail(Func<Error, A> f) =>\n        Match(Fail: f, Succ: identity);\n\n    /// <summary>\n    /// Returns the `value` if the `Fin` is in a `Fail` state.\n    /// Returns the `Succ` value if the `Fin` is in a `Succ` state.\n    /// </summary>\n    /// <param name=\"value\">Value to return if in the Fail state</param>\n    /// <returns>Returns an unwrapped `Succ` value</returns>\n    [Pure]\n    public K<M, A> IfFail(A value) =>\n        IfFail(_ => value);\n\n    /// <summary>\n    /// Executes the `Fail` action if the `Fin` is in a `Fail` state.\n    /// </summary>\n    /// <param name=\"Fail\">Function to generate a `Succ` value if in the `Fail` state</param>\n    /// <returns>Returns an unwrapped Succ value</returns>\n    public K<M, Unit> IfFail(Action<Error> Fail) =>\n        Match(Fail: Fail, Succ: _ => {});\n\n    /// <summary>\n    /// Invokes the `Succ` action if the `Fin` is in a `Succ` state, otherwise does nothing\n    /// </summary>\n    /// <param name=\"Succ\">Action to invoke</param>\n    /// <returns>Unit</returns>\n    public K<M, Unit> IfSucc(Action<A> Succ) =>\n        Match(Fail: _ => { }, Succ: Succ);\n\n    /// <summary>\n    /// Returns the `fail` value if the `Fin` is in a `Succ` state.\n    /// Returns the `Fail` value if the `Fin` is in a `Fail` state.\n    /// </summary>\n    /// <param name=\"fail\">Value to return if in the `Succ` state</param>\n    /// <returns>Returns an unwrapped `Fail` value</returns>\n    [Pure]\n    public K<M, Error> IfSucc(Error fail) =>\n        Match(Fail: identity, Succ: _ => fail);\n\n    /// <summary>\n    /// Returns the result of `Succ()` if the `Fin` is in a `Succ` state.\n    /// Returns the `Fail` value if the `Fin` is in a `Fail` state.\n    /// </summary>\n    /// <param name=\"Succ\">Function to generate a `Fail` value if in the `Succ` state</param>\n    /// <returns>Returns an unwrapped Fail value</returns>\n    [Pure]\n    public K<M, Error> IfSucc(Func<Error> Succ) =>\n        Match(Fail: identity, Succ: _ => Succ());\n\n    /// <summary>\n    /// Returns the result of `f` if the `Fin` is in a `Succ` state.\n    /// Returns the `Fail` value if the `Fin` is in a `Fail` state.\n    /// </summary>\n    /// <param name=\"f\">Function to generate a `Fail` value if in the `Succ` state</param>\n    /// <returns>Returns an unwrapped Fail value</returns>\n    [Pure]\n    public K<M, Error> IfSucc(Func<A, Error> f) =>\n        Match(Fail: identity, Succ: f);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M1\">Target monad type</typeparam>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Mapped monad</returns>\n    public FinT<M1, B> MapT<M1, B>(Func<K<M, Fin<A>>, K<M1, Fin<B>>> f)\n        where M1 : Monad<M1> =>\n        new (f(runFin));\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    public FinT<M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new(runFin\n               .Bind(fv => fv switch\n                           {\n                               Fin<A>.Succ (var v) => f(M.Pure(v)).Map(Fin.Succ),\n                               Fin<A>.Fail (var e) => M.Pure<Fin<B>>(e),\n                               _                   => throw new NotSupportedException()\n                           }));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, B> Map<B>(Func<A, B> f) =>\n        new(M.Map(mx => mx.Map(f), runFin));\n    \n    /// <summary>\n    /// Maps the `Error` value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, A> MapFail(Func<Error, Error> f) =>\n        new(M.Map(mx => mx.MapFail(f), runFin));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, B> Select<B>(Func<A, B> f) =>\n        new(M.Map(mx => mx.Map(f), runFin));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, B> Bind<B>(Func<A, K<FinT<M>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, B> Bind<B>(Func<A, Fin<B>> f) =>\n        Bind(x => FinT.lift<M, B>(f(x)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, B> Bind<B>(Func<A, FinT<M, B>> f) =>\n        new(M.Bind(runFin, \n                   ex => ex.Match(\n                       Succ: x => f(x).runFin,\n                       Fail: e => M.Pure(Fin.Fail<B>(e)))));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(a => f(a).Value);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, B> Bind<B>(Func<A, Fail<Error>> f) =>\n        Bind(a => FinT.lift<M, B>(f(a).Value));\n\n    /// <summary>\n    /// Monad bi-bind operation\n    /// </summary>\n    /// <param name=\"Fail\">Fail state mapping function</param>\n    /// <param name=\"Succ\">Fail state mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, B> BiBind<B>(Func<Error, FinT<M, B>> Fail, Func<A, FinT<M, B>> Succ) =>\n        new(M.Bind(runFin, \n                   ex => ex.Match(\n                       Succ: x => Succ(x).runFin,\n                       Fail: e => Fail(e).runFin)));\n\n    /// <summary>\n    /// Monad bi-bind operation\n    /// </summary>\n    /// <param name=\"Fail\">Fail state mapping function</param>\n    /// <returns>`FinT`</returns>\n    public FinT<M, A> BindFail(Func<Error, FinT<M, A>> Fail) =>\n        BiBind(Fail, FinT.Succ<M, A>);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, C> SelectMany<B, C>(Func<A, K<FinT<M>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, C> SelectMany<B, C>(Func<A, FinT<M, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => FinT.lift(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, C> SelectMany<B, C>(Func<A, Fin<B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => FinT.lift<M, B>(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`FinT`</returns>\n    public FinT<M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n    \n    public static implicit operator FinT<M, A>(Fin<A> ma) =>\n        FinT.lift<M, A>(ma);\n    \n    public static implicit operator FinT<M, A>(Pure<A> ma) =>\n        FinT.Succ<M, A>(ma.Value);\n    \n    public static implicit operator FinT<M, A>(Fail<Error> ma) =>\n        FinT.lift<M, A>(new Fin<A>.Fail(ma.Value));\n    \n    public static implicit operator FinT<M, A>(Error ma) =>\n        FinT.Fail<M, A>(ma);\n    \n    public static implicit operator FinT<M, A>(IO<A> ma) =>\n        FinT.liftIOMaybe<M, A>(ma);\n    \n    public static implicit operator FinT<M, A>(Lift<A> ma) =>\n        FinT.liftIOMaybe<M, A>(ma);\n    \n    public static implicit operator FinT<M, A>(Lift<EnvIO, A> ma) =>\n        FinT.liftIOMaybe<M, A>(ma);\n    \n    public static implicit operator FinT<M, A>(IO<Fin<A>> ma) =>\n        FinT.liftIOMaybe<M, A>(ma);\n    \n    public OptionT<M, A> ToOption() =>\n        new(runFin.Map(ma => ma.ToOption()));\n\n    public EitherT<Error, M, A> ToEither() =>\n        new(runFin.Map(ma => ma.ToEither()));\n\n    public ValidationT<Error, M, A> ToValidation() =>\n        new(_ => runFin.Map(ma => ma.ToValidation()));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Operators/FinT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    extension<M, A, B>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static FinT<M, B> operator >>> (K<FinT<M>, A> ma, K<FinT<M>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, B> operator * (K<FinT<M>, Func<A, B>> mf, K<FinT<M>, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, B> operator * (K<FinT<M>, A> ma, K<FinT<M>, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<M, A, B, C>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, C>> operator * (\n            K<FinT<M>, Func<A, B, C>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, C>> operator * (\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, D>>> operator * (\n            K<FinT<M>, Func<A, B, C, D>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, D>>> operator * (\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<FinT<M>, Func<A, B, C, D, E>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<FinT<M>, Func<A, B, C, D, E, F>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<FinT<M>, Func<A, B, C, D, E, F, G>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G, H>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<FinT<M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<FinT<M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<FinT<M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<FinT<M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<FinT<M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<FinT<M>, A> ma,\n            K<FinT<M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Operators/FinT.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    extension<M, A>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        public static FinT<M, A> operator |(K<FinT<M>, A> lhs, K<FinT<M>, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static FinT<M, A> operator |(K<FinT<M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(FinT.lift<M, A>(rhs.ToFin()));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Operators/FinT.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    extension<M, A>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        public static FinT<M, A> operator |(K<FinT<M>, A> lhs, CatchM<Error, FinT<M>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static FinT<M, A> operator |(K<FinT<M>, A> lhs, Fail<Error> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static FinT<M, A> operator |(K<FinT<M>, A> lhs, Error rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Operators/FinT.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class FinTExtensions\n{\n    extension<X, M, A>(K<FinT<M>, A> _)\n        where M : Monad<M>, Final<M>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static FinT<M, A> operator |(K<FinT<M>, A> lhs, Finally<M, X> rhs) =>\n            new (lhs.As().runFin.Finally(rhs.Operation));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Operators/FinT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    extension<M, A, B>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, B> operator *(Func<A, B> f, K<FinT<M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, B> operator *(K<FinT<M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<M, A, B, C>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, C>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, D>>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<FinT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static FinT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<FinT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Operators/FinT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    extension<M, A, B>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static FinT<M, B> operator >> (K<FinT<M>, A> ma, Func<A, K<FinT<M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static FinT<M, B> operator >> (K<FinT<M>, A> lhs, K<FinT<M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<M, A, B>(K<FinT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static FinT<M, B> operator >> (K<FinT<M>, A> ma, Func<A, K<IO, B>> f) =>\n            +ma.Bind(x => +f(x));\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static FinT<M, B> operator >> (K<FinT<M>, A> lhs, K<IO, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<M, A>(K<FinT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static FinT<M, A> operator >> (K<FinT<M>, A> lhs, K<FinT<M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n        \n    extension<M, A>(K<FinT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static FinT<M, A> operator >> (K<FinT<M>, A> lhs, K<IO, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Operators/FinT.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\nnamespace LanguageExt;\n\npublic static partial class FinExtensions\n{\n    extension<M, A>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static FinT<M, A> operator +(K<FinT<M>, A> lhs, K<FinT<M>, A> rhs) =>\n            +lhs.Combine(rhs);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static FinT<M, A> operator +(K<FinT<M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Combine(FinT.lift<M, A>(rhs.ToFin()));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static FinT<M, A> operator +(K<FinT<M>, A> lhs, Fail<Error> rhs) =>\n            +lhs.Combine(FinT.Fail<M, A>(rhs.Value));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static FinT<M, A> operator +(K<FinT<M>, A> lhs, Error rhs) =>\n            +lhs.Combine(FinT.Fail<M, A>(rhs));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Operators/FinT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinTExtensions\n{\n    extension<M, A>(K<FinT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static FinT<M, A> operator +(K<FinT<M>, A> ma) =>\n            (FinT<M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static FinT<M, A> operator >> (K<FinT<M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/FinT/Trait/FinT.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `FinT` \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class FinT<M> : \n    MonadT<FinT<M>, M>, \n    Fallible<FinT<M>>,\n    MonoidK<FinT<M>>,\n    Alternative<FinT<M>>,\n    Natural<FinT<M>, EitherT<Error, M>>,\n    Natural<FinT<M>, OptionT<M>>,\n    Natural<FinT<M>, TryT<M>>,\n    MonadIO<FinT<M>>\n    where M : Monad<M>\n{\n    static K<FinT<M>, B> Monad<FinT<M>>.Bind<A, B>(K<FinT<M>, A> ma, Func<A, K<FinT<M>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<FinT<M>, B> Monad<FinT<M>>.Recur<A, B>(A value, Func<A, K<FinT<M>, Next<A, B>>> f) => \n        new FinT<M, B>(\n            M.Recur<A, Fin<B>>(\n                value,\n                a => f(a).As()\n                         .runFin\n                         .Map(e => e switch\n                                   {\n                                       Fin<Next<A, B>>.Fail(var err)            => Next.Done<A, Fin<B>>(err), \n                                       Fin<Next<A, B>>.Succ({ IsDone: true } n) => Next.Done<A, Fin<B>>(n.Done), \n                                       Fin<Next<A, B>>.Succ({ IsLoop: true } n) => Next.Loop<A, Fin<B>>(n.Loop),\n                                       _                                        => throw new NotSupportedException()\n                                   })));\n\n    static K<FinT<M>, B> Functor<FinT<M>>.Map<A, B>(Func<A, B> f, K<FinT<M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<FinT<M>, A> Applicative<FinT<M>>.Pure<A>(A value) => \n        FinT.Succ<M, A>(value);\n\n    static K<FinT<M>, B> Applicative<FinT<M>>.Apply<A, B>(K<FinT<M>, Func<A, B>> mf, K<FinT<M>, A> ma) =>\n        new FinT<M, B>(((Fin<Func<A, B>> ff, Fin<A> fa) => ff.Apply(fa)) * mf.As().runFin * ma.As().runFin);\n\n    static K<FinT<M>, B> Applicative<FinT<M>>.Apply<A, B>(K<FinT<M>, Func<A, B>> mf, Memo<FinT<M>, A> ma) =>\n        new FinT<M, B>(((Fin<Func<A, B>> ff, Fin<A> fa) => ff.Apply(fa)) * mf.As().runFin * ma.Value.As().runFin);\n\n    static K<FinT<M>, A> MonadT<FinT<M>, M>.Lift<A>(K<M, A> ma) => \n        FinT.lift(ma);\n        \n    static K<FinT<M>, A> MonadIO<FinT<M>>.LiftIO<A>(IO<A> ma) => \n        FinT.lift(M.LiftIOMaybe(ma));\n\n    static K<FinT<M>, A> MonoidK<FinT<M>>.Empty<A>() =>\n        FinT.Fail<M, A>(Error.Empty);\n\n    static K<FinT<M>, A> Alternative<FinT<M>>.Empty<A>() =>\n        FinT.Fail<M, A>(Error.Empty);\n\n    static K<FinT<M>, A> SemigroupK<FinT<M>>.Combine<A>(K<FinT<M>, A> ma, K<FinT<M>, A> mb) =>\n        new FinT<M, A>(\n            M.Bind(ma.As().runFin,\n                   ea => ea switch\n                         {\n                             Fin<A>.Succ => M.Pure(ea),\n                             Fin<A>.Fail => mb.As().runFin.Map(fb => ea.Combine(fb).As()),\n                             _           => M.Pure(ea)\n                         }));\n\n    static K<FinT<M>, A> Choice<FinT<M>>.Choose<A>(K<FinT<M>, A> ma, K<FinT<M>, A> mb) =>\n        new FinT<M, A>(\n            M.Bind(ma.As().runFin,\n                   ea => ea switch\n                         {\n                             Fin<A>.Succ => M.Pure(ea),\n                             Fin<A>.Fail => mb.As().runFin,\n                             _           => M.Pure(ea)\n                         }));\n\n    static K<FinT<M>, A> Choice<FinT<M>>.Choose<A>(K<FinT<M>, A> ma, Memo<FinT<M>, A> mb) => \n        new FinT<M, A>(\n            M.Bind(ma.As().runFin,\n                   ea => ea switch\n                         {\n                             Fin<A>.Succ => M.Pure(ea),\n                             Fin<A>.Fail => mb.Value.As().runFin,\n                             _           => M.Pure(ea)\n                         }));\n\n    static K<FinT<M>, A> Fallible<Error, FinT<M>>.Fail<A>(Error error) =>\n        FinT.Fail<M, A>(error);\n\n    static K<FinT<M>, A> Fallible<Error, FinT<M>>.Catch<A>(\n        K<FinT<M>, A> fa, Func<Error, bool> Predicate,\n        Func<Error, K<FinT<M>, A>> Fail) =>\n        fa.As().BindFail(l => Predicate(l) ? Fail(l).As() : FinT.Fail<M, A>(l));\n\n    static K<EitherT<Error, M>, A> Natural<FinT<M>, EitherT<Error, M>>.Transform<A>(K<FinT<M>, A> fa) => \n        new EitherT<Error, M, A>(fa.As().runFin.Map(Natural.transform<Fin, Either<Error>, A>).Map(ma => ma.As()));\n\n    static K<OptionT<M>, A> Natural<FinT<M>, OptionT<M>>.Transform<A>(K<FinT<M>, A> fa) => \n        new OptionT<M, A>(fa.As().runFin.Map(Natural.transform<Fin, Option, A>).Map(ma => ma.As()));\n\n    static K<TryT<M>, A> Natural<FinT<M>, TryT<M>>.Transform<A>(K<FinT<M>, A> fa) => \n        new TryT<M, A>(fa.As().runFin.Map(Natural.transform<Fin, Try, A>).Map(ma => ma.As()));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Nullable/Nullable.Prelude.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Convert NullableT to OptionT\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"self\">Value to convert</param>\n    /// <returns>OptionT with Some or None, depending on HasValue</returns>\n    [Pure]\n    public static Option<T> toOption<T>(T? self) where T : struct =>\n        self.HasValue\n            ? Some(self.Value)\n            : None;\n\n    /// <summary>\n    /// Match the two states of the Nullable and return a non-null R.\n    /// </summary>\n    /// <typeparam name=\"R\">Return type</typeparam>\n    /// <param name=\"Some\">Some handler</param>\n    /// <param name=\"None\">None handler</param>\n    /// <returns>A non-null R</returns>\n    [Pure]\n    public static R match<T, R>(T? self, Func<T, R> Some, Func<R> None) where T : struct =>\n        self.HasValue\n            ? Some(self.Value)\n            : None();\n\n    /// <summary>\n    /// Match the two states of the Nullable and return a promise for an R.\n    /// </summary>\n    /// <typeparam name=\"R\">Return type</typeparam>\n    /// <param name=\"Some\">Some handler</param>\n    /// <param name=\"None\">None handler</param>\n    /// <returns>A promise to return an R</returns>\n    public static async Task<R> matchAsync<T, R>(T? self, Func<T, Task<R>> Some, Func<R> None) where T : struct =>\n        self.HasValue\n            ? await Some(self.Value)\n            : None();\n\n    /// <summary>\n    /// Match the two states of the Nullable and return a promise for an R.\n    /// </summary>\n    /// <typeparam name=\"R\">Return type</typeparam>\n    /// <param name=\"Some\">Some handler</param>\n    /// <param name=\"None\">None handler</param>\n    /// <returns>A promise to return an R</returns>\n    public static async Task<R> matchAsync<T, R>(T? self, Func<T, Task<R>> Some, Func<Task<R>> None) where T : struct =>\n        self.HasValue\n            ? await Some(self.Value)\n            : await None();\n\n    /// <summary>\n    /// Match the two states of the Nullable T\n    /// </summary>\n    /// <param name=\"Some\">Some match</param>\n    /// <param name=\"None\">None match</param>\n    public static Unit match<T>(T? self, Action<T> Some, Action None) where T : struct\n    {\n        if (self.HasValue)\n        {\n            Some(self.Value);\n        }\n        else\n        {\n            None();\n        }\n        return Unit.Default;\n    }\n\n    /// <summary>\n    /// Invokes the someHandler if Nullable is in the Some state, otherwise nothing\n    /// happens.\n    /// </summary>\n    public static Unit ifSome<T>(T? self, Action<T> someHandler) where T : struct\n    {\n        if (self.HasValue)\n        {\n            someHandler(self.Value);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Invokes the someHandler if Nullable is in the Some state, otherwise nothing\n    /// happens.\n    /// </summary>\n    public static Unit ifSome<T>(T? self, Func<T, Unit> someHandler) where T : struct\n    {\n        if (self.HasValue)\n        {\n            someHandler(self.Value);\n        }\n        return unit;\n    }\n\n    [Pure]\n    public static T ifNone<T>(T? self, Func<T> None) where T : struct =>\n        self ?? None();\n\n    [Pure]\n    public static T ifNone<T>(T? self, T noneValue) where T : struct =>\n        self ?? noneValue;\n\n    [Pure]\n    public static Either<L, T> toEither<L, T>(T? self, L defaultLeftValue) where T : struct =>\n        self.HasValue\n            ? Right<L, T>(self.Value)\n            : Left<L, T>(defaultLeftValue);\n\n    [Pure]\n    public static Either<L, T> toEither<L, T>(T? self, Func<L> Left) where T : struct =>\n        self.HasValue\n            ? Right<L, T>(self.Value)\n            : Left<L, T>(Left());\n\n    /// <summary>\n    /// Append the Some(x) of one option to the Some(y) of another.\n    /// For numeric values the behaviour is to sum the Somes (lhs + rhs)\n    /// For string values the behaviour is to concatenate the strings\n    /// For Lst/Stck/Que values the behaviour is to concatenate the lists\n    /// For Map or Set values the behaviour is to merge the sets\n    /// Otherwise if the T type derives from IAppendable then the behaviour\n    /// is to call lhs.Append(rhs);\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs + rhs</returns>\n    [Pure]\n    public static T? append<T>(T? lhs, T? rhs)\n        where T : struct, Semigroup<T>\n    {\n        if (!lhs.HasValue && !rhs.HasValue) return lhs; // None  + None  = None\n        if (!rhs.HasValue) return lhs;                  // Value + None  = Value\n        if (!lhs.HasValue) return rhs;                  // None  + Value = Value\n        return lhs.Value.Combine(rhs.Value);\n    }\n\n    /// <summary>\n    /// Sum the Some(x) of one nullable from the Some(y) of another.\n    /// For numeric values the behaviour is to find the subtract between the Somes (lhs - rhs)\n    /// For Lst values the behaviour is to remove items in the rhs from the lhs\n    /// For Map or Set values the behaviour is to remove items in the rhs from the lhs\n    /// Otherwise if the T type derives from ISubtractable then the behaviour\n    /// is to call lhs.Plus(rhs);\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs - rhs</returns>\n    [Pure]\n    public static T? plus<NUM, T>(T? lhs, T? rhs)\n        where T : struct\n        where NUM : Arithmetic<T>\n    {\n        if (!lhs.HasValue) return rhs;\n        if (!rhs.HasValue) return lhs;\n        return NUM.Add(lhs.Value, rhs.Value);\n    }\n\n    /// <summary>\n    /// Subtract the Some(x) of one nullable from the Some(y) of another.\n    /// For numeric values the behaviour is to find the subtract between the Somes (lhs - rhs)\n    /// For Lst values the behaviour is to remove items in the rhs from the lhs\n    /// For Map or Set values the behaviour is to remove items in the rhs from the lhs\n    /// Otherwise if the T type derives from ISubtractable then the behaviour\n    /// is to call lhs.Subtract(rhs);\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs - rhs</returns>\n    [Pure]\n    public static T? subtract<NUM, T>(T? lhs, T? rhs)\n        where T : struct\n        where NUM : Arithmetic<T>\n    {\n        if (!lhs.HasValue) return rhs;\n        if (!rhs.HasValue) return lhs;\n        return NUM.Subtract(lhs.Value, rhs.Value);\n    }\n\n    /// <summary>\n    /// Find the product of the Somes.\n    /// For numeric values the behaviour is to multiply the Somes (lhs * rhs)\n    /// For Lst values the behaviour is to multiply all combinations of values in both lists \n    /// to produce a new list\n    /// Otherwise if the T type derives from IMultiplicable then the behaviour\n    /// is to call lhs.Product(rhs);\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs * rhs</returns>\n    [Pure]\n    public static T? product<NUM, T>(T? lhs, T? rhs)\n        where T : struct\n        where NUM : Arithmetic<T>\n    {\n        if (!lhs.HasValue) return lhs; // zero * rhs = zero\n        if (!rhs.HasValue) return rhs; // lhs * zero = zero\n        return NUM.Multiply(lhs.Value, rhs.Value);\n    }\n\n    /// <summary>\n    /// Divide the Somes.\n    /// For numeric values the behaviour is to divide the Somes (lhs / rhs)\n    /// For Lst values the behaviour is to divide all combinations of values in both lists \n    /// to produce a new list\n    /// Otherwise if the T type derives from IDivisible then the behaviour\n    /// is to call lhs.Divide(rhs);\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs / rhs</returns>\n    [Pure]\n    public static T? divide<NUM, T>(T? lhs, T? rhs)\n        where T : struct\n        where NUM : Num<T>\n    {\n        if (!lhs.HasValue) return lhs; // zero / rhs  = zero\n        if (!rhs.HasValue) return rhs; // lhs  / zero = undefined: zero\n        return NUM.Divide(lhs.Value, rhs.Value);\n    }\n\n    /// <summary>\n    /// Extracts from a list of 'Option' all the 'Some' elements.\n    /// All the 'Some' elements are extracted in order.\n    /// </summary>\n    [Pure]\n    public static IEnumerable<T> somes<T>(IEnumerable<T?> self) where T : struct\n    {\n        foreach (var item in self)\n        {\n            if (item.HasValue)\n            {\n                yield return item.Value;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Iterate Nullable.  Imagine the item has zero or one items depending on whether\n    /// it's in a None state or not.\n    /// </summary>\n    /// <param name=\"action\">Action to invoke with the value if not in None state</param>\n    public static Unit iter<T>(T? self, Action<T> action) where T : struct\n    {\n        if (self.HasValue) action(self.Value);\n        return default;\n    }\n        \n\n    /// <summary>\n    /// Returns 1 if there is a value, 0 otherwise\n    /// </summary>\n    /// <returns>1 if there is a value, 0 otherwise</returns>\n    [Pure]\n    public static int count<T>(T? self) where T : struct =>\n        self.HasValue\n            ? 1\n            : 0;\n\n    /// <summary>\n    /// ForAll Nullable.  Imagine the item has zero or one items depending on whether\n    /// it's in a None state or not.  This function runs a predicate against the value\n    /// if it exists, returns true if it doesn't (because the predicate holds 'for all'\n    /// items).\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    [Pure]\n    public static bool forall<T>(T? self, Func<T, bool> pred) where T : struct =>\n        !self.HasValue || pred(self.Value);\n\n    /// <summary>\n    /// ForAll Nullable.  Imagine the item has zero or one items depending on whether\n    /// it's in a None state or not.  This function runs a predicate against the value\n    /// if it exists, returns true if it doesn't (because the predicate holds 'for all'\n    /// items).\n    /// </summary>\n    /// <param name=\"Some\">Some predicate</param>\n    /// <param name=\"None\">None predicate</param>\n    [Pure]\n    public static bool forall<T>(T? self, Func<T, bool> Some, Func<bool> None) where T : struct =>\n        self.HasValue\n            ? Some(self.Value)\n            : None();\n\n    /// <summary>\n    /// Exists Nullable.  Imagine the item has zero or one items depending on whether\n    /// it's in a None state or not.  This function runs a predicate against the value\n    /// if it exists, returns false if it doesn't.\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    [Pure]\n    public static bool exists<T>(T? self, Func<T, bool> pred) where T : struct =>\n        self.HasValue && pred(self.Value);\n\n    /// <summary>\n    /// Exists Nullable.  Imagine the item has zero or one items depending on whether\n    /// it's in a None state or not.  This function runs a predicate against the value\n    /// if it exists, returns false if it doesn't.\n    /// </summary>\n    /// <param name=\"Some\">Some predicate</param>\n    /// <param name=\"None\">None predicate</param>\n    [Pure]\n    public static bool exists<T>(T? self, Func<T, bool> Some, Func<bool> None) where T : struct =>\n        self.HasValue\n            ? Some(self.Value)\n            : None();\n\n    [Pure]\n    public static R? map<T, R>(T? self, Func<T, R> mapper)\n        where T : struct\n        where R : struct =>\n        self.HasValue\n            ? mapper(self.Value)\n            : default(R?);\n\n    [Pure]\n    public static R? map<T, R>(T? self, Func<T, R> Some, Func<R> None)\n        where T : struct\n        where R : struct =>\n        self.HasValue\n            ? Some(self.Value)\n            : default(R?);\n\n    [Pure]\n    public static T? filter<T>(T? self, Func<T, bool> pred) where T : struct =>\n        self.HasValue\n            ? pred(self.Value)\n                  ? self\n                  : default\n            : self;\n\n    [Pure]\n    public static T? filter<T>(T? self, Func<T, bool> Some, Func<bool> None) where T : struct =>\n        self.HasValue\n            ? Some(self.Value)\n                  ? self\n                  : default\n            : None()\n                ? self\n                : default;\n\n    [Pure]\n    public static R? bind<T, R>(T? self, Func<T, R?> binder)\n        where T : struct\n        where R : struct =>\n        self.HasValue\n            ? binder(self.Value)\n            : default;\n\n    [Pure]\n    public static R? bind<T, R>(T? self, Func<T, R?> Some, Func<R?> None)\n        where T : struct\n        where R : struct =>\n        self.HasValue\n            ? Some(self.Value)\n            : None();\n\n    [Pure]\n    public static int sum(int? self) =>\n        self ?? 0;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Nullable/README.md",
    "content": "The `Nullable` extensions turns the `Nullable<T>` type from .NET into a monad.  This means you can use them in LINQ expressions, just like\nthe other monadic types in this library.  There are natural transformation functions to help convert from a nullable into other types, i.e.\n\n    int? x = ...\n    Option<int> mx = x.ToOption();"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Extensions/Option.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Option<B> Map<A, B>(this Func<A, B> f, K<Option, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Option<B> Map<A, B>(this Func<A, B> f, Option<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Option<B> Action<A, B>(this Option<A> ma, K<Option, B> mb) =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Option<B> Action<A, B>(this K<Option, A> ma, K<Option, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Option<B> Apply<A, B>(this Option<Func<A, B>> mf, K<Option, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Option<B> Apply<A, B>(this K<Option, Func<A, B>> mf, K<Option, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Extensions/Option.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Trait;\nusing System.Diagnostics.Contracts;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Extension methods for Option\n/// </summary>\npublic static partial class OptionExtensions\n{\n    public static Option<A> As<A>(this K<Option, A> ma) =>\n        (Option<A>)ma;\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Validation<F, A> ToValidation<F, A>(Option<A> ma, F defaultFailureValue)\n        where F : Monoid<F>\n        => ma.IsSome\n               ? Validation.Success<F, A>(ma.Value!)\n               : Validation.Fail<F, A>(defaultFailureValue);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Flatten<A>(this Option<Option<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Extracts from a list of `Option` all the `Some` elements.\n    /// All the `Some` elements are extracted in order.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IEnumerable<A> Somes<A>(this IEnumerable<Option<A>> self)\n    {\n        foreach (var item in self)\n        {\n            if (item.IsSome)\n            {\n                yield return item.Value!;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Extracts from a list of `Option` all the `Some` elements.\n    /// All the `Some` elements are extracted in order.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Seq<A> Somes<A>(this Seq<Option<A>> self)\n    {\n        IEnumerable<A> ToSequence(Seq<Option<A>> items)\n        {\n            foreach (var item in items)\n            {\n                if (item.IsSome)\n                {\n                    yield return item.Value!;\n                }\n            }\n        }\n        return toSeq(ToSequence(self));\n    }\n\n    /// <summary>\n    /// Add the bound values of x and y, uses an Add trait to provide the add\n    /// operation for type A.  For example x.Add〈TInteger, int〉(y)\n    /// </summary>\n    /// <typeparam name=\"ADD\">Add of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"x\">Left hand side of the operation</param>\n    /// <param name=\"y\">Right hand side of the operation</param>\n    /// <returns>An option with y added to x</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Add<ARITH, A>(this Option<A> x, Option<A> y) where ARITH : Arithmetic<A> =>\n        from a in x\n        from b in y\n        select plus<ARITH, A>(a, b);\n\n    /// <summary>\n    /// Find the difference between the two bound values of x and y, uses a Subtract trait\n    /// to provide the subtract operation for type A.  For example x.Subtract〈TInteger, int〉(y)\n    /// </summary>\n    /// <typeparam name=\"DIFF\">Subtract of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"x\">Left hand side of the operation</param>\n    /// <param name=\"y\">Right hand side of the operation</param>\n    /// <returns>An option with the difference between x and y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Subtract<ARITH, A>(this Option<A> x, Option<A> y) where ARITH : Arithmetic<A> =>\n        from a in x\n        from b in y\n        select subtract<ARITH, A>(a, b);\n\n    /// <summary>\n    /// Find the product between the two bound values of x and y, uses a Product trait\n    /// to provide the product operation for type A.  For example x.Product〈TInteger, int〉(y)\n    /// </summary>\n    /// <typeparam name=\"PROD\">Product of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"x\">Left hand side of the operation</param>\n    /// <param name=\"y\">Right hand side of the operation</param>\n    /// <returns>An option with the product of x and y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Product<ARITH, A>(this Option<A> x, Option<A> y) where ARITH : Arithmetic<A> =>\n        from a in x\n        from b in y\n        select product<ARITH, A>(a, b);\n\n    /// <summary>\n    /// Divide the two bound values of x and y, uses a Divide trait to provide the divide\n    /// operation for type A.  For example x.Divide〈TDouble, double〉(y)\n    /// </summary>\n    /// <typeparam name=\"DIV\">Divide of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"x\">Left hand side of the operation</param>\n    /// <param name=\"y\">Right hand side of the operation</param>\n    /// <returns>An option x / y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Divide<NUM, A>(this Option<A> x, Option<A> y) where NUM : Num<A> =>\n        from a in x\n        from b in y\n        select divide<NUM, A>(a, b);\n\n    /// <summary>\n    /// Convert the Option type to a Nullable of A\n    /// </summary>\n    /// <typeparam name=\"A\">Type of the bound value</typeparam>\n    /// <param name=\"ma\">Option to convert</param>\n    /// <returns>Nullable of A</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static A? ToNullable<A>(this Option<A> ma) where A : struct =>\n        ma.IsNone\n            ? null\n            : ma.Value;\n\n    /// <summary>\n    /// Match for an optional boolean\n    /// </summary>\n    /// <param name=\"ma\">Optional boolean</param>\n    /// <param name=\"True\">Match for Some(true)</param>\n    /// <param name=\"False\">Match for Some(false)</param>\n    /// <param name=\"None\">Match for None</param>\n    /// <typeparam name=\"R\"></typeparam>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static R Match<R>(this Option<bool> ma, Func<R> True, Func<R> False, Func<R> None) =>\n        ma.Match(Some: x => x ? True() : False(), None: None());\n\n    /// <summary>\n    /// Match over a list of options\n    /// </summary>\n    /// <typeparam name=\"T\">Type of the bound values</typeparam>\n    /// <typeparam name=\"R\">Result type</typeparam>\n    /// <param name=\"list\">List of options to match against</param>\n    /// <param name=\"Some\">Operation to perform when an Option is in the Some state</param>\n    /// <param name=\"None\">Operation to perform when an Option is in the None state</param>\n    /// <returns>An enumerable of results of the match operations</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IEnumerable<R> Match<T, R>(this IEnumerable<Option<T>> list,\n        Func<T, IEnumerable<R>> Some,\n        Func<IEnumerable<R>> None) =>\n        match(list, Some, None);\n\n    /// <summary>\n    /// Match over a list of options\n    /// </summary>\n    /// <typeparam name=\"T\">Type of the bound values</typeparam>\n    /// <typeparam name=\"R\">Result type</typeparam>\n    /// <param name=\"list\">List of options to match against</param>\n    /// <param name=\"Some\">Operation to perform when an Option is in the Some state</param>\n    /// <param name=\"None\">Default if the list is empty</param>\n    /// <returns>An enumerable of results of the match operations</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IEnumerable<R> Match<T, R>(this IEnumerable<Option<T>> list,\n        Func<T, IEnumerable<R>> Some,\n        IEnumerable<R> None) =>\n        match(list, Some, () => None);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Operators/Option.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class OptionExtensions\n{\n    extension<A, B>(K<Option, A> self)\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Option<B> operator >>> (K<Option, A> ma, K<Option, B> mb) =>\n            ma.Action(mb).As();\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<B> operator * (K<Option, Func<A, B>> mf, K<Option, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<B> operator * (K<Option, A> ma, K<Option, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<A, B, C>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, C>> operator * (\n            K<Option, Func<A, B, C>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, C>> operator * (\n            K<Option, A> ma,\n            K<Option, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<A, B, C, D>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, D>>> operator * (\n            K<Option, Func<A, B, C, D>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, D>>> operator * (\n            K<Option, A> ma,\n            K<Option, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Option, Func<A, B, C, D, E>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Option, A> ma,\n            K<Option, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Option, Func<A, B, C, D, E, F>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Option, A> ma,\n            K<Option, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Option, Func<A, B, C, D, E, F, G>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Option, A> ma,\n            K<Option, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G, H>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Option, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Option, A> ma,\n            K<Option, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Option, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Option, A> ma,\n            K<Option, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Option, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Option, A> ma,\n            K<Option, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Option, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Option, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Option, A> ma,\n            K<Option, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Operators/Option.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionExtensions\n{\n    extension<A>(Option<A> self)\n    {\n        public static Option<A> operator |(Option<A> lhs, Option<A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static Option<A> operator |(Option<A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(rhs.ToOption());\n    }\n\n    extension<A>(K<Option, A> self)\n    {\n        public static Option<A> operator |(K<Option, A> lhs, K<Option, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static Option<A> operator |(K<Option, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(rhs.ToOption());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Operators/Option.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionExtensions\n{\n    extension<A>(Option<A> self)\n    {\n        public static Option<A> operator |(Option<A> lhs, CatchM<Unit, Option, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Option<A> operator |(Option<A> lhs, Fail<Unit> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Option<A> operator |(Option<A> lhs, Unit rhs) =>\n            +lhs.Catch(rhs);\n    }\n    \n    extension<A>(K<Option, A> self)\n    {\n        public static Option<A> operator |(K<Option, A> lhs, CatchM<Unit, Option, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Option<A> operator |(K<Option, A> lhs, Fail<Unit> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Option<A> operator |(K<Option, A> lhs, Unit rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Operators/Option.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class OptionExtensions\n{\n    extension<A, B>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<B> operator *(Func<A, B> f, K<Option, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<B> operator *(K<Option, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<A, B, C>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, C>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<A, B, C, D>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, D>>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Option, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Option<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Option, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Operators/Option.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionExtensions\n{\n    extension<A, B>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Option<B> operator >> (K<Option, A> ma, Func<A, K<Option, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Option<B> operator >> (K<Option, A> lhs, K<Option, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<A>(K<Option, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Option<A> operator >> (K<Option, A> lhs, K<Option, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Operators/Option.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionExtensions\n{\n    extension<A>(K<Option, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Option<A> operator +(K<Option, A> ma) =>\n            (Option<A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Option<A> operator >> (K<Option, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Option.Module.cs",
    "content": "using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic partial class Option\n{\n    /// <summary>\n    /// None\n    /// </summary>\n    public static readonly Fail<Unit> None = new (default);\n\n    /// <summary>\n    /// Construct an Option of A in a Some state\n    /// </summary>\n    /// <param name=\"value\">Value to bind, must be non-null</param>\n    /// <returns>Option of A</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Some<A>(A value) =>\n        new (value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Option.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\nusing System.Runtime.Serialization;\nusing System.Collections;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Discriminated union type.  Can be in one of two states:\n/// \n///     Some(a)\n///     None\n///     \n/// </summary>\n/// <typeparam name=\"A\">Bound value</typeparam>\n[Serializable]\npublic readonly struct Option<A> :\n    IOptional,\n    IEquatable<Option<A>>,\n    IComparable<Option<A>>,\n    IComparable,\n    ISerializable,\n    K<Option, A>,\n    Monoid<Option<A>>\n{\n    internal readonly A? Value;\n    internal readonly bool isSome;\n\n    /// <summary>\n    /// None\n    /// </summary>\n    public static readonly Option<A> None =\n        default;\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    internal Option(A value)\n    {\n        Value  = value;\n        isSome = true;\n    }\n\n    /// <summary>\n    /// Ctor that facilitates serialisation\n    /// </summary>\n    /// <param name=\"option\">None or Some A.</param>\n    public Option(IEnumerable<A> option)\n    {\n        var first = option.Take(1).ToArray();\n        isSome = first.Length == 1;\n        Value = isSome\n                    ? first[0]\n                    : default;\n    }\n\n    Option(SerializationInfo info, StreamingContext context)\n    {\n        isSome = info.GetValue(\"IsSome\", typeof(bool)) is true;\n        if(isSome)\n        {\n            Value = info.GetValue(\"Value\", typeof(A)) is A x ? x : throw new SerializationException();\n        }\n        else\n        {\n            Value = default;\n        }\n    }\n\n    public void GetObjectData(SerializationInfo info, StreamingContext context)\n    {\n        info.AddValue(\"IsSome\", IsSome);\n        if(IsSome) info.AddValue(\"Value\", Value);\n    }\n\n    /// <summary>\n    /// Reference version of option for use in pattern-matching\n    /// </summary>\n    /// <remarks>\n    ///\n    ///     Some = result is A\n    ///     None = result is null\n    ///\n    /// </remarks>\n    [Pure]\n    public object? Case =>\n        IsSome\n            ? Value\n            : null;\n\n    /// <summary>\n    /// Uses the `EqDefault` instance to do an equality check on the bound value.  \n    /// To use anything other than the default call `oa.Equals〈EqA〉(ob)`\n    /// where `EqA` is an instance derived from `Eq〈A〉`\n    /// </summary>\n    /// <remarks>\n    /// This uses the `EqDefault` instance for comparison of the bound `A` values.  \n    /// The `EqDefault` instance wraps up the .NET `EqualityComparer.Default`\n    /// behaviour.  \n    /// </remarks>\n    /// <param name=\"other\">The `Option` type to compare this type with</param>\n    /// <returns>`True` if `this` and `other` are equal</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals(Option<A> other) =>\n        Equals<EqDefault<A>>(other);\n\n    /// <summary>\n    /// Uses the `EqA` instance to do an equality check on the bound value.  \n    /// </summary>\n    /// <param name=\"other\">The `Option` type to compare this type with</param>\n    /// <returns>`True` if `this` and `other` are equal</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Equals<EqA>(Option<A> other) where EqA : Eq<A>\n    {\n        var yIsSome = other.IsSome;\n        var xIsNone = !isSome;\n        var yIsNone = !yIsSome;\n        return xIsNone && yIsNone || isSome && yIsSome && EqA.Equals(Value!, other.Value!);\n    }\n\n    /// <summary>\n    /// Uses the `OrdDefault` instance to do an ordering comparison on the bound \n    /// value.  To use anything other than the default call  `this.Compare〈OrdA〉(this, other)`, \n    /// where `OrdA` is an instance derived  from `Ord〈A〉`\n    /// </summary>\n    /// <param name=\"other\">The `Option` type to compare `this` type with</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo(Option<A> other) =>\n        CompareTo<OrdDefault<A>>(other);\n\n    /// <summary>\n    /// Uses the `Ord` instance provided to do an ordering comparison on the bound \n    /// value.  \n    /// </summary>\n    /// <param name=\"other\">The `Option` type to compare `this` type with</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int CompareTo<OrdA>(Option<A> other) where OrdA : Ord<A>\n    {\n        var yIsSome = other.IsSome;\n        var xIsNone = !isSome;\n        var yIsNone = !yIsSome;\n\n        if (xIsNone && yIsNone) return 0;\n        if (isSome  && yIsNone) return 1;\n        if (xIsNone) return -1;\n\n        return OrdA.Compare(Value!, other.Value!);\n    }\n    \n    /// <summary>\n    /// Must exist here to make `operator true` work\n    /// </summary>\n    public static Option<A> operator |(Option<A> lhs, Option<A> rhs) =>\n        lhs.Choose(rhs).As();\n\n    /// <summary>\n    /// Explicit conversion operator from `Option〈A〉` to `A`\n    /// </summary>\n    /// <param name=\"a\">None value</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static explicit operator A(Option<A> ma)\n    {\n        var opExplicit = ma.IsSome\n                             ? ma.Value\n                             : throw new InvalidCastException(\"Option is not in a Some state\");\n        \n        return opExplicit!;\n    }\n\n    /// <summary>\n    /// Implicit conversion operator from A to Option〈A〉\n    /// </summary>\n    /// <param name=\"a\">Unit value</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Option<A>(A? a) =>\n        Optional(a);\n\n    /// <summary>\n    /// Implicit conversion operator from None to Option〈A〉\n    /// </summary>\n    /// <param name=\"a\">None value</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Option<A>(Fail<Unit> a) =>\n        default;\n\n    /// <summary>\n    /// Implicit conversion operator from None to Option〈A〉\n    /// </summary>\n    /// <param name=\"a\">None value</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static implicit operator Option<A>(in Unit fail) => \n        default;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <(Option<A> lhs, Option<A> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator <=(Option<A> lhs, Option<A> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >(Option<A> lhs, Option<A> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left hand side of the operation</param>\n    /// <param name=\"rhs\">The right hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator >=(Option<A> lhs, Option<A> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Equality operator\n    /// </summary>\n    /// <remarks>\n    /// This uses the EqDefault instance for comparison of the bound A values.  \n    /// The EqDefault instance wraps up the .NET EqualityComparer.Default \n    /// behaviour.  For more control over equality you can call:\n    /// \n    ///     equals〈EQ, A〉(lhs, rhs);\n    ///     \n    /// Where EQ is a struct derived from Eq〈A〉.  For example: \n    /// \n    ///     equals〈EqString, string〉(lhs, rhs);\n    ///     equals〈EqArray〈int〉, int[]〉(lhs, rhs);\n    ///     \n    /// </remarks>\n    /// <param name=\"lhs\">Left hand side of the operation</param>\n    /// <param name=\"rhs\">Right hand side of the operation</param>\n    /// <returns>True if the values are equal</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator ==(Option<A> lhs, Option<A> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Non-equality operator\n    /// </summary>\n    /// <remarks>\n    /// This uses the EqDefault instance for comparison of the A value.  \n    /// The EqDefault trait wraps up the .NET EqualityComparer.Default \n    /// behaviour.  For more control over equality you can call:\n    /// \n    ///     !equals〈EQ, A〉(lhs, rhs);\n    ///     \n    /// Where EQ is a struct derived from Eq〈A〉.  For example: \n    /// \n    ///     !equals〈EqString, string〉(lhs, rhs);\n    ///     !equals〈EqArray〈int〉, int[]〉(lhs, rhs);\n    ///     \n    /// </remarks>\n    /// <param name=\"lhs\">Left hand side of the operation</param>\n    /// <param name=\"rhs\">Right hand side of the operation</param>\n    /// <returns>True if the values are equal</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator !=(Option<A> lhs, Option<A> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Truth operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator true(Option<A> value) =>\n        value.IsSome;\n\n    /// <summary>\n    /// Falsity operator\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool operator false(Option<A> value) =>\n        value.IsNone;\n\n    /// <summary>\n    /// DO NOT USE - Use the Structural equality variant of this method Equals〈EQ, A〉(y)\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override bool Equals(object? obj) =>\n        obj is Option<A> opt && Equals(opt);\n\n    /// <summary>\n    /// Calculate the hash-code from the bound value, unless the Option is in a None\n    /// state, in which case the hash-code will be 0\n    /// </summary>\n    /// <returns>Hash-code from the bound value, unless the Option is in a None\n    /// state, in which case the hash-code will be 0</returns>\n    [Pure]\n    public override int GetHashCode() =>\n        isSome \n            ? Value?.GetHashCode() ?? 0 \n            : 0;\n        \n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj is Option<A> t ? CompareTo(t) : 1;\n\n    /// <summary>\n    /// Get a string representation of the Option\n    /// </summary>\n    /// <returns>String representation of the Option</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public override string ToString() =>\n        isSome\n            ? $\"Some({Value?.ToString() ?? \"\"})\"\n            : \"None\";\n\n    /// <summary>\n    /// Is the option in a Some state\n    /// </summary>\n    [Pure]\n    public bool IsSome =>\n        isSome;\n\n    /// <summary>\n    /// Is the option in a None state\n    /// </summary>\n    [Pure]\n    public bool IsNone =>\n        !isSome;\n\n    /// <summary>\n    /// Impure iteration of the bound value in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<A> Do(Action<A> f)\n    {\n        Iter(f);\n        return this;\n    }\n\n    /// <summary>\n    /// Projection from one value to another \n    /// </summary>\n    /// <typeparam name=\"B\">Resulting functor value type</typeparam>\n    /// <param name=\"f\">Projection function</param>\n    /// <returns>Mapped functor</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<B> Select<B>(Func<A, B> f) =>\n        isSome\n            ? Option.Some(f(Value!))\n            : default;\n\n    /// <summary>\n    /// Projection from one value to another \n    /// </summary>\n    /// <typeparam name=\"B\">Resulting functor value type</typeparam>\n    /// <param name=\"f\">Projection function</param>\n    /// <returns>Mapped functor</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<B> Map<B>(Func<A, B> f) =>\n        isSome\n            ? Option.Some(f(Value!))\n            : default;\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Option<B>> Traverse<F, B>(Func<A, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, Option<B>> TraverseM<M, B>(Func<A, K<M, B>> f) \n        where M : Monad<M> =>\n        M.Map(x => x.As(), Traversable.traverseM(f, this));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<B> Bind<B>(Func<A, Option<B>> f) =>\n        isSome\n            ? f(Value!)\n            : default;\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<B> Bind<B>(Func<A, K<Option, B>> f) =>\n        isSome\n            ? f(Value!).As()\n            : default;\n\n    /// <summary>\n    /// Bi-bind.  Allows mapping of both monad states\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<B> BiBind<B>(Func<A, Option<B>> Some, Func<Option<B>> None) =>\n        isSome\n            ? Some(Value!)\n            : None();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<C> SelectMany<B, C>(\n        Func<A, Option<B>> bind,\n        Func<A, B, C> project)\n    {\n        if (IsNone) return default;\n        var mb = bind(Value!);\n        if (mb.IsNone) return default;\n        return project(Value!, mb.Value!);\n    }\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<C> SelectMany<C>(\n        Func<A, Fail<Unit>> bind,\n        Func<A, Unit, C> project) =>\n        Option<C>.None;\n\n    /// <summary>\n    /// Match operation with an untyped value for Some. This can be\n    /// useful for serialisation and dealing with the IOptional interface\n    /// </summary>\n    /// <typeparam name=\"R\">The return type</typeparam>\n    /// <param name=\"Some\">Operation to perform if the option is in a Some state</param>\n    /// <param name=\"None\">Operation to perform if the option is in a None state</param>\n    /// <returns>The result of the match operation</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public R MatchUntyped<R>(Func<object?, R> Some, Func<R> None) =>\n        IsSome\n            ? Some(Value)\n            : None();    \n\n    /// <summary>\n    /// Get the Type of the bound value\n    /// </summary>\n    /// <returns>Type of the bound value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Type GetUnderlyingType() => \n        typeof(A);\n\n    /// <summary>\n    /// If the Option is in a `Some` state then the span will contain one itemm otherwise empty.\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> ToSpan() =>\n        IsSome\n            ? new([Value!])\n            : ReadOnlySpan<A>.Empty;\n    \n    /// <summary>\n    /// Convert the Option to an enumerable of zero or one items\n    /// </summary>\n    /// <returns>An enumerable of zero or one items</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Arr<A> ToArray() =>\n        isSome\n            ? Arr.create(Value!)\n            : [];\n\n    /// <summary>\n    /// Convert the Option to an immutable list of zero or one items\n    /// </summary>\n    /// <returns>An immutable list of zero or one items</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Lst<A> ToList() =>\n        isSome\n            ? List.create(Value!)\n            : [];\n\n    /// <summary>\n    /// Convert the Option to an enumerable sequence of zero or one items\n    /// </summary>\n    /// <returns>An enumerable sequence of zero or one items</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Seq<A> ToSeq() =>\n        isSome\n            ? [Value!]\n            : [];\n\n    /// <summary>\n    /// Convert the `Option` to an enumerable of zero or one items\n    /// </summary>\n    /// <returns>An enumerable of zero or one items</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public IEnumerable<A> AsEnumerable() =>\n        IsSome ? [Value!] : [];\n\n    /// <summary>\n    /// Convert the Option to an enumerable of zero or one items\n    /// </summary>\n    /// <returns>An enumerable of zero or one items</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Iterable<A> ToIterable() =>\n        IsSome ? [Value!] : [];\n        \n    /// <summary>\n    /// Convert the structure to an Eff\n    /// </summary>\n    /// <returns>An Eff representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Eff<A> ToEff() =>\n        ToEff(Errors.None);\n\n    /// <summary>\n    /// Convert to an Option transformer with embedded IO\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    public OptionT<IO, A> ToIO() =>\n        OptionT.lift<IO, A>(this);\n\n    /// <summary>\n    /// Convert the structure to an `Eff`\n    /// </summary>\n    /// <param name=\"Fail\">Default value if the structure is in a None state</param>\n    /// <returns>An Eff representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Eff<A> ToEff(Error Fail) =>\n        isSome\n            ? Pure(Value!)\n            : Prelude.Fail(Fail);\n\n    /// <summary>\n    /// Convert the structure to a Fin\n    /// </summary>\n    /// <returns>A Fin representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Fin<A> ToFin() =>\n        ToFin(Errors.None);\n\n    /// <summary>\n    /// Convert the structure to a Fin\n    /// </summary>\n    /// <param name=\"Fail\">Default value if the structure is in a None state</param>\n    /// <returns>A Fin representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Fin<A> ToFin(Error Fail) =>\n        isSome\n            ? Fin.Succ<A>(Value!)\n            : Fin.Fail<A>(Fail);\n\n    /// <summary>\n    /// Convert the structure to an Either\n    /// </summary>\n    /// <param name=\"defaultLeftValue\">Default value if the structure is in a None state</param>\n    /// <returns>An Either representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Either<L, A> ToEither<L>(L defaultLeftValue) =>\n        isSome\n            ? Right<L, A>(Value!)\n            : Left<L, A>(defaultLeftValue);\n\n    /// <summary>\n    /// Convert the structure to an Either\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Either<L, A> ToEither<L>() where L : Monoid<L> =>\n        isSome\n            ? Right<L, A>(Value!)\n            : Left<L, A>(L.Empty);\n    \n    /// <summary>\n    /// Convert the structure to an Either\n    /// </summary>\n    /// <param name=\"Left\">Function to invoke to get a default value if the \n    /// structure is in a None state</param>\n    /// <returns>An Either representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Either<L, A> ToEither<L>(Func<L> Left) =>\n        isSome\n            ? Right<L, A>(Value!)\n            : Left<L, A>(Left());\n    \n    /// <summary>\n    /// Convert the structure to a Validation\n    /// </summary>\n    /// <param name=\"Fail\">Function to invoke to get a default value if the \n    /// structure is in a None state</param>\n    /// <returns>An Validation representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Validation<L, A> ToValidation<L>(Func<L> Fail) where L : Monoid<L> =>\n        isSome\n            ? Success<L, A>(Value!)\n            : Fail<L, A>(Fail());\n    \n    /// <summary>\n    /// Convert the structure to a Validation\n    /// </summary>\n    /// <param name=\"Fail\">Default value if the structure is in a None state</param>\n    /// <returns>An Validation representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Validation<L, A> ToValidation<L>(L Fail) where L : Monoid<L> =>\n        isSome\n            ? Success<L, A>(Value!)\n            : Fail<L, A>(Fail);\n    \n    /// <summary>\n    /// Convert the structure to a Validation\n    /// </summary>\n    /// <returns>An Validation representation of the structure</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Validation<L, A> ToValidation<L>() where L : Monoid<L> =>\n        isSome\n            ? Success<L, A>(Value!)\n            : Fail<L, A>(L.Empty);\n\n    /// <summary>\n    /// Fluent pattern matching.  Provide a Some handler and then follow\n    /// on fluently with .None(...) to complete the matching operation.\n    /// This is for dispatching actions, use Some〈A, B〉(...) to return a value\n    /// from the match operation.\n    /// </summary>\n    /// <param name=\"f\">The `Some(x)` match operation</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public SomeUnitContext<A> Some(Action<A> f) =>\n        new (this, f);\n\n    /// <summary>\n    /// Fluent pattern matching.  Provide a Some handler and then follow\n    /// on fluently with .None(...) to complete the matching operation.\n    /// This is for returning a value from the match operation, to dispatch\n    /// an action instead, use Some〈A〉(...)\n    /// </summary>\n    /// <typeparam name=\"B\">Match operation return value type</typeparam>\n    /// <param name=\"f\">The `Some(x)` match operation</param>\n    /// <returns>The result of the match operation</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public SomeContext<A, B> Some<B>(Func<A, B> f) =>\n        new (this, f);\n\n    /// <summary>\n    /// Match the two states of the Option and return a non-null R.\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Some\">Some match operation. Must not return null.</param>\n    /// <param name=\"None\">None match operation. Must not return null.</param>\n    /// <returns>A non-null B</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(Func<A, B> Some, Func<B> None) =>\n        isSome\n            ? Some(Value!)\n            : None();\n\n    /// <summary>\n    /// Match the two states of the Option and return a non-null R.\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Some\">Some match operation. Must not return null.</param>\n    /// <param name=\"None\">None match operation. Must not return null.</param>\n    /// <returns>A non-null B</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public B Match<B>(Func<A, B> Some, B None) =>\n        isSome\n            ? Some(Value!)\n            : None;\n\n    /// <summary>\n    /// Match the two states of the Option\n    /// </summary>\n    /// <param name=\"Some\">Some match operation</param>\n    /// <param name=\"None\">None match operation</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Match(Action<A> Some, Action None)\n    {\n        if(isSome)\n        {\n            Some(Value!);\n        }\n        else\n        {\n            None();\n        }\n        return default;\n    }\n\n    /// <summary>\n    /// Invokes the action if Option is in the Some state, otherwise nothing happens.\n    /// </summary>\n    /// <param name=\"f\">Action to invoke if Option is in the Some state</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit IfSome(Action<A> f)\n    {\n        if(isSome)\n        {\n            f(Value!);\n        }\n        return default;\n    }\n\n    /// <summary>\n    /// Invokes the f function if Option is in the Some state, otherwise nothing\n    /// happens.\n    /// </summary>\n    /// <param name=\"f\">Function to invoke if Option is in the Some state</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit IfSome(Func<A, Unit> f)\n    {\n        if (isSome)\n        {\n            f(Value!);\n        }\n        return default;\n    }\n\n    /// <summary>\n    /// Returns the result of invoking the None() operation if the optional \n    /// is in a None state, otherwise the bound Some(x) value is returned.\n    /// </summary>\n    /// <remarks>Will not accept a null return value from the None operation</remarks>\n    /// <param name=\"None\">Operation to invoke if the structure is in a None state</param>\n    /// <returns>Result of invoking the None() operation if the optional \n    /// is in a None state, otherwise the bound Some(x) value is returned.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public A IfNone(Func<A> None) =>\n        isSome\n            ? Value!\n            : None();\n\n    /// <summary>\n    /// Invokes the action if Option is in the None state, otherwise nothing happens.\n    /// </summary>\n    /// <param name=\"f\">Action to invoke if Option is in the None state</param>\n    public Unit IfNone(Action None)\n    {\n        if (IsNone) None();\n        return unit;\n    }\n        \n    /// <summary>\n    /// Returns the noneValue if the optional is in a None state, otherwise\n    /// the bound Some(x) value is returned.\n    /// </summary>\n    /// <remarks>Will not accept a null noneValue</remarks>\n    /// <param name=\"noneValue\">Value to return if in a None state</param>\n    /// <returns>noneValue if the optional is in a None state, otherwise\n    /// the bound Some(x) value is returned</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public A IfNone(A noneValue) =>\n        isSome\n            ? Value!\n            : noneValue;\n\n    /// <summary>\n    /// <para>\n    /// Option types are like lists of 0 or 1 items, and therefore follow the \n    /// same rules when folding.\n    /// </para><para>\n    /// In the case of lists, 'Fold', when applied to a binary\n    /// operator, a starting value(typically the left-identity of the operator),\n    /// and a list, reduces the list using the binary operator, from left to\n    /// right:\n    /// </para>\n    /// <para>\n    /// Note that, since the head of the resulting expression is produced by\n    /// an application of the operator to the first element of the list,\n    /// 'Fold' can produce a terminating expression from an infinite list.\n    /// </para>\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folder function, applied if Option is in a Some state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S Fold<S>(S state, Func<S, A, S> folder) =>\n        isSome\n            ? folder(state, Value!)\n            : state;\n\n    /// <summary>\n    /// <para>\n    /// Option types are like lists of 0 or 1 items, and therefore follow the \n    /// same rules when folding.\n    /// </para><para>\n    /// In the case of lists, 'Fold', when applied to a binary\n    /// operator, a starting value(typically the left-identity of the operator),\n    /// and a list, reduces the list using the binary operator, from left to\n    /// right:\n    /// </para>\n    /// <para>\n    /// Note that, since the head of the resulting expression is produced by\n    /// an application of the operator to the first element of the list,\n    /// 'Fold' can produce a terminating expression from an infinite list.\n    /// </para>\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"folder\">Folder function, applied if Option is in a Some state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S FoldBack<S>(S state, Func<S, A, S> folder) =>\n        isSome\n            ? folder(state, Value!)\n            : state;\n\n    /// <summary>\n    /// <para>\n    /// Option types are like lists of 0 or 1 items, and therefore follow the \n    /// same rules when folding.\n    /// </para><para>\n    /// In the case of lists, 'Fold', when applied to a binary\n    /// operator, a starting value(typically the left-identity of the operator),\n    /// and a list, reduces the list using the binary operator, from left to\n    /// right:\n    /// </para>\n    /// <para>\n    /// Note that, since the head of the resulting expression is produced by\n    /// an application of the operator to the first element of the list,\n    /// 'Fold' can produce a terminating expression from an infinite list.\n    /// </para>\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"Some\">Folder function, applied if Option is in a Some state</param>\n    /// <param name=\"None\">Folder function, applied if Option is in a None state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S BiFold<S>(S state, Func<S, A, S> Some, Func<S, Unit, S> None) =>\n        isSome\n            ? Some(state, Value!)\n            : None(state, unit);\n\n    /// <summary>\n    /// <para>\n    /// Option types are like lists of 0 or 1 items, and therefore follow the \n    /// same rules when folding.\n    /// </para><para>\n    /// In the case of lists, 'Fold', when applied to a binary\n    /// operator, a starting value(typically the left-identity of the operator),\n    /// and a list, reduces the list using the binary operator, from left to\n    /// right:\n    /// </para>\n    /// <para>\n    /// Note that, since the head of the resulting expression is produced by\n    /// an application of the operator to the first element of the list,\n    /// 'Fold' can produce a terminating expression from an infinite list.\n    /// </para>\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"Some\">Folder function, applied if Option is in a Some state</param>\n    /// <param name=\"None\">Folder function, applied if Option is in a None state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public S BiFold<S>(S state, Func<S, A, S> Some, Func<S, S> None) =>\n        isSome\n            ? Some(state, Value!)\n            : None(state);\n\n    /// <summary>\n    /// Projection from one value to another\n    /// </summary>\n    /// <typeparam name=\"B\">Resulting functor value type</typeparam>\n    /// <param name=\"Some\">Projection function</param>\n    /// <param name=\"None\">Projection function</param>\n    /// <returns>Mapped functor</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<B> BiMap<B>(Func<A, B> Some, Func<Unit, B> None) =>\n        Check.NullReturn(\n            isSome\n                ? Some(Value!)\n                : None(unit));\n\n    /// <summary>\n    /// Projection from one value to another\n    /// </summary>\n    /// <typeparam name=\"B\">Resulting functor value type</typeparam>\n    /// <param name=\"Some\">Projection function</param>\n    /// <param name=\"None\">Projection function</param>\n    /// <returns>Mapped functor</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<B> BiMap<B>(Func<A, B> Some, Func<B> None) =>\n        isSome\n            ? Some(Value!)\n            : None();\n\n    /// <summary>\n    /// <para>\n    /// Return the number of bound values in this structure:\n    /// </para>\n    /// <para>\n    ///     None = 0\n    /// </para>\n    /// <para>\n    ///     Some = 1\n    /// </para>\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public int Count() =>\n        isSome ? 1 : 0;\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned (because the predicate applies for-all values).\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the predicate supplied.        \n    /// </summary>\n    /// <param name=\"pred\"></param>\n    /// <returns>If the Option is in a None state then True is returned (because \n    /// the predicate applies for-all values).  If the Option is in a Some state\n    /// the value is the result of running applying the bound value to the \n    /// predicate supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool ForAll(Func<A, bool> pred) =>\n        !isSome || pred(Value!);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"Some\">Predicate to apply if in a Some state</param>\n    /// <param name=\"None\">Predicate to apply if in a None state</param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool BiForAll(Func<A, bool> Some, Func<Unit, bool> None) =>\n        isSome\n            ? Some(Value!)\n            : None(unit);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"Some\">Predicate to apply if in a Some state</param>\n    /// <param name=\"None\">Predicate to apply if in a None state</param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool BiForAll(Func<A, bool> Some, Func<bool> None) =>\n        isSome\n            ? Some(Value!)\n            : None();\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then False is returned.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the predicate supplied.        \n    /// </summary>\n    /// <param name=\"pred\"></param>\n    /// <returns>If the Option is in a None state then False is returned. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool Exists(Func<A, bool> pred) =>\n        isSome && pred(Value!);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"pred\"></param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool BiExists(Func<A, bool> Some, Func<Unit, bool> None) =>\n        isSome\n            ? Some(Value!)\n            : None(unit);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"pred\"></param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public bool BiExists(Func<A, bool> Some, Func<bool> None) =>\n        isSome\n            ? Some(Value!)\n            : None();\n\n    /// <summary>\n    /// Invoke an action for the bound value (if in a Some state)\n    /// </summary>\n    /// <param name=\"Some\">Action to invoke</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit Iter(Action<A> Some)\n    {\n        if(isSome)\n        {\n            Some(Value!);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Invoke an action depending on the state of the Option\n    /// </summary>\n    /// <param name=\"Some\">Action to invoke if in a Some state</param>\n    /// <param name=\"None\">Action to invoke if in a None state</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit BiIter(Action<A> Some, Action<Unit> None)\n    {\n        if (isSome)\n        {\n            Some(Value!);\n        }\n        else\n        {\n            None(unit);\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Invoke an action depending on the state of the Option\n    /// </summary>\n    /// <param name=\"Some\">Action to invoke if in a Some state</param>\n    /// <param name=\"None\">Action to invoke if in a None state</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Unit BiIter(Action<A> Some, Action None)\n    {\n        if (isSome)\n        {\n            Some(Value!);\n        }\n        else\n        {\n            None();\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Apply a predicate to the bound value (if in a Some state)\n    /// </summary>\n    /// <param name=\"pred\">Predicate to apply</param>\n    /// <returns>Some(x) if the Option is in a Some state and the predicate\n    /// returns True.  None otherwise.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<A> Filter(Func<A, bool> pred) =>\n        isSome && pred(Value!)\n            ? this\n            : default;\n\n    /// <summary>\n    /// Apply a predicate to the bound value (if in a Some state)\n    /// </summary>\n    /// <param name=\"pred\">Predicate to apply</param>\n    /// <returns>Some(x) if the Option is in a Some state and the predicate\n    /// returns True.  None otherwise.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<A> Where(Func<A, bool> pred) =>\n        isSome && pred(Value!)\n            ? this\n            : default;\n\n    /// <summary>\n    /// Partial application map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<Func<B, C>> ParMap<B, C>(Func<A, B, C> func) =>\n        Map(curry(func));\n\n    /// <summary>\n    /// Partial application map\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public Option<Func<B, Func<C, D>>> ParMap<B, C, D>(Func<A, B, C, D> func) =>\n        Map(curry(func));\n        \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    // `Pure` support\n    //\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    [Pure]\n    public Option<B> Bind<B>(Func<A, Pure<B>> f) =>\n        IsSome  \n            ? f(Value!).ToOption()\n            : Option<B>.None;\n\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    [Pure]\n    public Option<B> Bind<B>(Func<A, Fail<Unit>> f) =>\n        Option<B>.None;\n\n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    [Pure]\n    public Option<C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        IsSome\n            ? Option.Some(project(Value!, bind(Value!).Value))\n            : Option<C>.None;\n\n    [Pure]\n    public static implicit operator Option<A>(Pure<A> mr) =>\n        mr.Value is null ? None : Option.Some(mr.Value);\n\n    /// <summary>\n    /// Semigroup combine\n    /// </summary>\n    /// <param name=\"rhs\">Alternative to return if this is None</param>\n    /// <returns>This if in a Some state, `rhs` otherwise</returns>\n    [Pure]\n    public Option<A> Combine(Option<A> rhs) => \n        IsSome ? this : rhs;\n\n    /// <summary>\n    /// Monoid empty (aka None)\n    /// </summary>\n    [Pure]\n    public static Option<A> Empty =>\n        None;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Prelude/Option.Prelude.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Option<A> flatten<A>(Option<Option<A>> ma) =>\n        ma.Bind(identity);\n\n    /// <summary>\n    /// Subtract the Ts\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs - rhs</returns>\n    [Pure]\n    public static Option<T> subtract<NUM, T>(Option<T> lhs, Option<T> rhs) where NUM : Num<T> =>\n        lhs.Subtract<NUM, T>(rhs);\n\n    /// <summary>\n    /// Find the product of the Ts\n    /// </summary>\n    [Pure]\n    public static Option<T> product<NUM, T>(Option<T> lhs, Option<T> rhs) where NUM : Num<T> =>\n        lhs.Product<NUM, T>(rhs);\n\n    /// <summary>\n    /// Divide the Ts\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs / rhs</returns>\n    [Pure]\n    public static Option<T> divide<NUM, T>(Option<T> lhs, Option<T> rhs) where NUM : Num<T> =>\n        lhs.Divide<NUM, T>(rhs);\n\n    /// <summary>\n    /// Add the Ts\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs / rhs</returns>\n    [Pure]\n    public static Option<T> add<NUM, T>(Option<T> lhs, Option<T> rhs) where NUM : Num<T> =>\n        lhs.Add<NUM, T>(rhs);\n\n    /// <summary>\n    /// Check if Option is in a Some state\n    /// </summary>\n    /// <typeparam name=\"T\">T</typeparam>\n    /// <param name=\"value\">Option</param>\n    /// <returns>True if value is in a Some state</returns>\n    [Pure]\n    public static bool isSome<T>(Option<T> value) =>\n        value.IsSome;\n\n    /// <summary>\n    /// Check if Option is in a None state\n    /// </summary>\n    /// <typeparam name=\"T\">T</typeparam>\n    /// <param name=\"value\">Option</param>\n    /// <returns>True if value is in a None state</returns>\n    [Pure]\n    public static bool isNone<T>(Option<T> value) =>\n        value.IsNone;\n\n    /// <summary>\n    /// 'No value' state of Option T.\n    /// </summary>\n    public static readonly Fail<Unit> None = new (default);\n\n    /// <summary>\n    /// Create a `Some` of `A`\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"value\">Non-null value to be made optional</param>\n    /// <returns>`Option〈A〉` in a `Some` state or throws `ValueIsNullException`\n    /// if `isnull(value)`.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Some<A>(A value) =>\n        Option.Some(value);\n\n    /// <summary>\n    /// Create a `Some` of `A` from a `Nullable〈A〉`\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"value\">Non-null value to be made optional</param>\n    /// <returns>`Option〈A〉` in a `Some` state or throws `ValueIsNullException`\n    /// if `isnull(value)`</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Some<A>(A? value) where A : struct =>\n        value.HasValue\n            ? new Option<A>(value.Value)\n            : throw new ValueIsNullException();\n\n    /// <summary>\n    /// Create an `Option` of `A`\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"value\">Value to be made optional, or `null`</param>\n    /// <returns>If the value is `null` it will be `None` else `Some(value)`</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Optional<A>(A? value) =>\n        value is null\n            ? default\n            : new Option<A>(value);\n\n    /// <summary>\n    /// Create an `Option` of `A`\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"value\">Value to be made optional, or null</param>\n    /// <returns>If the value is `null` it will be `None` else `Some(value)`</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<A> Optional<A>(A? value) where A : struct =>\n        value.HasValue\n            ? new Option<A>(value.Value)\n            : default;\n\n    /// <summary>\n    /// Invokes the action if Option is in the Some state, otherwise nothing happens.\n    /// </summary>\n    /// <param name=\"f\">Action to invoke if Option is in the Some state</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit ifSome<T>(Option<T> option, Action<T> Some) => \n        option.IfSome(Some);\n\n    /// <summary>\n    /// Returns the result of invoking the None() operation if the optional \n    /// is in a None state, otherwise the bound Some(x) value is returned.\n    /// </summary>\n    /// <remarks>Will not accept a null return value from the None operation</remarks>\n    /// <param name=\"None\">Operation to invoke if the structure is in a None state</param>\n    /// <returns>Result of invoking the None() operation if the optional \n    /// is in a None state, otherwise the bound Some(x) value is returned.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static T ifNone<T>(Option<T> option, Func<T> None) =>\n        option.IfNone(None);\n\n    /// <summary>\n    /// Returns the noneValue if the optional is in a None state, otherwise\n    /// the bound Some(x) value is returned.\n    /// </summary>\n    /// <remarks>Will not accept a null noneValue</remarks>\n    /// <param name=\"noneValue\">Value to return if in a None state</param>\n    /// <returns>noneValue if the optional is in a None state, otherwise\n    /// the bound Some(x) value is returned</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static T ifNone<T>(Option<T> option, T noneValue) =>\n        option.IfNone(noneValue);\n\n    /// <summary>\n    /// Match the two states of the Option and return a non-null R.\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Some\">Some match operation. Must not return null.</param>\n    /// <param name=\"None\">None match operation. Must not return null.</param>\n    /// <returns>A non-null B</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static R match<T, R>(Option<T> option, Func<T, R> Some, Func<R> None) =>\n        option.Match(Some, None);\n\n    /// <summary>\n    /// Match the two states of the Option\n    /// </summary>\n    /// <param name=\"Some\">Some match operation</param>\n    /// <param name=\"None\">None match operation</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Unit match<T>(Option<T> option, Action<T> Some, Action None) =>\n        option.Match(Some, None);\n\n    /// <summary>\n    /// <para>\n    /// Option types are like lists of 0 or 1 items, and therefore follow the \n    /// same rules when folding.\n    /// </para><para>\n    /// In the case of lists, 'Fold', when applied to a binary\n    /// operator, a starting value(typically the left-identity of the operator),\n    /// and a list, reduces the list using the binary operator, from left to\n    /// right:\n    /// </para><para>\n    /// Note that, since the head of the resulting expression is produced by\n    /// an application of the operator to the first element of the list,\n    /// 'Fold' can produce a terminating expression from an infinite list.\n    /// </para>\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"Some\">Folder function, applied if Option is in a Some state</param>\n    /// <param name=\"None\">Folder function, applied if Option is in a None state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static S bifold<S, A>(Option<A> option, S state, Func<S, A, S> Some, Func<S, S> None) =>\n        option.BiFold(state, Some, None);\n\n    /// <summary>\n    /// <para>\n    /// Option types are like lists of 0 or 1 items, and therefore follow the \n    /// same rules when folding.\n    /// </para><para>\n    /// In the case of lists, 'Fold', when applied to a binary\n    /// operator, a starting value(typically the left-identity of the operator),\n    /// and a list, reduces the list using the binary operator, from left to\n    /// right:\n    /// </para><para>\n    /// Note that, since the head of the resulting expression is produced by\n    /// an application of the operator to the first element of the list,\n    /// 'Fold' can produce a terminating expression from an infinite list.\n    /// </para>\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"Some\">Folder function, applied if Option is in a Some state</param>\n    /// <param name=\"None\">Folder function, applied if Option is in a None state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static S bifold<S, A>(Option<A> option, S state, Func<S, A, S> Some, Func<S, Unit, S> None) =>\n        option.BiFold(state, Some, None);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned (because the predicate applies for-all values).\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the predicate supplied.        \n    /// </summary>\n    /// <param name=\"pred\">Predicate to apply</param>\n    /// <returns>If the Option is in a None state then True is returned (because \n    /// the predicate applies for-all values).  If the Option is in a Some state\n    /// the value is the result of running applying the bound value to the \n    /// predicate supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool forall<A>(Option<A> option, Func<A, bool> pred) =>\n        option.ForAll(pred);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"Some\">Predicate to apply if in a Some state</param>\n    /// <param name=\"None\">Predicate to apply if in a None state</param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool biforall<A>(Option<A> option, Func<A, bool> Some, Func<Unit, bool> None) =>\n        option.BiForAll(Some, None);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"Some\">Predicate to apply if in a Some state</param>\n    /// <param name=\"None\">Predicate to apply if in a None state</param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool biforall<A>(Option<A> option, Func<A, bool> Some, Func<bool> None) =>\n        option.BiForAll(Some, None);\n\n    /// <summary>\n    /// <para>\n    /// Return the number of bound values in this structure:\n    /// </para>\n    /// <para>\n    ///     None = 0\n    /// </para>\n    /// <para>\n    ///     Some = 1\n    /// </para>\n    /// </summary>\n    /// <returns></returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int count<A>(Option<A> option) =>\n        option.Count();\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"pred\">Predicate to apply</param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool exists<A>(Option<A> option, Func<A, bool> pred) =>\n        option.Exists(pred);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"Some\">Predicate to apply if in a Some state</param>\n    /// <param name=\"None\">Predicate to apply if in a None state</param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool biexists<A>(Option<A> option, Func<A, bool> Some, Func<Unit, bool> None) =>\n        option.BiExists(Some, None);\n\n    /// <summary>\n    /// Apply a predicate to the bound value.  If the Option is in a None state\n    /// then True is returned if invoking None returns True.\n    /// If the Option is in a Some state the value is the result of running \n    /// applying the bound value to the Some predicate supplied.        \n    /// </summary>\n    /// <param name=\"Some\">Predicate to apply if in a Some state</param>\n    /// <param name=\"None\">Predicate to apply if in a None state</param>\n    /// <returns>If the Option is in a None state then True is returned if \n    /// invoking None returns True. If the Option is in a Some state the value \n    /// is the result of running applying the bound value to the Some predicate \n    /// supplied.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool biexists<A>(Option<A> option, Func<A, bool> Some, Func<bool> None) =>\n        option.BiExists(Some, None);\n\n    /// <summary>\n    /// Projection from one value to another \n    /// </summary>\n    /// <typeparam name=\"B\">Resulting functor value type</typeparam>\n    /// <param name=\"f\">Projection function</param>\n    /// <returns>Mapped functor</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<B> map<A, B>(Option<A> option, Func<A, B> f) =>\n        option.Map(f);\n\n    /// <summary>\n    /// Projection from one value to another\n    /// </summary>\n    /// <typeparam name=\"B\">Resulting functor value type</typeparam>\n    /// <param name=\"Some\">Projection function</param>\n    /// <param name=\"None\">Projection function</param>\n    /// <returns>Mapped functor</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<B> bimap<A, B>(Option<A> option, Func<A, B> Some, Func<B> None) =>\n        option.BiMap(Some, None);\n\n    /// <summary>\n    /// Projection from one value to another\n    /// </summary>\n    /// <typeparam name=\"B\">Resulting functor value type</typeparam>\n    /// <param name=\"Some\">Projection function</param>\n    /// <param name=\"None\">Projection function</param>\n    /// <returns>Mapped functor</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<B> bimap<A, B>(Option<A> option, Func<A, B> Some, Func<Unit, B> None) =>\n        option.BiMap(Some, None);\n\n    /// <summary>\n    /// Apply a predicate to the bound value (if in a Some state)\n    /// </summary>\n    /// <param name=\"pred\">Predicate to apply</param>\n    /// <returns>Some(x) if the Option is in a Some state and the predicate\n    /// returns True.  None otherwise.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<T> filter<T>(Option<T> option, Func<T, bool> pred) =>\n        option.Filter(pred);\n\n    /// <summary>\n    /// Monadic bind operation\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Option<R> bind<T, R>(Option<T> option, Func<T, Option<R>> binder) =>\n        option.Bind(binder);\n\n    /// <summary>\n    /// Match the two states of the list of Options\n    /// </summary>\n    /// <param name=\"Some\">Some match operation</param>\n    /// <param name=\"None\">None match operation</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IEnumerable<R> match<T, R>(\n        IEnumerable<Option<T>> list,\n        Func<T, IEnumerable<R>> Some,\n        Func<IEnumerable<R>> None) =>\n        list.Match(\n            None,\n            opt     => match(opt, Some, None),\n            (x, xs) => match(x,   Some, None).ConcatFast(match(xs, Some, None)));\n\n    /// <summary>\n    /// Match the two states of the list of Options\n    /// </summary>\n    /// <param name=\"Some\">Some match operation</param>\n    /// <param name=\"None\">None match operation</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IEnumerable<R> match<T, R>(IEnumerable<Option<T>> list,\n                                             Func<T, IEnumerable<R>> Some,\n                                             IEnumerable<R> None) =>\n        match(list, Some, () => None);\n\n    /// <summary>\n    /// Extracts from a list of 'Option' all the 'Some' elements.\n    /// All the 'Some' elements are extracted in order.\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IEnumerable<T> somes<T>(IEnumerable<Option<T>> list) =>\n        list.Somes();\n\n    /// <summary>\n    /// Convert the Option to an immutable list of zero or one items\n    /// </summary>\n    /// <returns>An immutable list of zero or one items</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Lst<T> toList<T>(Option<T> option) =>\n        option.ToList();\n\n    /// <summary>\n    /// Convert the Option to an enumerable of zero or one items\n    /// </summary>\n    /// <returns>An enumerable of zero or one items</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Arr<T> toArray<T>(Option<T> option) =>\n        option.ToArray();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Prelude/Option.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Option<B> map<A, B>(Func<A, B> f, K<Option, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Option<B> action<A, B>(K<Option, A> ma, K<Option, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Option<B> apply<A, B>(K<Option, Func<A, B>> mf, K<Option, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/README.md",
    "content": "`Option` monads support either an `A` (success) value, or a `None` (no-value) option.  You can think of this as an alternative to using\n`null` to represent a lack of a value.  `null` unfortunately still allows you to `.` into the interface of the decalred type, which means\nthere's a ticking time-bomb in every reference type.  \n\nC# does now have the nullable references feature, which goes some way to removing the need for an optional type, however there's still edge\ncases that mean the reference types are problematic.  It's also useful to build generic types and say this is an `Option<A>` - I don't care\nif it's a value-type or reference-type, it's optional.\n\nAnd finally, there's the automatic checking of `None` values when using `Option<A>` in LINQ expressions, or if you call `Map`.  This makes\nworking with optional values, and the implications for all of the code that works with it, fully declarative. \n\nHere we have two flavours of `Option`:\n\n1. `Option<A>` the default optional monad.  It does not allow `null` in its `Some` case.\n2. `OptionUnsafe<A>` as above, but it does allow `null` in its `Some` case.\n\nYou can construct a `Some` using the constructor functions in the `Prelude`:\n\n    Option<int> ma = Some(123);\n    Option<int> mb = None;\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Shared/IOptional.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic interface IOptional\n{\n    bool IsSome { get; }\n\n    bool IsNone { get; }\n\n    R MatchUntyped<R>(Func<object?, R> Some, Func<R> None);\n\n    Type GetUnderlyingType();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Shared/SomeContext.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Provides a fluent context when calling the Some(Func) method from\n/// a member of the Optional〈A〉 trait.  Must call None(Func) or \n/// None(Value) on this context to complete the matching operation.\n/// </summary>\n/// <typeparam name=\"A\">Bound optional value type</typeparam>\n/// <typeparam name=\"B\">The operation return value type</typeparam>\npublic class SomeContext<A, B>\n{\n    readonly Option<A> option;\n    readonly Func<A, B> someHandler;\n\n    internal SomeContext(Option<A> option, Func<A, B> someHandler)\n    {\n        this.option      = option;\n        this.someHandler = someHandler;\n    }\n\n    /// <summary>\n    /// The None branch of the matching operation\n    /// </summary>\n    /// <param name=\"noneHandler\">None branch operation</param>\n    public B None(Func<B> noneHandler) =>\n        option.Match(someHandler, noneHandler);\n\n    /// <summary>\n    /// The None branch of the matching operation\n    /// </summary>\n    /// <param name=\"noneHandler\">None branch operation</param>\n    public B None(B noneValue) =>\n        option.Match(someHandler, noneValue);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Shared/SomeUnitContext.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Provides a fluent context when calling the `Some(Action)` method from\n/// Optional〈A〉 trait.  Must call `None(Action)` or `None(Value)` on this \n/// context to complete the matching operation.\n/// </summary>\n/// <typeparam name=\"A\">Bound optional value type</typeparam>\npublic class SomeUnitContext<A>\n{\n    readonly Option<A> option;\n    readonly Action<A> someHandler;\n    Action? noneHandler;\n\n    internal SomeUnitContext(Option<A> option, Action<A> someHandler)\n    {\n        this.option      = option;\n        this.someHandler = someHandler;\n    }\n\n    /// <summary>\n    /// The None branch of the matching operation\n    /// </summary>\n    /// <param name=\"noneHandler\">None branch operation</param>\n    public Unit None(Action f)\n    {\n        noneHandler = f;\n        return option.Match(HandleSome, HandleNone);\n    }\n\n    Unit HandleSome(A value)\n    {\n        someHandler(value);\n        return unit;\n    }\n\n    Unit HandleNone()\n    {\n        noneHandler?.Invoke();\n        return unit;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Option/Trait/Option.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Option : \n    Monad<Option>, \n    Fallible<Unit, Option>,\n    Traversable<Option>, \n    Alternative<Option>,\n    Natural<Option, Arr>,\n    Natural<Option, Lst>,\n    Natural<Option, Seq>,\n    Natural<Option, Iterable>,\n    Natural<Option, Eff>,\n    Natural<Option, OptionT<IO>>,\n    Natural<Option, Fin>\n{\n    static K<Option, B> Monad<Option>.Bind<A, B>(K<Option, A> ma, Func<A, K<Option, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<Option, B> Functor<Option>.Map<A, B>(Func<A, B> f, K<Option, A> ma) => \n        ma.As().Map(f);\n\n    static K<Option, A> Applicative<Option>.Pure<A>(A value) =>\n        Some(value);\n\n    static K<Option, B> Applicative<Option>.Apply<A, B>(K<Option, Func<A, B>> mf, K<Option, A> ma) =>\n        mf.As().Bind(f => ma.As().Map(f));\n\n    static K<Option, B> Applicative<Option>.Apply<A, B>(K<Option, Func<A, B>> mf, Memo<Option, A> ma) =>\n        mf.As().Bind(f => ma.Value.As().Map(f));\n\n    static K<Option, B> Monad<Option>.Recur<A, B>(A value, Func<A, K<Option, Next<A, B>>> f)\n    {\n        while (true)\n        {\n            var mr = +f(value);\n            if (mr.IsNone) return Option<B>.None;\n            var mnext = (Next<A, B>)mr;\n            if(mnext.IsDone) return Some(mnext.Done);\n            value = mnext.Loop;\n        }\n    }\n\n    static S Foldable<Option>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState,\n        K<Option, A> ta) =>\n        ta.As().Match(Some: a => predicate((initialState, a)) ? f(a)(initialState) : initialState,\n                      None: initialState);\n\n    static S Foldable<Option>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<Option, A> ta) => \n        ta.As().Match(Some: a => predicate((initialState, a)) ? f(initialState)(a) : initialState,\n                      None: initialState);\n\n    static K<F, K<Option, B>> Traversable<Option>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Option, A> ta) =>\n        ta.As().Match(Some: a => F.Map(Prelude.pure<Option, B>, f(a)),\n                      None: F.Pure(Alternative.empty<Option, B>()));\n\n    static K<Option, A> Alternative<Option>.Empty<A>() =>\n        Option<A>.None;\n\n    static K<Option, A> Choice<Option>.Choose<A>(K<Option, A> ma, K<Option, A> mb) =>\n        ma.As() switch\n        {\n            { IsSome: true } => ma,\n            _                => mb\n        };\n\n    static K<Option, A> Choice<Option>.Choose<A>(K<Option, A> ma, Memo<Option, A> mb) => \n        ma.As() switch\n        {\n            { IsSome: true } => ma,\n            _                => mb.Value\n        };\n\n    public static B Match<A, B>(K<Option, A> fa, Func<A, B> Some, Func<B> None) =>\n        fa.As().Match(Some, None);\n\n    static K<Option, A> Fallible<Unit, Option>.Fail<A>(Unit _) =>\n        Option<A>.None;\n\n    static K<Option, A> Fallible<Unit, Option>.Catch<A>(\n        K<Option, A> fa, \n        Func<Unit, bool> Predicate, \n        Func<Unit, K<Option, A>> Fail) => \n        fa.As().Match(Some: Some, \n                      None: () => Predicate(default) ? Fail(default).As() : Option<A>.None);\n\n    static K<Arr, A> Natural<Option, Arr>.Transform<A>(K<Option, A> fa) => \n        fa.As().ToArr();\n\n    static K<Lst, A> Natural<Option, Lst>.Transform<A>(K<Option, A> fa) => \n        fa.As().ToLst();\n\n    static K<Seq, A> Natural<Option, Seq>.Transform<A>(K<Option, A> fa) => \n        fa.As().ToSeq();\n\n    static K<Iterable, A> Natural<Option, Iterable>.Transform<A>(K<Option, A> fa) => \n        FoldableExtensions.ToIterable(fa.As());\n\n    static K<Eff, A> Natural<Option, Eff>.Transform<A>(K<Option, A> fa) => \n        fa.As().ToEff();\n\n    static K<OptionT<IO>, A> Natural<Option, OptionT<IO>>.Transform<A>(K<Option, A> fa) => \n        fa.As().ToIO();\n\n    static K<Fin, A> Natural<Option, Fin>.Transform<A>(K<Option, A> fa) => \n        fa.As().ToFin();\n    \n    static Fold<A, S> Foldable<Option>.FoldStep<A, S>(K<Option, A> ta, S initialState)\n    {\n        var ma = ta.As();\n        return ma.IsSome\n                   ? Fold.Loop(initialState, ma.Value!, Fold.Done<A, S>)\n                   : Fold.Done<A, S>(initialState);\n    }     \n        \n    static Fold<A, S> Foldable<Option>.FoldStepBack<A, S>(K<Option, A> ta, S initialState) =>\n        ta.FoldStep(initialState);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Extensions/OptionT.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionTExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static OptionT<M, B> Map<M, A, B>(this Func<A, B> f, K<OptionT<M>, A> ma) \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static OptionT<M, B> Map<M, A, B>(this Func<A, B> f, OptionT<M, A> ma)\n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static OptionT<M, B> Action<M, A, B>(this OptionT<M, A> ma, K<OptionT<M>, B> mb)\n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static OptionT<M, B> Action<M, A, B>(this K<OptionT<M>, A> ma, K<OptionT<M>, B> mb)\n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static OptionT<M, B> Apply<M, A, B>(this OptionT<M, Func<A, B>> mf, K<OptionT<M>, A> ma) \n        where M : Monad<M> =>\n        mf.Kind().Apply(ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static OptionT<M, B> Apply<M, A, B>(this K<OptionT<M>, Func<A, B>> mf, K<OptionT<M>, A> ma) \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Extensions/OptionT.Extensions.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// OptionT monad-transformer extensions\n/// </summary>\npublic static partial class OptionTExtensions\n{\n    public static OptionT<M, A> As<M, A>(this K<OptionT<M>, A> ma)\n        where M : Monad<M> =>\n        (OptionT<M, A>)ma;\n\n    public static K<M, Option<A>> Run<M, A>(this K<OptionT<M>, A> ma)\n        where M : Monad<M> =>\n        ((OptionT<M, A>)ma).Run();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, B> Bind<M, A, B>(this K<OptionT<M>, A> ma, Func<A, IO<B>> f) \n        where M : MonadIO<M> =>\n        ma.As().Bind(a => OptionT.liftIO<M, B>(f(a)));\n    \n    /// <summary>\n    /// Get the outer task and wrap it up in a new IO within the OptionT IO\n    /// </summary>\n    public static OptionT<IO, A> Flatten<A>(this Task<OptionT<IO, A>> tma) =>\n        OptionT.lift(IO.liftAsync(async () => await tma.ConfigureAwait(false)))\n               .Flatten();\n\n    /// <summary>\n    /// Lift the task\n    /// </summary>\n    public static OptionT<IO, A> ToIO<A>(this Task<Option<A>> ma) =>\n        liftIO(ma);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static OptionT<M, A> Flatten<M, A>(this OptionT<M, OptionT<M, A>> mma)\n        where M : Monad<M> =>\n        mma.Bind(identity);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    [Pure]\n    public static OptionT<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<OptionT<M>, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        OptionT.lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    [Pure]\n    public static OptionT<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, OptionT<M, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        OptionT.lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, C> SelectMany<M, A, B, C>(\n        this K<OptionT<M>, A> ma, \n        Func<A, IO<B>> bind, \n        Func<A, B, C> project)\n        where M : MonadIO<M> =>\n        ma.As().SelectMany(x => M.LiftIO(bind(x)), project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Operators/OptionT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class OptionTExtensions\n{\n    extension<M, A, B>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static OptionT<M, B> operator >>> (K<OptionT<M>, A> ma, K<OptionT<M>, B> mb) =>\n            ma.Action(mb).As();\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, B> operator * (K<OptionT<M>, Func<A, B>> mf, K<OptionT<M>, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, B> operator * (K<OptionT<M>, A> ma, K<OptionT<M>, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<M, A, B, C>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, C>> operator * (\n            K<OptionT<M>, Func<A, B, C>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, C>> operator * (\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, D>>> operator * (\n            K<OptionT<M>, Func<A, B, C, D>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, D>>> operator * (\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<OptionT<M>, Func<A, B, C, D, E>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<OptionT<M>, Func<A, B, C, D, E, F>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<OptionT<M>, Func<A, B, C, D, E, F, G>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G, H>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<OptionT<M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<OptionT<M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<OptionT<M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<OptionT<M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<OptionT<M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<OptionT<M>, A> ma,\n            K<OptionT<M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Operators/OptionT.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionTExtensions\n{\n    extension<M, A>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        public static OptionT<M, A> operator |(K<OptionT<M>, A> lhs, K<OptionT<M>, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static OptionT<M, A> operator |(K<OptionT<M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(OptionT.lift<M, A>(rhs.ToOption()));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Operators/OptionT.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionTExtensions\n{\n    extension<M, A>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        public static OptionT<M, A> operator |(K<OptionT<M>, A> lhs, CatchM<Unit, OptionT<M>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static OptionT<M, A> operator |(K<OptionT<M>, A> lhs, Fail<Unit> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static OptionT<M, A> operator |(K<OptionT<M>, A> lhs, Unit rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Operators/OptionT.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class OptionTExtensions\n{\n    extension<X, M, A>(K<OptionT<M>, A> _)\n        where M : Monad<M>, Final<M>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static OptionT<M, A> operator |(K<OptionT<M>, A> lhs, Finally<M, X> rhs) =>\n            new (lhs.As().runOption.Finally(rhs.Operation));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Operators/OptionT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class OptionTExtensions\n{\n    extension<M, A, B>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, B> operator *(Func<A, B> f, K<OptionT<M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, B> operator *(K<OptionT<M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<M, A, B, C>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, C>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, D>>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<OptionT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static OptionT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<OptionT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Operators/OptionT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionTExtensions\n{\n    extension<M, A, B>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static OptionT<M, B> operator >> (K<OptionT<M>, A> ma, Func<A, K<OptionT<M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static OptionT<M, B> operator >> (K<OptionT<M>, A> lhs, K<OptionT<M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<M, A>(K<OptionT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static OptionT<M, A> operator >> (K<OptionT<M>, A> lhs, K<OptionT<M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Operators/OptionT.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ChronicleTExtensions\n{\n    extension<M, A>(K<OptionT<M>, A> self)\n        where M : Monad<M>, SemigroupK<M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static OptionT<M, A> operator +(K<OptionT<M>, A> lhs, K<OptionT<M>, A> rhs) =>\n            new (lhs.As().runOption + rhs.As().runOption);\n    }\n\n    extension<M, A>(K<OptionT<M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Applicative<M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static OptionT<M, A> operator +(K<OptionT<M>, A> lhs, Pure<A> rhs) =>\n            new(lhs.As().runOption + M.Pure(rhs.Value).Map(Option.Some));\n    }\n    \n    extension<E, M, A>(K<OptionT<M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Fallible<E, M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static OptionT<M, A> operator +(K<OptionT<M>, A> lhs, Fail<E> rhs) =>\n            new (lhs.As().runOption + M.Fail<Option<A>>(rhs.Value));\n\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Operators/OptionT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class OptionTExtensions\n{\n    extension<M, A>(K<OptionT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static OptionT<M, A> operator +(K<OptionT<M>, A> ma) =>\n            (OptionT<M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static OptionT<M, A> operator >> (K<OptionT<M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/OptionT.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class OptionT\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> Some<M, A>(A value)  \n        where M : Monad<M> =>\n        lift(M.Pure(value));\n\n    /// <summary>\n    /// Lift a `None` value into the monad-transformer   \n    /// </summary>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> None<M, A>()  \n        where M : Monad<M> =>\n        OptionT<M, A>.None;\n    \n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> lift<M, A>(Pure<A> monad) \n        where M : Monad<M> =>\n        Some<M, A>(monad.Value);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> lift<M, A>(Option<A> monad) \n        where M : Monad<M> =>\n        new(M.Pure(monad));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> lift<M, A>(Fail<Unit> monad) \n        where M : Monad<M> =>\n        lift<M, A>(Option<A>.None);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> lift<M, A>(K<M, A> monad) \n        where M : Monad<M> =>\n        new(M.Map(Option.Some, monad));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> lift<M, A>(K<M, Option<A>> monad) \n        where M : Monad<M> =>\n        new(monad);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> liftIO<M, A>(IO<A> monad) \n        where M : MonadIO<M> =>\n        lift(M.LiftIO(monad));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    internal static OptionT<M, A> liftIOMaybe<M, A>(IO<A> monad) \n        where M : Monad<M> =>\n        lift(M.LiftIOMaybe(monad));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static OptionT<M, A> liftIO<M, A>(IO<Option<A>> monad) \n        where M : MonadIO<M> =>\n        lift(M.LiftIO(monad));\n    \n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`OptionT`</returns>\n    internal static OptionT<M, A> liftIOMaybe<M, A>(IO<Option<A>> monad) \n        where M : Monad<M> =>\n        lift(M.LiftIOMaybe(monad));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/OptionT.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.IO;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `OptionT` monad transformer, which allows for an optional result. \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record OptionT<M, A>(K<M, Option<A>> runOption) : \n    K<OptionT<M>, A>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`OptionT`</returns>\n    public static readonly OptionT<M, A> None =\n        OptionT.lift<M, A>(Option<A>.None);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Match\n    //\n\n    /// <summary>\n    /// Match the two states of the Option and return a B, which can be null.\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Some\">Some match operation. May return null.</param>\n    /// <param name=\"None\">None match operation. May return null.</param>\n    /// <returns>B, or null</returns>\n    public K<M, B> Match<B>(Func<A, B> Some, Func<B> None) =>\n        M.Map(mx => mx.Match(Some, None), runOption);\n\n    /// <summary>\n    /// Match the two states of the Option\n    /// </summary>\n    /// <param name=\"Some\">Some match operation</param>\n    /// <param name=\"None\">None match operation</param>\n    public K<M, Unit> Match(Action<A> Some, Action None) =>\n        M.Map(mx => mx.Match(Some, None), runOption);\n\n    /// <summary>\n    /// Invokes the action if Option is in the `Some` state, otherwise nothing happens.\n    /// </summary>\n    /// <param name=\"f\">Action to invoke if Option is in the `Some` state</param>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public K<M, Unit> IfSome(Action<A> f) =>\n        M.Map(mx => mx.IfSome(f), runOption);\n\n    /// <summary>\n    /// Invokes the f function if Option is in the `Some` state, otherwise nothing\n    /// happens.\n    /// </summary>\n    /// <param name=\"f\">Function to invoke if Option is in the `Some` state</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public K<M, Unit> IfSome(Func<A, Unit> f) =>\n        M.Map(mx => mx.IfSome(f), runOption);\n\n    /// <summary>\n    /// Returns the result of invoking the `None()` operation if the optional \n    /// is in a None state, otherwise the bound `Some(x)` value is returned.\n    /// </summary>\n    /// <remarks>Will not accept a null return value from the None operation</remarks>\n    /// <param name=\"None\">Operation to invoke if the structure is in a None state</param>\n    /// <returns>Result of invoking the `None()` operation if the optional \n    /// is in a None state, otherwise the bound `Some(x)` value is returned.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public K<M, A> IfNone(Func<A> None) =>\n        M.Map(mx => mx.IfNone(None), runOption);\n\n    /// <summary>\n    /// Invokes the action if Option is in the None state, otherwise nothing happens.\n    /// </summary>\n    /// <param name=\"f\">Action to invoke if Option is in the None state</param>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public K<M, Unit> IfNone(Action None) =>\n        M.Map(mx => mx.IfNone(None), runOption);\n        \n    /// <summary>\n    /// Returns the noneValue if the optional is in a None state, otherwise\n    /// the bound Some(x) value is returned.\n    /// </summary>\n    /// <remarks>Will not accept a null noneValue</remarks>\n    /// <param name=\"noneValue\">Value to return if in a None state</param>\n    /// <returns>noneValue if the optional is in a None state, otherwise\n    /// the bound Some(x) value is returned</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public K<M, A> IfNone(A noneValue) =>\n        M.Map(mx => mx.IfNone(noneValue), runOption);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Run\n    //\n\n    /// <summary>\n    /// Runs the OptionT exposing the outer monad with an inner wrapped `Option`\n    /// </summary>\n    public K<M, Option<A>> Run() =>\n        runOption;\n \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M1\">Target monad type</typeparam>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Mapped monad</returns>\n    public OptionT<M1, B> MapT<M1, B>(Func<K<M, Option<A>>, K<M1, Option<B>>> f)\n        where M1 : Monad<M1> =>\n        new (f(runOption));\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    public OptionT<M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new(runOption.Bind(\n                fv => fv.Match(Some: v => f(M.Pure(v)).Map(Option.Some),\n                               None: () => M.Pure(Option<B>.None))));\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, B> Map<B>(Func<A, B> f) =>\n        new(M.Map(mx => mx.Map(f), runOption));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, B> Select<B>(Func<A, B> f) =>\n        new(M.Map(mx => mx.Map(f), runOption));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, B> Bind<B>(Func<A, K<OptionT<M>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, B> Bind<B>(Func<A, OptionT<M, B>> f) =>\n        new(M.Bind(runOption, \n                   ox => ox.Match(\n                       Some: x => f(x).runOption,\n                       None: () => M.Pure(Option<B>.None))));\n\n    /// <summary>\n    /// Monad bi-bind operation\n    /// </summary>\n    /// <param name=\"Some\">Some state mapping function</param>\n    /// <param name=\"None\">None state mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, B> BiBind<B>(Func<A, OptionT<M, B>> Some, Func<OptionT<M, B>> None) =>\n        new(M.Bind(runOption, \n                   ox => ox.Match(\n                       Some: x => Some(x).runOption,\n                       None: () => None().runOption)));\n\n    /// <summary>\n    /// Monad bi-bind operation\n    /// </summary>\n    /// <param name=\"None\">None state mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, A> BindNone(Func<OptionT<M, A>> None) =>\n        BiBind(OptionT.Some<M, A>, None);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(a => f(a).Value);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, C> SelectMany<B, C>(Func<A, K<OptionT<M>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, C> SelectMany<B, C>(Func<A, OptionT<M, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => OptionT.lift(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, C> SelectMany<B, C>(Func<A, Option<B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => OptionT.lift<M, B>(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`OptionT`</returns>\n    public OptionT<M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n    \n    public static implicit operator OptionT<M, A>(in Option<A> ma) =>\n        OptionT.lift<M, A>(ma);\n    \n    public static implicit operator OptionT<M, A>(Pure<A> ma) =>\n        Some(ma.Value);\n    \n    public static implicit operator OptionT<M, A>(Fail<Unit> ma) =>\n        OptionT.lift<M, A>(Option<A>.None);\n\n    public static implicit operator OptionT<M, A>(in Unit fail) => \n        OptionT.lift<M, A>(Option<A>.None);\n\n    public static implicit operator OptionT<M, A>(IO<A> ma) =>\n        OptionT.liftIOMaybe<M, A>(ma);\n    \n    public static implicit operator OptionT<M, A>(Lift<A> ma) =>\n        OptionT.liftIOMaybe<M, A>(ma);\n    \n    public static implicit operator OptionT<M, A>(Lift<EnvIO, A> ma) =>\n        OptionT.liftIOMaybe<M, A>(ma);\n    \n    public static implicit operator OptionT<M, A>(IO<Option<A>> ma) =>\n        OptionT.liftIOMaybe<M, A>(ma);\n\n    public EitherT<L, M, A> ToEither<L>(L left) =>\n        new(runOption.Map(ma => ma.ToEither(left)));\n\n    public EitherT<L, M, A> ToEither<L>(Func<L> left) =>\n        new(runOption.Map(ma => ma.ToEither(left)));\n\n    public EitherT<L, M, A> ToEither<L>() where L : Monoid<L> =>\n        new(runOption.Map(ma => ma.ToEither<L>()));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Prelude/OptionT.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static OptionT<M, B> map<M, A, B>(Func<A, B> f, K<OptionT<M>, A> ma) \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static OptionT<M, B> action<M, A, B>(K<OptionT<M>, A> ma, OptionT<M, B> mb)\n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static OptionT<M, B> apply<M, A, B>(K<OptionT<M>, Func<A, B>> mf, K<OptionT<M>, A> ma) \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/OptionT/Trait/OptionT.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `OptionT` \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class OptionT<M> : \n    MonadT<OptionT<M>, M>,\n    Alternative<OptionT<M>>,\n    Fallible<Unit, OptionT<M>>,\n    MonadIO<OptionT<M>>\n    where M : Monad<M>\n{\n    static K<OptionT<M>, B> Monad<OptionT<M>>.Bind<A, B>(K<OptionT<M>, A> ma, Func<A, K<OptionT<M>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<OptionT<M>, B> Monad<OptionT<M>>.Recur<A, B>(A value, Func<A, K<OptionT<M>, Next<A, B>>> f) => \n        new OptionT<M, B>(\n            M.Recur<A, Option<B>>(\n                value,\n                a => f(a).As()\n                         .runOption\n                         .Map(e => e switch\n                                   {\n                                       { IsNone: true }                            => Next.Done<A, Option<B>>(default), \n                                       { IsSome: true, Value: { IsDone: true } n } => Next.Done<A, Option<B>>(n.Done), \n                                       { IsSome: true, Value: { IsLoop: true } n } => Next.Loop<A, Option<B>>(n.Loop),\n                                       _                                           => throw new NotSupportedException()\n                                   })));\n\n    static K<OptionT<M>, B> Functor<OptionT<M>>.Map<A, B>(Func<A, B> f, K<OptionT<M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<OptionT<M>, A> Applicative<OptionT<M>>.Pure<A>(A value) => \n        OptionT.Some<M, A>(value);\n\n    static K<OptionT<M>, B> Applicative<OptionT<M>>.Apply<A, B>(K<OptionT<M>, Func<A, B>> mf, K<OptionT<M>, A> ma) =>\n        mf.As().Bind(x => ma.As().Map(x));\n\n    static K<OptionT<M>, B> Applicative<OptionT<M>>.Apply<A, B>(K<OptionT<M>, Func<A, B>> mf, Memo<OptionT<M>, A> ma) =>\n        mf.As().Bind(x => ma.Value.As().Map(x));\n\n    static K<OptionT<M>, A> MonadT<OptionT<M>, M>.Lift<A>(K<M, A> ma) => \n        OptionT.lift(ma);\n        \n    static K<OptionT<M>, A> MonadIO<OptionT<M>>.LiftIO<A>(IO<A> ma) => \n        OptionT.lift(M.LiftIOMaybe(ma));\n\n    static K<OptionT<M>, A> Alternative<OptionT<M>>.Empty<A>() =>\n        OptionT<M, A>.None;\n \n    static K<OptionT<M>, A> Choice<OptionT<M>>.Choose<A>(K<OptionT<M>, A> ma, K<OptionT<M>, A> mb) =>\n        new OptionT<M, A>(\n            M.Bind(ma.As().runOption,\n                   ea => ea.IsSome\n                             ? M.Pure(ea)\n                             : mb.As().runOption));\n\n    static K<OptionT<M>, A> Choice<OptionT<M>>.Choose<A>(K<OptionT<M>, A> ma, Memo<OptionT<M>, A> mb) => \n        new OptionT<M, A>(\n            M.Bind(ma.As().runOption,\n                   ea => ea.IsSome\n                             ? M.Pure(ea)\n                             : mb.Value.As().runOption));\n\n    static K<OptionT<M>, A> Fallible<Unit, OptionT<M>>.Fail<A>(Unit error) =>\n        OptionT.None<M, A>();\n\n    static K<OptionT<M>, A> Fallible<Unit, OptionT<M>>.Catch<A>(\n        K<OptionT<M>, A> fa, \n        Func<Unit, bool> Predicate, \n        Func<Unit, K<OptionT<M>, A>> Fail) => \n        fa.As().BindNone(() => Predicate(default) ? Fail(default).As() : OptionT<M, A>.None);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/README.md",
    "content": "_Alternative Monads_ are monadic types that can have an alternative value!  What does this mean?  \n\nIf first we think about a tuple:\n\n    (int, string)\n\nThis type can represent an `int` _AND_ a `string`.  Now consider the `Either<L, R>` monad, this means the value \ncan be`Left` _OR_ `Right`  (`L` or `R`).  \n\nSo, this:\n\n    Either<int, string>\n\nMeans either `int` _OR_ `string`. It is the natural _dual_ of tuple.\n\nIn the case of `Either` the _Right_ value is considered the _bound_ value of the monad, and the _Left_ value \nis considered the _alternative_ value.  All the other _alternative value monads_ can be seen as derivatives \nor specialisations of `Either`.\n\n| Type                     | Alternative Value Type | Bound Value Type | Notes                                                       |\n|--------------------------|------------------------|------------------|-------------------------------------------------------------|\n| `Either<L, R>`           | `L`                    | `R`              |                                                             |\n| `Fin<A>`                 | `Error`                | `A`              | Equivalent to `Either<Error, A>`                            |\n| `Try<A>`                 | `Error`                | `A`              | Equivalent to `Either<Error, A>` (that catches exceptions!) |\n| `Option<A>`              | `None`                 | `A`              | Equivalent to `Either<Unit, A>`                             |   \n| `Nullable<A>`            | `null`                 | `A`              | Equivalent to `Either<Unit, A>`                             |\n| `Validation<Fail, Succ>` | `Fail`                 | `Succ`           | `Fail` must be a `Monoid<Fail>` to collect errors           |\n\n> _The alternative value is usually used to carry errors, but that doesn't have to be the case. It is \n> important to remember that the alternative-value can be for any purpose you want._"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/Extensions/These.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing NSE = System.NotSupportedException;\n\nnamespace LanguageExt;\n\npublic static partial class TheseExtensions\n{\n    public static These<A, B> As<A, B>(this K<These<A>, B> ma) =>\n        (These<A, B>)ma;\n    \n    /// <summary>\n    /// Coalesce with the provided operation\n    /// </summary>\n    /// <param name=\"f\">Coalesce operation</param>\n    /// <returns>Coalesced value</returns>\n    public static A Merge<A>(this K<These<A>, A> these, Func<A, A, A> f) =>\n        these.As().Match(x => x, x => x, f);\n\n    extension<F, A, B>(K<F, These<A, B>> theses) \n        where F : Foldable<F>\n    {\n        /// <summary>\n        /// Select each constructor and partition them into separate lists.\n        /// </summary>\n        /// <returns>Partitioned sequences</returns>\n        public (Seq<A> This, Seq<B> That, Seq<(A, B)> Both) Partition() =>\n            theses.Fold((This: Seq<A>(), That: Seq<B>(), Both: Seq<(A First, B Second)>()),\n                        (s, ts) => ts switch\n                                   {\n                                       These<A, B>.This (var x)        => (s.This.Add(x), s.That, s.Both),\n                                       These<A, B>.That (var y)        => (s.This, s.That.Add(y), s.Both),\n                                       These<A, B>.Both (var x, var y) => (s.This, s.That, s.Both.Add((x, y))),\n                                       _                               => throw new NSE()\n                                   });\n\n        /// <summary>\n        /// Select each constructor and partition them into separate lists.\n        /// </summary>\n        /// <returns>Partitioned sequences</returns>\n        public (Seq<A> This, Seq<B> That) Partition2() =>\n            theses.Fold((This: Seq<A>(), That: Seq<B>()),\n                        (state, these) => these switch\n                                          {\n                                              These<A, B>.This (var x)        => (state.This.Add(x), state.That),\n                                              These<A, B>.That (var y)        => (state.This, state.That.Add(y)),\n                                              These<A, B>.Both (var x, var y) => (state.This.Add(x), state.That.Add(y)),\n                                              _                               => throw new NSE()\n                                          });\n    }\n\n\n    extension<A, B>(K<These<A>, B> first) \n        where A : Semigroup<A> \n        where B : Semigroup<B>\n    {\n        /// <summary>\n        /// Semigroup combine\n        /// </summary>\n        /// <param name=\"second\">Second `These`</param>\n        /// <returns>`These` combined using semigroup rules</returns>\n        public These<A, B> Combine(K<These<A>, B> second) =>\n            Combine(first, second, Semigroup.combine, Semigroup.combine);\n    }\n\n    extension<A, B>(K<These<A>, B> first)\n    {\n        /// <summary>\n        /// Semigroup combine\n        /// </summary>\n        /// <param name=\"second\">Second `These`</param>\n        /// <returns>`These` combined using semigroup rules</returns>\n        public These<A, B> Combine(K<These<A>, B> second,\n                                   Func<A, A, A> combineFst,\n                                   Func<B, B, B> combineSnd) =>\n            (first, second) switch\n            {\n                (These<A, B>.This (var fx), These<A, B>.This (var sx))                 => This<A, B>(combineFst(fx, sx)),\n                (These<A, B>.This (var fx), These<A, B>.That (var sx))                 => Both(fx, sx),\n                (These<A, B>.This (var fx), These<A, B>.Both (var s1, var s2))         => Both(combineFst(fx, s1), s2),\n                (These<A, B>.That (var fx), These<A, B>.This (var sx))                 => Both(sx, fx),\n                (These<A, B>.That (var fx), These<A, B>.That (var sx))                 => That<A, B>(combineSnd(fx, sx)),\n                (These<A, B>.That (var fx), These<A, B>.Both (var s1, var s2))         => Both(s1, combineSnd(fx, s2)),\n                (These<A, B>.Both (var f1, var f2), These<A, B>.This (var sx))         => Both(combineFst(f1, sx), f2),\n                (These<A, B>.Both (var f1, var f2), These<A, B>.That (var sx))         => Both(f1, combineSnd(f2, sx)),\n                (These<A, B>.Both (var f1, var f2), These<A, B>.Both (var s1, var s2)) => Both(combineFst(f1, s1), combineSnd(f2, s2)),\n                _                                                                      => throw new NSE()\n            };\n    }\n\n    extension<A, B, C>(K<These<A>, Func<B, C>> mf) \n        where A : Semigroup<A>\n    {\n        public These<A, C> Apply(K<These<A>, B> ma) =>\n            mf.Apply(ma, Semigroup.combine);\n    }\n\n    extension<A, B, C>(K<These<A>, Func<B, C>> mf)\n    {\n        public These<A, C> Apply(K<These<A>, B> ma,\n                                 Func<A, A, A> combine) =>\n            (mf, ma) switch\n            {\n                (These<A, Func<B, C>>.This (var a), _)                                       => This<A, C>(a),\n                (These<A, Func<B, C>>.That, These<A, B>.This (var a))                        => This<A, C>(a),\n                (These<A, Func<B, C>>.That (var f), These<A, B>.That (var b))                => That<A, C>(f(b)),\n                (These<A, Func<B, C>>.That (var f), These<A, B>.Both (var a, var b))         => Both(a, f(b)),\n                (These<A, Func<B, C>>.Both (var a1, _), These<A, B>.This (var a2))           => This<A, C>(combine(a1, a2)),\n                (These<A, Func<B, C>>.Both (var a1, var f), These<A, B>.That (var b))        => Both(a1, f(b)),\n                (These<A, Func<B, C>>.Both (var a1, var f), These<A, B>.Both (var a, var b)) => Both(combine(a1, a), f(b)),\n                _                                                                            => throw new NSE()\n            };\n    }\n\n    extension<A, B>(K<These<A>, B> mb) where A : Semigroup<A>\n    {\n        /// <summary>\n        /// Monad bind operation\n        /// </summary>\n        /// <param name=\"f\">Chaining function</param>\n        public These<A, C> Bind<C>(Func<B, K<These<A>, C>> f) =>\n            mb switch\n            {\n                These<A, B>.This (var v) => This<A, C>(v),\n                These<A, B>.That (var v) => f(v).As(),\n                These<A, B>.Both (var x, var y) => f(y) switch\n                                                   {\n                                                       These<A, C>.This (var a)        => This<A, C>(x + a),\n                                                       These<A, C>.That (var b)        => Both(x, b),\n                                                       These<A, C>.Both (var a, var b) => Both(x + a, b),\n                                                       _                               => throw new NSE()\n                                                   },\n                _ => throw new NSE()\n            };\n\n        public These<A, D> SelectMany<C, D>(Func<B, K<These<A>, C>> bind, \n                                            Func<B, C, D> project) =>\n            mb.Bind(b => bind(b).Map(c => project(b, c)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/Operators/These.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class TheseExtensions\n{\n    extension<X, A, B>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, B> operator *(Func<A, B> f, K<These<X>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, B> operator *(K<These<X>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<X, A, B, C>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, C>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<X, A, B, C, D>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, D>>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<X, A, B, C, D, E>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<X, A, B, C, D, E, F>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<X, A, B, C, D, E, F, G>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<X, A, B, C, D, E, F, G, H>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<X, A, B, C, D, E, F, G, H, I>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<X, A, B, C, D, E, F, G, H, I, J>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<X, A, B, C, D, E, F, G, H, I, J, K>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<These<X>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static These<X, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<These<X>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/Operators/These.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Traits;\nnamespace LanguageExt;\n\npublic static partial class TheseExtensions\n{\n    extension<A, B>(K<These<A>, B> _) \n        where A : Semigroup<A>\n        where B : Semigroup<B>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static K<These<A>, B> operator +(K<These<A>, B> lhs, K<These<A>, B> rhs) =>\n            lhs.Combine(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/Operators/These.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TheseExtensions\n{\n    extension<X, A>(K<These<X>, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static These<X, A> operator +(K<These<X>, A> ma) =>\n            (These<X, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static These<X, A> operator >> (K<These<X>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/Prelude/These.Prelude.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Prelude\n{\n    /// <summary>\n    /// This constructor\n    /// </summary>\n    /// <param name=\"value\">Value to set</param>\n    /// <returns>Constructed `These` structure</returns>\n    public static These<A, B> This<A, B>(A value) =>\n        new These<A, B>.This(value);\n    \n    /// <summary>\n    /// That constructor\n    /// </summary>\n    /// <param name=\"value\">Value to set</param>\n    /// <returns>Constructed `These` structure</returns>\n    public static These<A, B> That<A, B>(B value) =>\n        new These<A, B>.That(value);    \n    \n    /// <summary>\n    /// Both constructor\n    /// </summary>\n    /// <param name=\"first\">First value to set</param>\n    /// <param name=\"second\">Second value to set</param>\n    /// <returns>Constructed `These` structure</returns>\n    public static These<A, B> Both<A, B>(A first, B second) =>\n        new These<A, B>.Both(first, second);\n    \n    /// <summary>\n    /// Coalesce with the provided operation\n    /// </summary>\n    /// <param name=\"f\">Coalesce operation</param>\n    /// <returns>Coalesced value</returns>\n    public static A merge<A>(Func<A, A, A> f, These<A, A> these) =>\n        these.Merge(f);\n\n    /// <summary>\n    /// Select each constructor and partition them into separate lists.\n    /// </summary>\n    /// <param name=\"theses\">Selection</param>\n    /// <typeparam name=\"F\">Foldable structure</typeparam>\n    /// <returns>Partitioned sequences</returns>\n    public static (Seq<A> This, Seq<B> That, Seq<(A, B)> Both) partition<F, A, B>(K<F, These<A, B>> theses)\n        where F : Foldable<F> =>\n        theses.Partition();\n    \n    /// <summary>\n    /// Select each constructor and partition them into separate lists.\n    /// </summary>\n    /// <param name=\"theses\">Selection</param>\n    /// <typeparam name=\"F\">Foldable structure</typeparam>\n    /// <returns>Partitioned sequences</returns>\n    public static (Seq<A> This, Seq<B> That) partition2<F, A, B>(K<F, These<A, B>> theses)\n        where F : Foldable<F> =>\n        theses.Partition2();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/These.Both.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\npublic abstract partial record These<A, B>\n{\n    public sealed record Both(A First, B Second) : These<A, B>\n    {\n        public override C Match<C>(Func<A, C> This, Func<B, C> That, Func<A, B, C> Both) =>\n            Both(First, Second);   \n    \n        public override (A, B) ToTuple(A x, B y) =>\n            (First, Second);    \n\n        public override These<A, C> Map<C>(Func<B, C> f) =>\n            new These<A, C>.Both(First, f(Second));\n\n        public override These<C, D> BiMap<C, D>(Func<A, C> This, Func<B, D> That) =>\n            new These<C, D>.Both(This(First), That(Second));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/These.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class These\n{\n    /// <summary>\n    /// This constructor\n    /// </summary>\n    /// <param name=\"value\">Value to set</param>\n    /// <returns>Constructed `These` structure</returns>\n    public static These<A, B> This<A, B>(A value) =>\n        new These<A, B>.This(value);\n    \n    /// <summary>\n    /// That constructor\n    /// </summary>\n    /// <param name=\"value\">Value to set</param>\n    /// <returns>Constructed `These` structure</returns>\n    public static These<A, B> That<A, B>(B value) =>\n        new These<A, B>.That(value);    \n    \n    /// <summary>\n    /// Both constructor\n    /// </summary>\n    /// <param name=\"first\">First value to set</param>\n    /// <param name=\"second\">Second value to set</param>\n    /// <returns>Constructed `These` structure</returns>\n    public static These<A, B> Both<A, B>(A first, B second) =>\n        new These<A, B>.Both(first, second);\n    \n    /// <summary>\n    /// Coalesce with the provided operation\n    /// </summary>\n    /// <param name=\"f\">Coalesce operation</param>\n    /// <returns>Coalesced value</returns>\n    public static A merge<A>(Func<A, A, A> f, These<A, A> these) =>\n        these.Merge(f);\n\n    /// <summary>\n    /// Select each constructor and partition them into separate lists.\n    /// </summary>\n    /// <param name=\"theses\">Selection</param>\n    /// <typeparam name=\"F\">Foldable structure</typeparam>\n    /// <returns>Partitioned sequences</returns>\n    public static (Seq<A> This, Seq<B> That, Seq<(A, B)> Both) partition<F, A, B>(\n        K<F, These<A, B>> theses)\n        where F : Foldable<F> =>\n        theses.Partition();\n    \n    /// <summary>\n    /// Select each constructor and partition them into separate lists.\n    /// </summary>\n    /// <param name=\"theses\">Selection</param>\n    /// <typeparam name=\"F\">Foldable structure</typeparam>\n    /// <returns>Partitioned sequences</returns>\n    public static (Seq<A> This, Seq<B> That) partition2<F, A, B>(\n        K<F, These<A, B>> theses)\n        where F : Foldable<F> =>\n        theses.Partition2();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/These.That.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\npublic abstract partial record These<A, B>\n{\n    public sealed record That(B Value) : These<A, B>\n    {\n        public override C Match<C>(Func<A, C> This, Func<B, C> That, Func<A, B, C> Both) =>\n            That(Value);\n    \n        public override (A, B) ToTuple(A x, B y) =>\n            (x, Value);\n\n        public override These<A, C> Map<C>(Func<B, C> f) =>\n            new These<A, C>.That(f(Value));\n\n        public override These<C, D> BiMap<C, D>(Func<A, C> This, Func<B, D> That) =>\n            new These<C, D>.That(That(Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/These.This.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\npublic abstract partial record These<A, B>\n{\n    public sealed record This(A Value) : These<A, B>\n    {\n        public override C Match<C>(Func<A, C> This, Func<B, C> That, Func<A, B, C> Both) =>\n            This(Value);\n    \n        public override (A, B) ToTuple(A x, B y) =>\n            (Value, y);\n\n        public override These<A, C> Map<C>(Func<B, C> f) =>\n            new These<A, C>.This(Value);\n\n        public override These<C, D> BiMap<C, D>(Func<A, C> This, Func<B, D> That) =>\n            new These<C, D>.This(This(Value));\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/These.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic abstract partial record These<A, B> : K<These<A>, B>\n{\n    /// <summary>\n    /// Stop other types deriving from These\n    /// </summary>\n    private These() {}\n    \n    /// <summary>\n    /// Case analysis for the `These` type\n    /// </summary>\n    /// <param name=\"This\">Match for `This` state</param>\n    /// <param name=\"That\">Match for `That` state</param>\n    /// <param name=\"Both\">Match for `Both` state</param>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of running either `This`, `That`, or `Both`</returns>\n    public abstract C Match<C>(Func<A, C> This, Func<B, C> That, Func<A, B, C> Both);\n\n    /// <summary>\n    /// Takes two default values and produces a tuple\n    /// </summary>\n    /// <param name=\"x\">Default value A</param>\n    /// <param name=\"y\">Default value B</param>\n    /// <returns>Tuple</returns>\n    public abstract (A, B) ToTuple(A x, B y);\n\n    /// <summary>\n    /// Bi-functor map operation\n    /// </summary>\n    /// <param name=\"This\">Mapping of `This`</param>\n    /// <param name=\"That\">Mapping of `That`</param>\n    /// <typeparam name=\"C\">Resulting `This` bound value type</typeparam>\n    /// <typeparam name=\"D\">Resulting `That` bound value type</typeparam>\n    /// <returns></returns>\n    public abstract These<C, D> BiMap<C, D>(Func<A, C> This, Func<B, D> That)\n        where C : Semigroup<C>;\n\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    public abstract These<A, C> Map<C>(Func<B, C> f);\n\n    /// <summary>\n    /// Traverse\n    /// </summary>\n    public K<F, These<A, C>> Traverse<F, C>(Func<B, K<F, C>> f) \n        where F : Applicative<F> =>\n        this.Kind().Traverse(f).Map(ac => ac.As());\n    \n    /// <summary>\n    /// Bi-map and coalesce results with the provided operation.\n    /// </summary>\n    /// <param name=\"This\">This mapping</param>\n    /// <param name=\"That\">That mapping</param>\n    /// <param name=\"Both\">Both mapping</param>\n    /// <typeparam name=\"C\"></typeparam>\n    /// <returns></returns>\n    public C Merge<C>(Func<A, C> This, Func<B, C> That, Func<C, C, C> Both) \n        where C : Semigroup<C> =>\n        BiMap(This, That).Merge(Both);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/These/Trait/These.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude; \n\nnamespace LanguageExt;\n\npublic class These<A> : Traversable<These<A>>\n{\n    public static K<These<A>, C> Map<B, C>(Func<B, C> f, K<These<A>, B> ma) =>\n        ma.As().Map(f);\n\n    public static S FoldWhile<B, S>(\n        Func<B, Func<S, S>> f,\n        Func<(S State, B Value), bool> predicate,\n        S state,\n        K<These<A>, B> ta) =>\n        ta switch\n        {\n            These<A, B>.This            => state,\n            These<A, B>.That (var b)    => predicate((state, b)) ? f(b)(state) : state,\n            These<A, B>.Both (_, var b) => predicate((state, b)) ? f(b)(state) : state,\n            _                           => throw new NotSupportedException()\n        };\n\n    public static S FoldBackWhile<B, S>(\n        Func<S, Func<B, S>> f,\n        Func<(S State, B Value), bool> predicate,\n        S state,\n        K<These<A>, B> ta) =>\n        ta switch\n        {\n            These<A, B>.This            => state,\n            These<A, B>.That (var b)    => predicate((state, b)) ? f(state)(b) : state,\n            These<A, B>.Both (_, var b) => predicate((state, b)) ? f(state)(b) : state,\n            _                           => throw new NotSupportedException()\n        };\n\n    public static K<F, K<These<A>, C>> Traverse<F, B, C>(Func<B, K<F, C>> f, K<These<A>, B> ta)\n        where F : Applicative<F> =>\n        ta switch\n        {\n            These<A, B>.This (var a)        => F.Pure(This<A, C>(a).Kind()),\n            These<A, B>.That (var b)        => F.Map(x => That<A, C>(x).Kind(), f(b)),\n            These<A, B>.Both (var a, var b) => F.Map(x => Both(a, x).Kind(), f(b)),\n            _                               => throw new NotSupportedException()\n        };\n\n    static Fold<B, S> Foldable<These<A>>.FoldStep<B, S>(K<These<A>, B> ta, S initialState)\n    {\n        var ma = ta.As();\n        return ma switch\n               {\n                   These<A, B>.That(var b)    => Fold.Loop(initialState, b, Fold.Done<B, S>),\n                   These<A, B>.Both(_, var b) => Fold.Loop(initialState, b, Fold.Done<B, S>),\n                   _                          => Fold.Done<B, S>(initialState)\n               };\n    }\n        \n    static Fold<B, S> Foldable<These<A>>.FoldStepBack<B, S>(K<These<A>, B> ta, S initialState) =>\n        ta.FoldStep(initialState);\n    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Extensions/Try.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Try<B> Map<A, B>(this Func<A, B> f, K<Try, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Try<B> Map<A, B>(this Func<A, B> f, Try<A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Try<B> Action<A, B>(this Try<A> ma, K<Try, B> mb) =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Try<B> Action<A, B>(this K<Try, A> ma, K<Try, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Try<B> Apply<A, B>(this Try<Func<A, B>> mf, K<Try, A> ma) =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Try<B> Apply<A, B>(this K<Try, Func<A, B>> mf, K<Try, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Extensions/Try.Extensions.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Try monad extensions\n/// </summary>\npublic static partial class TryExtensions\n{\n    public static Try<A> As<A>(this K<Try, A> ma) =>\n        (Try<A>)ma;\n\n    /// <summary>\n    /// Run the `Try`\n    /// </summary>\n    public static Fin<A> Run<A>(this K<Try, A> ma)\n    {\n        try\n        {\n            return ma.As().runTry();\n        }\n        catch (Exception e)\n        {\n            return Fin.Fail<A>(e);\n        }\n    }\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Try<A> Flatten<A>(this K<Try, Try<A>> mma) =>\n        new(() =>\n                mma.As().Run() switch\n                {\n                    Fin<Try<A>>.Succ (var succ) => succ.Run(),\n                    Fin<Try<A>>.Fail (var fail) => Fin.Fail<A>(fail),\n                    _                           => throw new NotSupportedException()\n                });\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Try<A> Flatten<A>(this K<Try, K<Try, A>> mma) =>\n        new(() =>\n                mma.Run() switch\n                {\n                    Fin<K<Try, A>>.Succ (var succ) => succ.Run(),\n                    Fin<K<Try, A>>.Fail (var fail) => Fin.Fail<A>(fail),\n                    _                              => throw new NotSupportedException()\n                });\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Operators/Try.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class TryExtensions\n{\n    extension<A, B>(K<Try, A> self)\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Try<B> operator >>> (K<Try, A> ma, K<Try, B> mb) =>\n            ma.Action(mb).As();\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<B> operator * (K<Try, Func<A, B>> mf, K<Try, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<B> operator * (K<Try, A> ma, K<Try, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<A, B, C>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, C>> operator * (\n            K<Try, Func<A, B, C>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, C>> operator * (\n            K<Try, A> ma,\n            K<Try, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<A, B, C, D>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, D>>> operator * (\n            K<Try, Func<A, B, C, D>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, D>>> operator * (\n            K<Try, A> ma,\n            K<Try, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Try, Func<A, B, C, D, E>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Try, A> ma,\n            K<Try, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Try, Func<A, B, C, D, E, F>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Try, A> ma,\n            K<Try, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Try, Func<A, B, C, D, E, F, G>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Try, A> ma,\n            K<Try, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G, H>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Try, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Try, A> ma,\n            K<Try, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Try, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Try, A> ma,\n            K<Try, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Try, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Try, A> ma,\n            K<Try, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Try, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Try, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Try, A> ma,\n            K<Try, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Operators/Try.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryExtensions\n{\n    extension<A>(K<Try, A> self)\n    {\n        public static Try<A> operator |(K<Try, A> lhs, K<Try, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static Try<A> operator |(K<Try, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(rhs.ToTry());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Operators/Try.Operators.Fallible.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryExtensions\n{\n    extension<A>(K<Try, A> self)\n    {\n        public static Try<A> operator |(K<Try, A> lhs, CatchM<Error, Try, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Try<A> operator |(K<Try, A> lhs, Fail<Error> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Try<A> operator |(K<Try, A> lhs, Fail<Exception> rhs) =>\n            +lhs.Choose(Try.Fail<A>(rhs.Value));\n\n        public static Try<A> operator |(K<Try, A> lhs, Error rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Try<A> operator |(K<Try, A> lhs, Exception rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Operators/Try.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class TryExtensions\n{\n    extension<X, A>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static Try<A> operator |(K<Try, A> lhs, Finally<Try, X> rhs) =>\n            +lhs.Finally(rhs.Operation);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Operators/Try.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class TryExtensions\n{\n    extension<A, B>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<B> operator *(Func<A, B> f, K<Try, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<B> operator *(K<Try, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<A, B, C>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, C>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<A, B, C, D>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, D>>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Try, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Try<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Try, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Operators/Try.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryExtensions\n{\n    extension<A, B>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Try<B> operator >> (K<Try, A> ma, Func<A, K<Try, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Try<B> operator >> (K<Try, A> lhs, K<Try, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<A>(K<Try, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Try<A> operator >> (K<Try, A> lhs, K<Try, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Operators/Try.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryExtensions\n{\n    extension<A>(K<Try, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Try<A> operator +(K<Try, A> ma) =>\n            (Try<A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Try<A> operator >> (K<Try, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Prelude/Try.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Try<B> map<A, B>(Func<A, B> f, K<Try, A> ma) =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Try<B> action<A, B>(K<Try, A> ma, K<Try, B> mb) =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Try<B> apply<A, B>(K<Try, Func<A, B>> mf, K<Try, A> ma) =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Trait/Try.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `Try` \n/// </summary>\npublic partial class Try : \n    Monad<Try>,\n    Fallible<Try>, \n    Final<Try>,\n    Alternative<Try>\n{\n    static K<Try, B> Monad<Try>.Bind<A, B>(K<Try, A> ma, Func<A, K<Try, B>> f) =>\n        new Try<B>(() => ma.Run() switch\n                         {\n                             Fin<A>.Succ(var x) => f(x).Run(),\n                             Fin<A>.Fail(var e) => Fin.Fail<B>(e),\n                             _                  => throw new NotSupportedException()\n                         });\n\n    static K<Try, B> Monad<Try>.Recur<A, B>(A value, Func<A, K<Try, Next<A, B>>> f) =>\n        lift(() =>\n             {\n                 while (true)\n                 {\n                     var mr = +f(value).Run();\n                     if (mr.IsFail) return Fin.Fail<B>(mr.FailValue);\n                     var next = (Next<A, B>)mr;\n                     if (next.IsDone) return Fin.Succ<B>(next.Done);\n                     value = next.Loop;\n                 }\n             });\n\n    static K<Try, B> Functor<Try>.Map<A, B>(Func<A, B> f, K<Try, A> ma) => \n        new Try<B>(() => ma.Run().Map(f));\n\n    static K<Try, A> Applicative<Try>.Pure<A>(A value) => \n        Succ(value);\n\n    static K<Try, B> Applicative<Try>.Apply<A, B>(K<Try, Func<A, B>> mf, K<Try, A> ma) =>\n        new Try<B>(() => mf.Run().Apply(ma.Run()));\n\n    static K<Try, B> Applicative<Try>.Apply<A, B>(K<Try, Func<A, B>> mf, Memo<Try, A> ma) =>\n        new Try<B>(() => mf.Run().Apply(ma.Value.Run()));\n\n    static K<Try, A> Alternative<Try>.Empty<A>() =>\n        Try.Fail<A>(Error.Empty);\n\n    static K<Try, A> Choice<Try>.Choose<A>(K<Try, A> ma, K<Try, A> mb) =>\n        new Try<A>(() => ma.Run() switch\n                         {\n                             Fin<A>.Succ(var x) => Fin.Succ<A>(x),\n                             Fin<A>.Fail        => mb.Run(),\n                             _                  => throw new NotSupportedException()\n                         });\n\n    static K<Try, A> Choice<Try>.Choose<A>(K<Try, A> ma, Memo<Try, A> mb) => \n        new Try<A>(() => ma.Run() switch\n                         {\n                             Fin<A>.Succ(var x) => Fin.Succ(x),\n                             Fin<A>.Fail        => mb.Value.Run(),\n                             _                  => throw new NotSupportedException()\n                         });\n\n    static K<Try, A> Fallible<Error, Try>.Fail<A>(Error value) => \n        Fail<A>(value);\n\n    static K<Try, A> Fallible<Error, Try>.Catch<A>(\n        K<Try, A> fa, \n        Func<Error, bool> Predicate,\n        Func<Error, K<Try, A>> Fail) =>\n        new Try<A>(() => fa.Run() switch\n                         {\n                             Fin<A>.Succ ma                       => ma,\n                             Fin<A>.Fail(var e) when Predicate(e) => Fail(e).Run(),\n                             var ma                               => ma\n                         });\n\n    static K<Try, A> Final<Try>.Finally<X, A>(K<Try, A> fa, K<Try, X> @finally) =>\n        new Try<A>(() =>\n                   {\n                       try\n                       {\n                           return fa.Run();\n                       }\n                       finally\n                       {\n                           @finally.Run().ThrowIfFail();\n                       }\n                   });\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Try.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\npublic partial class Try\n{\n    /// <summary>\n    /// Lifts a pure success value into a `Try` monad\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`Try`</returns>\n    public static Try<A> Succ<A>(A value) => \n        new (() => value);\n\n    /// <summary>\n    /// Lifts a failure value into a `Try` monad\n    /// </summary>\n    /// <param name=\"value\">Failure value to lift</param>\n    /// <returns>`Try`</returns>\n    public static Try<A> Fail<A>(Error value) => \n        new (() => value);\n\n    /// <summary>\n    /// Lifts a given function into a `Try` monad\n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`Try`</returns>\n    public static Try<A> lift<A>(Func<Fin<A>> f) => \n        new(() =>\n            {\n                try\n                {\n                    return f();\n                }\n                catch (Exception e)\n                {\n                    return Fin.Fail<A>(e);\n                }\n            });\n    \n    /// <summary>\n    /// Lifts a given value into a `Try` monad\n    /// </summary>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <returns>`Try`</returns>\n    public static Try<A> lift<A>(Fin<A> ma) => \n        new (() => ma);\n\n    /// <summary>\n    /// Lifts a given value into a `Try` monad\n    /// </summary>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <returns>`Try`</returns>\n    public static Try<A> lift<A>(Pure<A> ma) => \n        new (() => ma.Value);\n\n    /// <summary>\n    /// Lifts a given value into a `Try` monad\n    /// </summary>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <returns>`Try`</returns>\n    public static Try<A> lift<A>(Fail<Error> ma) => \n        new (() => ma.Value);\n\n    /// <summary>\n    /// Lifts a given function into a `Try` monad\n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`Try`</returns>\n    public static Try<A> lift<A>(Func<A> f) => \n        new(() =>\n            {\n                try\n                {\n                    return f();\n                }\n                catch (Exception e)\n                {\n                    return Fin.Fail<A>(e);\n                }\n            });\n\n    /// <summary>\n    /// Lifts a given function into a `Try` monad\n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`Try`</returns>\n    public static Try<Unit> lift(Action f) =>\n        lift<Unit>(() => { f(); return default; });\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Try/Try.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `Try` monad which allows for an optional `Error` result and catches exceptions, converting them to `Error`. \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record Try<A>(Func<Fin<A>> runTry) : \n    K<Try, A>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Match\n    //\n\n    /// <summary>\n    /// Match the bound value and return a result (which gets packages back up inside the inner monad)\n    /// </summary>\n    /// <param name=\"Succ\">Success branch</param>\n    /// <param name=\"Fail\">Fail branch</param>\n    /// <returns>Inner monad with the result of the `Succ` or `Fail` branches</returns>\n    public B Match<B>(Func<A, B> Succ, Func<Error, B> Fail) =>\n        this.Run().Match(Succ, Fail);\n\n    /// <summary>\n    /// Match the bound value and return a result (which gets packages back up inside the inner monad)\n    /// </summary>\n    /// <param name=\"Succ\">Success branch</param>\n    /// <param name=\"Fail\">Fail branch</param>\n    /// <returns>Inner monad with the result of the `Succ` or `Fail` branches</returns>\n    public A IfFail(Func<Error, A> Fail) =>\n        Match(identity, Fail);\n\n    /// <summary>\n    /// Match the bound value and return a result (which gets packages back up inside the inner monad)\n    /// </summary>\n    /// <param name=\"Succ\">Success branch</param>\n    /// <param name=\"Fail\">Fail branch</param>\n    /// <returns>Inner monad with the result of the `Succ` or `Fail` branches</returns>\n    public Fin<A> IfFailM(Func<Error, Fin<A>> Fail) =>\n        Match(Fin.Succ, Fail);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<B> Map<B>(Func<A, B> f) =>\n        new(() => runTry().Map(f));\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`TryT`</returns>\n    public Try<A> MapFail(Func<Error, Error> f) =>\n        this.Catch(f).As();\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<B> Select<B>(Func<A, B> f) =>\n        new(() => runTry().Map(f));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<B> Bind<B>(Func<A, K<Try, B>> f) =>\n        new(() =>\n            {\n                var r = runTry();\n                return r.IsFail\n                           ? Fin.Fail<B>((Error)r)\n                           : f((A)r).As().runTry();\n            });\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<B> Bind<B>(Func<A, Try<B>> f) =>\n        new(() =>\n            {\n                var r = runTry();\n                return r.IsFail\n                           ? Fin.Fail<B>((Error)r)\n                           : f((A)r).runTry();\n            });\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(a => f(a).Value);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"Succ\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<B> BiBind<B>(Func<A, Try<B>> Succ, Func<Error, Try<B>> Fail) =>\n        Bind(Succ).Catch(Fail).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"Succ\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<A> BindFail(Func<Error, Try<A>> Fail) =>\n        this.Catch(Fail).As();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<C> SelectMany<B, C>(Func<A, K<Try, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<C> SelectMany<B, C>(Func<A, Try<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<C> SelectMany<B, C>(Func<A, Fin<B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => Try.lift(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public Try<C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Conversion operators\n    //\n\n    public static implicit operator Try<A>(Pure<A> ma) =>\n        Try.Succ(ma.Value);\n    \n    public static implicit operator Try<A>(Error ma) =>\n        Try.lift(Fin.Fail<A>(ma));\n    \n    public static implicit operator Try<A>(Fail<Error> ma) =>\n        Try.lift(Fin.Fail<A>(ma.Value));\n    \n    public static implicit operator Try<A>(Fail<Exception> ma) =>\n        Try.lift(Fin.Fail<A>(ma.Value));\n\n    public Option<A> ToOption() =>\n        this.Run().ToOption(); \n\n    public Either<Error, A> ToEither() =>\n        this.Run().ToEither(); \n\n    public Fin<A> ToFin() =>\n        this.Run();\n\n    public IO<A> ToIO() => \n        IO.lift(runTry);\n\n    [Pure]\n    public Try<A> Combine(Try<A> rhs) =>\n        new(() => this.Run() switch\n                  {\n                      Fin<A>.Fail fa => fa.Combine(rhs.Run()).As(),\n                      var fa         => fa\n                  });\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Extensions/TryT.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryTExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static TryT<M, B> Map<M, A, B>(this Func<A, B> f, K<TryT<M>, A> ma) \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static TryT<M, B> Map<M, A, B>(this Func<A, B> f, TryT<M, A> ma) \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static TryT<M, B> Action<M, A, B>(this TryT<M, A> ma, K<TryT<M>, B> mb)\n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static TryT<M, B> Action<M, A, B>(this K<TryT<M>, A> ma, K<TryT<M>, B> mb) \n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static TryT<M, B> Apply<M, A, B>(this TryT<M, Func<A, B>> mf, K<TryT<M>, A> ma) \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static TryT<M, B> Apply<M, A, B>(this K<TryT<M>, Func<A, B>> mf, K<TryT<M>, A> ma) \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Extensions/TryT.Extensions.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `TryT` monad extensions\n/// </summary>\npublic static partial class TryTExtensions\n{\n    public static TryT<M, A> As<M, A>(this K<TryT<M>, A> ma)\n        where M : Monad<M> =>\n        (TryT<M, A>)ma;\n\n    /// <summary>\n    /// Run the transformer\n    /// </summary>\n    /// <remarks>\n    /// This is where the exceptions are caught\n    /// </remarks>\n    public static K<M, Fin<A>> Run<M, A>(this K<TryT<M>, A> ma) \n        where M : Monad<M> =>\n        ma.As().runTry.Map(t => t.Run());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, B> Bind<M, A, B>(this K<TryT<M>, A> ma, Func<A, IO<B>> f) \n        where M : MonadIO<M> =>\n        ma.As().Bind(a => TryT.liftIO<M, B>(f(a)));\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static TryT<M, A> Flatten<M, A>(this K<TryT<M>, TryT<M, A>> mma)\n        where M : Monad<M> =>\n        new(mma.As().runTry.Bind(\n                ta => ta.Run() switch\n                      {\n                          Fin<TryT<M, A>>.Succ(var ma) => ma.runTry,\n                          Fin<TryT<M, A>>.Fail(var e)  => M.Pure(Try.Fail<A>(e)),\n                          _                            => throw new NotSupportedException()\n                      }));\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static TryT<M, A> Flatten<M, A>(this K<TryT<M>, K<TryT<M>, A>> mma)\n        where M : Monad<M> =>\n        new(mma.As().runTry.Bind(\n                ta => ta.Run() switch\n                      {\n                          Fin<K<TryT<M>, A>>.Succ(var ma) => ma.As().runTry,\n                          Fin<K<TryT<M>, A>>.Fail(var e)  => M.Pure(Try.Fail<A>(e)),\n                          _                               => throw new NotSupportedException()\n                      }));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    [Pure]\n    public static TryT<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<TryT<M>, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        TryT.lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    [Pure]\n    public static TryT<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, TryT<M, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        TryT.lift(ma).SelectMany(bind, project);\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    [Pure]\n    public static TryT<M, C> SelectMany<M, A, B, C>(\n        this K<TryT<M>, A> ma,\n        Func<A, IO<B>> bind, \n        Func<A, B, C> project) \n        where M : MonadIO<M> =>\n        ma.As().SelectMany(x => M.LiftIO(bind(x)), project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Operators/TryT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class TryTExtensions\n{\n    extension<M, A, B>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static TryT<M, B> operator >>> (K<TryT<M>, A> ma, K<TryT<M>, B> mb) =>\n            ma.Action(mb).As();\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, B> operator * (K<TryT<M>, Func<A, B>> mf, K<TryT<M>, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, B> operator * (K<TryT<M>, A> ma, K<TryT<M>, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<M, A, B, C>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, C>> operator * (\n            K<TryT<M>, Func<A, B, C>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, C>> operator * (\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, D>>> operator * (\n            K<TryT<M>, Func<A, B, C, D>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, D>>> operator * (\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<TryT<M>, Func<A, B, C, D, E>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<TryT<M>, Func<A, B, C, D, E, F>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<TryT<M>, Func<A, B, C, D, E, F, G>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G, H>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<TryT<M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<TryT<M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<TryT<M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<TryT<M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<TryT<M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<TryT<M>, A> ma,\n            K<TryT<M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Operators/TryT.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryTExtensions\n{\n    extension<M, A>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        public static TryT<M, A> operator |(K<TryT<M>, A> lhs, K<TryT<M>, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static TryT<M, A> operator |(K<TryT<M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(TryT.Succ<M, A>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Operators/TryT.Operators.Fallible.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryTExtensions\n{\n    extension<M, A>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        public static TryT<M, A> operator |(K<TryT<M>, A> lhs, CatchM<Error, TryT<M>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static TryT<M, A> operator |(K<TryT<M>, A> lhs, Fail<Error> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static TryT<M, A> operator |(K<TryT<M>, A> lhs, Fail<Exception> rhs) =>\n            +lhs.Catch(rhs.Value);\n\n        public static TryT<M, A> operator |(K<TryT<M>, A> lhs, Error rhs) =>\n            +lhs.Catch(rhs);\n\n        public static TryT<M, A> operator |(K<TryT<M>, A> lhs, Exception rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Operators/TryT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class TryTExtensions\n{\n    extension<M, A, B>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, B> operator *(Func<A, B> f, K<TryT<M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, B> operator *(K<TryT<M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<M, A, B, C>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, C>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, D>>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<TryT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static TryT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<TryT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Operators/TryT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryTExtensions\n{\n    extension<M, A, B>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static TryT<M, B> operator >> (K<TryT<M>, A> ma, Func<A, K<TryT<M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static TryT<M, B> operator >> (K<TryT<M>, A> lhs, K<TryT<M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<M, A>(K<TryT<M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static TryT<M, A> operator >> (K<TryT<M>, A> lhs, K<TryT<M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Operators/TryT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class TryTExtensions\n{\n    extension<M, A>(K<TryT<M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static TryT<M, A> operator +(K<TryT<M>, A> ma) =>\n            (TryT<M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static TryT<M, A> operator >> (K<TryT<M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Prelude/TryT.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static TryT<M, B> map<M, A, B>(Func<A, B> f, K<TryT<M>, A> ma) \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static TryT<M, B> action<M, A, B>(K<TryT<M>, A> ma, K<TryT<M>, B> mb) \n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static TryT<M, B> apply<M, A, B>(K<TryT<M>, Func<A, B>> mf, K<TryT<M>, A> ma) \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/Trait/TryT.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `TryT` \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class TryT<M> : \n    Fallible<TryT<M>>, \n    MonadT<TryT<M>, M>, \n    Alternative<TryT<M>>,\n    MonadIO<TryT<M>>\n    where M : Monad<M>\n{\n    static K<TryT<M>, B> Monad<TryT<M>>.Bind<A, B>(K<TryT<M>, A> ma, Func<A, K<TryT<M>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<TryT<M>, B> Monad<TryT<M>>.Recur<A, B>(A value, Func<A, K<TryT<M>, Next<A, B>>> f) => \n        new TryT<M, B>(\n            M.Recur<A, Try<B>>(\n                value,\n                a => f(a).As()\n                         .Run()\n                         .Map(e => e switch\n                                   {\n                                       Fin<Next<A, B>>.Fail(var err)            => Next.Done<A, Try<B>>(err), \n                                       Fin<Next<A, B>>.Succ({ IsDone: true } n) => Next.Done<A, Try<B>>(Try.Succ(n.Done)), \n                                       Fin<Next<A, B>>.Succ({ IsLoop: true } n) => Next.Loop<A, Try<B>>(n.Loop),\n                                       _                                        => throw new NotSupportedException()\n                                   })));\n\n    static K<TryT<M>, B> Functor<TryT<M>>.Map<A, B>(Func<A, B> f, K<TryT<M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<TryT<M>, A> Applicative<TryT<M>>.Pure<A>(A value) => \n        TryT.Succ<M, A>(value);\n\n    static K<TryT<M>, B> Applicative<TryT<M>>.Apply<A, B>(K<TryT<M>, Func<A, B>> mf, K<TryT<M>, A> ma) =>\n        new TryT<M, B>(mf.As().runTry.Bind(\n                           mf1 => ma.As().runTry.Bind(\n                               ma1 => M.Pure(mf1.Apply(ma1)))));\n    \n    static K<TryT<M>, B> Applicative<TryT<M>>.Apply<A, B>(K<TryT<M>, Func<A, B>> mf, Memo<TryT<M>, A> ma) =>\n        new TryT<M, B>(mf.As().runTry.Bind(\n                           mf1 => ma.Value.As().runTry.Bind(\n                               ma1 => M.Pure(mf1.Apply(ma1)))));\n\n    static K<TryT<M>, A> MonadT<TryT<M>, M>.Lift<A>(K<M, A> ma) => \n        TryT.lift(ma);\n    \n    static K<TryT<M>, A> MonadIO<TryT<M>>.LiftIO<A>(IO<A> ma) => \n        TryT.liftIOMaybe<M, A>(ma);\n\n    static K<TryT<M>, A> Alternative<TryT<M>>.Empty<A>() =>\n        TryT.Fail<M, A>(Error.Empty);\n\n    static K<TryT<M>, A> Choice<TryT<M>>.Choose<A>(K<TryT<M>, A> ma, K<TryT<M>, A> mb) =>\n        new TryT<M, A>(ma.Run().Bind(\n                           lhs => lhs switch\n                                  {\n                                      Fin<A>.Succ (var x) => M.Pure(Try.Succ(x)),\n                                      Fin<A>.Fail         => mb.As().runTry,\n                                      _                      => throw new NotSupportedException()\n                                  }));\n\n    static K<TryT<M>, A> Choice<TryT<M>>.Choose<A>(K<TryT<M>, A> ma, Memo<TryT<M>, A> mb) => \n        new TryT<M, A>(ma.Run().Bind(\n                           lhs => lhs switch\n                                  {\n                                      Fin<A>.Succ (var x) => M.Pure(Try.Succ(x)),\n                                      Fin<A>.Fail         => mb.Value.As().runTry,\n                                      _                      => throw new NotSupportedException()\n                                  }));\n\n    static K<TryT<M>, A> Fallible<Error, TryT<M>>.Fail<A>(Error error) =>\n        TryT.Fail<M, A>(error);\n\n    static K<TryT<M>, A> Fallible<Error, TryT<M>>.Catch<A>(\n        K<TryT<M>, A> fa,\n        Func<Error, bool> Predicate,\n        Func<Error, K<TryT<M>, A>> Fail) =>\n        fa.As().BindFail(e => Predicate(e) ? Fail(e).As() : TryT.Fail<M, A>(e));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/TryT.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class TryT\n{\n    /// <summary>\n    /// Lift a pure success value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, A> Succ<M, A>(A value) \n        where M : Monad<M> => \n        lift(M.Pure(value));\n\n    /// <summary>\n    /// Lift a fail value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, A> Fail<M, A>(Error value)  \n        where M : Monad<M> => \n        lift<M, A>(Fin.Fail<A>(value));\n    \n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, A> lift<M, A>(K<M, A> ma) \n        where M : Monad<M> => \n        new(M.Map(Try.Succ, ma));\n\n    /// <summary>\n    /// Lifts a given lazy-value into the transformer\n    /// </summary>\n    /// <param name=\"f\">Lazy value to lift</param>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, A> lift<M, A>(Func<Fin<A>> f)  \n        where M : Monad<M> => \n        new(M.Pure(Try.lift(f)));\n\n    /// <summary>\n    /// Lifts a given value into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, A> lift<M, A>(Fin<A> ma)  \n        where M : Monad<M> => \n        new(M.Pure(Try.lift(ma)));\n\n    /// <summary>\n    /// Lifts a given value into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, A> lift<M, A>(Pure<A> ma)  \n        where M : Monad<M> => \n        Succ<M, A>(ma.Value);\n\n    /// <summary>\n    /// Lifts a given value into the transformer\n    /// </summary>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, A> lift<M, A>(Fail<Error> ma)  \n        where M : Monad<M> => \n        lift<M, A>(Fin.Fail<A>(ma.Value));\n\n    /// <summary>\n    /// Lifts a given `IO` monad into the `TryT` transformer\n    /// </summary>\n    /// <param name=\"ma\">IO monad to lift</param>\n    /// <returns>`TryT`</returns>\n    public static TryT<M, A> liftIO<M, A>(IO<A> ma)   \n        where M : MonadIO<M> => \n        new(M.LiftIO(ma.Try().Run()).Map(Try.lift));\n\n    /// <summary>\n    /// Lifts a given `IO` monad into the `TryT` transformer\n    /// </summary>\n    /// <param name=\"ma\">IO monad to lift</param>\n    /// <returns>`TryT`</returns>\n    internal static TryT<M, A> liftIOMaybe<M, A>(IO<A> ma)   \n        where M : Monad<M> => \n        new(M.LiftIOMaybe(ma.Try().Run()).Map(Try.lift));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/TryT/TryT.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `TryT` monad transformer, which allows for an  optional `Error` result and catches exceptions,\n/// converting them to `Error`. \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record TryT<M, A>(K<M, Try<A>> runTry) : \n    K<TryT<M>, A>\n    where M : Monad<M>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Match\n    //\n\n    /// <summary>\n    /// Match the bound value and return a result (which gets packages back up inside the inner monad)\n    /// </summary>\n    /// <param name=\"Succ\">Success branch</param>\n    /// <param name=\"Fail\">Fail branch</param>\n    /// <returns>Inner monad with the result of the `Succ` or `Fail` branches</returns>\n    public K<M, B> Match<B>(Func<A, B> Succ, Func<Error, B> Fail) =>\n        M.Map(mx => mx.Match(Succ, Fail), this.Run());\n\n    /// <summary>\n    /// Match the bound value and return a result (which gets packages back up inside the inner monad)\n    /// </summary>\n    /// <param name=\"Succ\">Success branch</param>\n    /// <param name=\"Fail\">Fail branch</param>\n    /// <returns>Inner monad with the result of the `Succ` or `Fail` branches</returns>\n    public K<M, A> IfFail(Func<Error, A> Fail) =>\n        Match(identity, Fail);\n\n    /// <summary>\n    /// Match the bound value and return a result (which gets packages back up inside the inner monad)\n    /// </summary>\n    /// <param name=\"Succ\">Success branch</param>\n    /// <param name=\"Fail\">Fail branch</param>\n    /// <returns>Inner monad with the result of the `Succ` or `Fail` branches</returns>\n    public K<M, A> IfFailM(Func<Error, K<M, A>> Fail) =>\n        Match(M.Pure, Fail).Flatten();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M1\">Target monad type</typeparam>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Mapped monad</returns>\n    public TryT<M1, B> MapT<M1, B>(Func<K<M, Fin<A>>, K<M1, Fin<B>>> f)\n        where M1 : Monad<M1> =>\n        new(f(this.Run()).Map(Try.lift));\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, B> Map<B>(Func<A, B> f) =>\n        new(M.Map(mx => mx.Map(f), runTry));\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`TryT`</returns>\n    public TryT<M, A> MapFail(Func<Error, Error> f) =>\n        new(M.Map(mx => mx.MapFail(f), runTry));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, B> Select<B>(Func<A, B> f) =>\n        new(M.Map(mx => mx.Map(f), runTry));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, B> Bind<B>(Func<A, K<TryT<M>, B>> f) =>\n        Map(f).Flatten();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, B> Bind<B>(Func<A, TryT<M, B>> f) =>\n        Map(f).Flatten();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"Succ\">Success mapping function</param>\n    /// <param name=\"Fail\">Failure mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, B> BiBind<B>(Func<A, TryT<M, B>> Succ, Func<Error, TryT<M, B>> Fail) =>\n        new (runTry.Bind(\n                 ta => ta.runTry()\n                         .Match(Succ: Succ, Fail: Fail)\n                         .runTry));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"Fail\">Failure mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, A> BindFail(Func<Error, TryT<M, A>> Fail) =>\n        BiBind(TryT.Succ<M, A>, Fail);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(a => f(a).Value);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, C> SelectMany<B, C>(Func<A, K<TryT<M>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, C> SelectMany<B, C>(Func<A, TryT<M, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => TryT.lift(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, C> SelectMany<B, C>(Func<A, Fin<B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => TryT.lift<M, B>(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`TryT`</returns>\n    public TryT<M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n\n    public static implicit operator TryT<M, A>(Pure<A> ma) =>\n        TryT.Succ<M, A>(ma.Value);\n    \n    public static implicit operator TryT<M, A>(Error ma) =>\n        TryT.lift<M, A>(Fin.Fail<A>(ma));\n    \n    public static implicit operator TryT<M, A>(Fail<Error> ma) =>\n        TryT.lift<M, A>(Fin.Fail<A>(ma.Value));\n    \n    public static implicit operator TryT<M, A>(Fail<Exception> ma) =>\n        TryT.lift<M, A>(Fin.Fail<A>(ma.Value));\n    \n    public static implicit operator TryT<M, A>(IO<A> ma) =>\n        TryT.liftIOMaybe<M, A>(ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Extensions/Validation.Extensions.Apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Validation<F, B> Action<F, A, B>(this K<Validation<F>, A> ma, K<Validation<F>, B> mb) \n        where F : Semigroup<F> =>\n        ActionI(ma, mb, F.Instance).As();\n\n    /// <summary>\n    /// Applicative-functor apply-operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Validation<F, B> Apply<F, A, B>(this K<Validation<F>, Func<A, B>> mf, K<Validation<F>, A> ma)\n        where F : Semigroup<F> =>\n        ApplyI(mf, ma, F.Instance).As();\n\n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    internal static Validation<F, B> ActionI<F, A, B>(\n        this K<Validation<F>, A> ma,\n        K<Validation<F>, B> mb,\n        Option<SemigroupInstance<F>> trait) =>\n        trait switch\n        {\n            { IsSome: true, Value: { } semigroup } =>\n                ma switch\n                {\n                    Validation<F, A>.Success =>\n                        mb.As(),\n\n                    Validation<F, A>.Fail (var e1) =>\n                        mb switch\n                        {\n                            Validation<F, B>.Fail (var e2) =>\n                                Validation.FailI<F, B>(semigroup.Combine(e1, e2)),\n\n                            _ =>\n                                Validation.FailI<F, B>(e1)\n                        },\n                    _ => throw new NotSupportedException()\n                },\n\n            _ =>\n                ma switch\n                {\n                    Validation<F, A>.Success       => mb.As(),\n                    Validation<F, A>.Fail (var e1) => Validation.FailI<F, B>(e1),\n                    _                              => throw new NotSupportedException()\n                }\n        };\n\n    /// <summary>\n    /// Applicative-functor apply-operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    internal static Validation<F, B> ApplyI<F, A, B>(\n        this K<Validation<F>, Func<A, B>> mf, \n        K<Validation<F>, A> ma,\n        Option<SemigroupInstance<F>> trait) =>\n        trait switch\n        {\n            { IsSome: true, Value: { } semigroup } =>\n                mf switch\n                {\n                    Validation<F, Func<A, B>>.Success (var f) =>\n                        ma switch\n                        {\n                            Validation<F, A>.Success (var a) =>\n                                Validation.SuccessI<F, B>(f(a)),\n\n                            Validation<F, A>.Fail (var e) =>\n                                Validation.FailI<F, B>(e),\n\n                            _ => throw new NotSupportedException()\n                        },\n\n                    Validation<F, Func<A, B>>.Fail (var e1) =>\n                        ma switch\n                        {\n                            Validation<F, A>.Fail (var e2) =>\n                                Validation.FailI<F, B>(semigroup.Combine(e1, e2)),\n\n                            _ =>\n                                Validation.FailI<F, B>(e1)\n\n                        },\n\n                    _ => throw new NotSupportedException()\n                },\n\n            _ => mf switch\n                 {\n                     Validation<F, Func<A, B>>.Success (var f) =>\n                         ma switch\n                         {\n                             Validation<F, A>.Success (var a) =>\n                                 Validation.SuccessI<F, B>(f(a)),\n\n                             Validation<F, A>.Fail (var e) =>\n                                 Validation.FailI<F, B>(e),\n\n                             _ => throw new NotSupportedException()\n                         },\n\n                     Validation<F, Func<A, B>>.Fail (var e1) =>\n                         Validation.FailI<F, B>(e1),\n\n                     _ => throw new NotSupportedException()\n                 }\n        };\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Extensions/Validation.Extensions.Map.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Validation<F, B> Map<F, A, B>(this Func<A, B> f, K<Validation<F>, A> ma) => \n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Validation<F, B> Map<F, A, B>(this Func<A, B> f, Validation<F, A> ma) \n        where F : Monoid<F> =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Extensions/Validation.Extensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    [Pure]\n    public static Validation<F, A> As<F, A>(this K<Validation<F>, A> ma) =>\n        (Validation<F, A>)ma;\n    \n    [Pure]\n    public static Validation<F, A> As2<F, A>(this K<Validation, F, A> ma) =>\n        (Validation<F, A>)ma;\n\n    [Pure]\n    public static Validation<F, A> Combine<F, A>(this K<Validation<F>, A> lhs, K<Validation<F>, A> rhs)\n        where F : Semigroup<F> =>\n        lhs.As().CombineFirst(rhs.As(), F.Instance);        \n\n    [Pure]\n    public static Validation<F, A> Choose<F, A>(this K<Validation<F>, A> lhs, K<Validation<F>, A> rhs) =>\n        Choice.choose(lhs, rhs).As();\n\n    /// <summary>\n    /// Match Success and return a context.  You must follow this with `.Fail(...)` to complete the match\n    /// </summary>\n    /// <param name=\"success\">Action to invoke if in a Success state</param>\n    /// <returns>Context that must have `Fail()` called upon it.</returns>\n    [Pure]\n    public static ValidationUnitContext<F, A> Success<F, A>(this K<Validation<F>, A> ma, Action<A> success) =>\n        new (ma.As(), success);\n\n    /// <summary>\n    /// Match Success and return a context.  You must follow this with `.Fail(...)` to complete the match\n    /// </summary>\n    /// <param name=\"success\">Action to invoke if in a Success state</param>\n    /// <returns>Context that must have `Fail()` called upon it.</returns>\n    [Pure]\n    public static ValidationContext<F, A, B> Success<F, A, B>(this K<Validation<F>, A> ma, Func<A, B> success) =>\n        new (ma.As(), success);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Validation<F, A> Flatten<F, A>(this Validation<F, Validation<F, A>> mma) =>\n        mma.Bind(x => x);\n\n    /// <summary>\n    /// Filter the Validation\n    /// </summary>\n    /// <remarks>\n    /// If the predicate returns `false`, then the `Validation` goes into a failed state using `Monoid.Empty` of `F` as\n    /// its failure value.\n    /// </remarks>\n    [Pure]\n    public static Validation<F, A> Filter<F, A>(this K<Validation<F>, A> ma, Func<A, bool> pred) \n        where F : Monoid<F> =>\n        ma.As().Bind(x => pred(x)\n                              ? Validation.Success<F, A>(x)\n                              : Validation.Fail<F, A>(F.Empty));\n\n    /// <summary>\n    /// Filter the Validation\n    /// </summary>\n    /// <remarks>\n    /// If the predicate returns `false`, then the `Validation` goes into a failed state using `Monoid.Empty` of `F` as\n    /// its failure value.\n    /// </remarks>\n    [Pure]\n    public static Validation<F, A> Where<F, A>(this K<Validation<F>, A> ma, Func<A, bool> pred) \n        where F : Monoid<F> =>\n        ma.Filter(pred);\n    \n    /// <summary>\n    /// Extract only the successes \n    /// </summary>\n    /// <param name=\"vs\">Enumerable of validations</param>\n    /// <typeparam name=\"F\">Fail type</typeparam>\n    /// <typeparam name=\"S\">Success type</typeparam>\n    /// <returns>Enumerable of successes</returns>\n    [Pure]\n    public static IEnumerable<S> Successes<F, S>(this IEnumerable<Validation<F, S>> vs)\n    {\n        foreach (var v in vs)\n        {\n            if (v.IsSuccess) yield return (S)v;\n        }\n    }\n\n    /// <summary>\n    /// Extract only the failures \n    /// </summary>\n    /// <param name=\"vs\">Enumerable of validations</param>\n    /// <typeparam name=\"F\">Fail type</typeparam>\n    /// <typeparam name=\"S\">Success type</typeparam>\n    /// <returns>Enumerable of failures</returns>\n    [Pure]\n    public static IEnumerable<F> Fails<F, S>(this IEnumerable<Validation<F, S>> vs)\n    {\n        foreach (var v in vs)\n        {\n            if (v.IsFail) yield return (F)v;\n        }\n    }\n    \n    /// <summary>\n    /// Extract only the successes \n    /// </summary>\n    /// <param name=\"vs\">Seq of validations</param>\n    /// <typeparam name=\"F\">Fail type</typeparam>\n    /// <typeparam name=\"S\">Success type</typeparam>\n    /// <returns>Enumerable of successes</returns>\n    [Pure]\n    public static Seq<S> Successes<F, S>(this Seq<Validation<F, S>> vs) =>\n        toSeq(Successes(vs.AsEnumerable()));\n    \n    /// <summary>\n    /// Extract only the failures \n    /// </summary>\n    /// <param name=\"vs\">Seq of validations</param>\n    /// <typeparam name=\"F\">Fail type</typeparam>\n    /// <typeparam name=\"S\">Success type</typeparam>\n    /// <returns>Enumerable of failures</returns>\n    [Pure]\n    public static Seq<F> Fails<F, S>(this Seq<Validation<F, S>> vs) =>\n        toSeq(Fails(vs.AsEnumerable()));\n\n    /// <summary>\n    /// Convert `Validation` type to `Fin` type.\n    /// </summary>\n    [Pure]\n    public static Fin<A> ToFin<A>(this Validation<Error, A> ma) =>\n        ma switch\n        {\n            Validation<Error, A>.Success (var x) => new Fin<A>.Succ(x),\n            Validation<Error, A>.Fail (var x)    => new Fin<A>.Fail(x),\n            _                                    => throw new NotSupportedException()\n        };\n\n\n    /// <summary>\n    /// If any items are `Fail`, then the errors are collected and returned.  If they all pass, then the Success values\n    /// are collected into a `Seq`.  \n    /// </summary>\n    /// <exception cref=\"TypeLoadException\">\n    /// <para>\n    /// Any `TypeLoadException` thrown is because the `F` type used does not derive from `Semigroup〈F〉`.\n    /// This is a runtime error rather than a compile-time constraint error because we're resolving the `Semigroup〈F〉`\n    /// trait ad hoc.\n    /// </para>\n    /// <para>\n    /// That means we delay finding out that the provided `F` type isn't compatible for `Validation〈F, A〉`.  That is\n    /// annoying, we would prefer compile-time constraints, of course, but it enables much more freedom to implement the\n    /// `Coproduct`, `Bifunctor`, and `Bimonad` traits which, in turn, give additional functionality for free (like\n    /// `Partition`).\n    /// </para>\n    /// <para>\n    /// Implementation of those traits would not be possible if we were to add compile-time constraints to `F`.  So, the\n    /// resolution of any type-exception thrown is to only use `Semigroup〈F〉` deriving types for `F`.\n    /// </para> \n    /// </exception>\n    [Pure]\n    internal static Validation<F, A> CombineFirst<F, A>(\n        this Validation<F, A> lhs,\n        Validation<F, A> rhs,\n        Option<SemigroupInstance<F>> trait) =>\n        trait switch\n        {\n            { IsSome: true, Case: SemigroupInstance<F> semi } =>\n                (lhs, rhs) switch\n                {\n                    ({ IsSuccess: true }, { IsSuccess: true }) =>\n                        lhs,\n\n                    ({ IsFail: true }, { IsFail: true }) =>\n                        semi.Combine(lhs.FailValue, rhs.FailValue),\n\n                    ({ IsFail: true }, _) =>\n                        lhs.FailValue,\n\n                    _ =>\n                        rhs.FailValue\n                },\n\n            _ => (lhs, rhs) switch\n                 {\n                     ({ IsSuccess: true }, _) => lhs,\n                     _                        => rhs\n                 }\n        };\n\n    /// <summary>\n    /// If any items are `Fail`, then the errors are collected and returned.  If they all pass, then the Success values\n    /// are collected into a `Seq`.  \n    /// </summary>\n    /// <exception cref=\"TypeLoadException\">\n    /// <para>\n    /// Any `TypeLoadException` thrown is because the `F` type used does not derive from `Semigroup〈F〉`.\n    /// This is a runtime error rather than a compile-time constraint error because we're resolving the `Semigroup〈F〉`\n    /// trait ad hoc.\n    /// </para>\n    /// <para>\n    /// That means we delay finding out that the provided `F` type isn't compatible for `Validation〈F, A〉`.  That is\n    /// annoying, we would prefer compile-time constraints, of course, but it enables much more freedom to implement the\n    /// `Coproduct`, `Bifunctor`, and `Bimonad` traits which, in turn, give additional functionality for free (like\n    /// `Partition`).\n    /// </para>\n    /// <para>\n    /// Implementation of those traits would not be possible if we were to add compile-time constraints to `F`.  So, the\n    /// resolution of any type-exception thrown is to only use `Semigroup〈F〉` deriving types for `F`.\n    /// </para> \n    /// </exception>\n    [Pure]\n    internal static Validation<F, Seq<A>> CombineI<F, A>(\n        this Validation<F, A> lhs,\n        Validation<F, A> rhs,\n        Option<SemigroupInstance<F>> trait) =>\n        trait switch\n        {\n            { IsSome: true, Case: SemigroupInstance<F> semi } =>\n                (lhs, rhs) switch\n                {\n                    ({ IsSuccess: true }, { IsSuccess: true }) =>\n                        Validation.SuccessI<F, Seq<A>>([lhs.SuccessValue, rhs.SuccessValue]),\n\n                    ({ IsFail: true }, { IsFail: true }) =>\n                        semi.Combine(lhs.FailValue, rhs.FailValue),\n\n                    ({ IsFail: true }, _) =>\n                        lhs.FailValue,\n\n                    _ =>\n                        rhs.FailValue\n                },\n            _ => (lhs, rhs) switch\n                 {\n                     ({ IsSuccess: true, SuccessValue: var x }, { IsSuccess: true, SuccessValue: var y }) => Seq(x, y),\n                     ({ IsSuccess: false, FailValue : var lf }, _) => lf,\n                     (_, { IsSuccess: false, FailValue : var rf }) => rf\n                 }\n        };\n\n    /// <summary>\n    /// If any items are `Fail`, then the errors are collected and returned.  If they all pass, then the Success values\n    /// are collected into a `Seq`.  \n    /// </summary>\n    /// <exception cref=\"TypeLoadException\">\n    /// <para>\n    /// Any `TypeLoadException` thrown is because the `F` type used does not derive from `Semigroup〈F〉`.\n    /// This is a runtime error rather than a compile-time constraint error because we're resolving the `Semigroup〈F〉`\n    /// trait ad hoc.\n    /// </para>\n    /// <para>\n    /// That means we delay finding out that the provided `F` type isn't compatible for `Validation〈F, A〉`.  That is\n    /// annoying, we would prefer compile-time constraints, of course, but it enables much more freedom to implement the\n    /// `Coproduct`, `Bifunctor`, and `Bimonad` traits which, in turn, give additional functionality for free (like\n    /// `Partition`).\n    /// </para>\n    /// <para>\n    /// Implementation of those traits would not be possible if we were to add compile-time constraints to `F`.  So, the\n    /// resolution of any type-exception thrown is to only use `Semigroup〈F〉` deriving types for `F`.\n    /// </para> \n    /// </exception>\n    [Pure]\n    public static Validation<F, Seq<A>> CombineI<F, A>(\n        this Validation<F, Seq<A>> lhs,\n        Validation<F, A> rhs,\n        Option<SemigroupInstance<F>> trait) =>\n        trait switch\n        {\n            { IsSome: true, Case: SemigroupInstance<F> semi } =>\n                (lhs, rhs) switch\n                {\n                    ({ IsSuccess: true }, { IsSuccess: true }) =>\n                        Validation.SuccessI<F, Seq<A>>(lhs.SuccessValue.Add(rhs.SuccessValue)),\n\n                    ({ IsFail: true }, { IsFail: true }) =>\n                        semi.Combine(lhs.FailValue, rhs.FailValue),\n\n                    ({ IsFail: true }, _) =>\n                        lhs.FailValue,\n\n                    _ =>\n                        rhs.FailValue\n                },\n            _ => (lhs, rhs) switch\n                 {\n                     ({ IsSuccess: true, SuccessValue: var xs }, { IsSuccess: true, SuccessValue: var y }) => xs.Add(y),\n                     ({ IsSuccess: false, FailValue : var lf }, _) => lf,\n                     (_, { IsSuccess: false, FailValue : var rf }) => rf\n                 }\n        };\n\n    /// <summary>\n    /// If any items are `Fail`, then the errors are collected and returned.  If they all pass, then the Success values\n    /// are collected into a `Seq`.  \n    /// </summary>\n    /// <exception cref=\"TypeLoadException\">\n    /// <para>\n    /// Any `TypeLoadException` thrown is because the `F` type used does not derive from `Semigroup〈F〉`.\n    /// This is a runtime error rather than a compile-time constraint error because we're resolving the `Semigroup〈F〉`\n    /// trait ad hoc.\n    /// </para>\n    /// <para>\n    /// That means we delay finding out that the provided `F` type isn't compatible for `Validation〈F, A〉`.  That is\n    /// annoying, we would prefer compile-time constraints, of course, but it enables much more freedom to implement the\n    /// `Coproduct`, `Bifunctor`, and `Bimonad` traits which, in turn, give additional functionality for free (like\n    /// `Partition`).\n    /// </para>\n    /// <para>\n    /// Implementation of those traits would not be possible if we were to add compile-time constraints to `F`.  So, the\n    /// resolution of any type-exception thrown is to only use `Semigroup〈F〉` deriving types for `F`.\n    /// </para> \n    /// </exception>\n    [Pure]\n    internal static Validation<F, Seq<A>> CombineI<F, A>(\n        this Validation<F, A> lhs,\n        Validation<F, Seq<A>> rhs,\n        Option<SemigroupInstance<F>> trait) =>\n        trait switch\n        {\n            { IsSome: true, Case: SemigroupInstance<F> semi } =>\n                (lhs, rhs) switch\n                {\n                    ({ IsSuccess: true }, { IsSuccess: true }) =>\n                        Validation.SuccessI<F, Seq<A>>(lhs.SuccessValue.Cons(rhs.SuccessValue)),\n\n                    ({ IsFail: true }, { IsFail: true }) =>\n                        semi.Combine(lhs.FailValue, rhs.FailValue),\n\n                    ({ IsFail: true }, _) =>\n                        lhs.FailValue,\n\n                    _ =>\n                        rhs.FailValue\n                },\n            _ => (lhs, rhs) switch\n                 {\n                     ({ IsSuccess: true, SuccessValue: var x }, { IsSuccess: true, SuccessValue: var ys }) => x.Cons(ys),\n                     ({ IsSuccess: false, FailValue : var lf }, _) => lf,\n                     (_, { IsSuccess: false, FailValue : var rf }) => rf\n                 }\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Extensions/Validation.Guard.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class ValidationGuardExtensions\n{\n    /// <summary>\n    /// Natural transformation to `Validation`\n    /// </summary>\n    public static Validation<F, Unit> ToValidation<F>(this Guard<F, Unit> guard) \n        where F : Monoid<F> =>\n        guard.Flag\n            ? Validation.Success<F, Unit>(default)\n            : Validation.Fail<F, Unit>(guard.OnFalse());\n \n    /// <summary>\n    /// Natural transformation to `Validation`\n    /// </summary>\n    internal static Validation<F, Unit> ToValidationI<F>(this Guard<F, Unit> guard) =>\n        guard.Flag\n            ? Validation.SuccessI<F, Unit>(default)\n            : Validation.FailI<F, Unit>(guard.OnFalse());\n \n    /// <summary>\n    /// Monadic binding support for `Validation`\n    /// </summary>\n    public static Validation<F, B> Bind<F, B>(\n        this Guard<F, Unit> guard,\n        Func<Unit, Validation<F, B>> f) \n        where F : Monoid<F> =>\n        guard.Flag\n            ? f(default).As()\n            : Validation.Fail<F, B>(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `Validation`\n    /// </summary>\n    public static Validation<F, C> SelectMany<F, B, C>(\n        this Guard<F, Unit> guard,\n        Func<Unit, Validation<F, B>> bind, \n        Func<Unit, B, C> project) \n        where F : Monoid<F> =>\n        guard.Flag\n            ? bind(default).As().Map(b => project(default, b))\n            : Validation.Fail<F, C>(guard.OnFalse());    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Operators/Validation.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    extension<F, A, B>(K<Validation<F>, A> self)\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Validation<F, B> operator >>> (K<Validation<F>, A> ma, K<Validation<F>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<F, B> operator * (K<Validation<F>, Func<A, B>> mf, K<Validation<F>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<F, B> operator * (K<Validation<F>, A> ma, K<Validation<F>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<F, A, B, C>(K<Validation<F>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<F, Func<B, C>> operator * (\n            K<Validation<F>, Func<A, B, C>> mf, \n            K<Validation<F>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<F, Func<B, C>> operator * (\n            K<Validation<F>, A> ma,\n            K<Validation<F>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<F, A, B, C, D>(K<Validation<F>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<F, Func<B, Func<C, D>>> operator * (\n            K<Validation<F>, Func<A, B, C, D>> mf, \n            K<Validation<F>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<F, Func<B, Func<C, D>>> operator * (\n            K<Validation<F>, A> ma,\n            K<Validation<F>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<F, A, B, C, D, E>(K<Validation<F>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<F, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Validation<F>, Func<A, B, C, D, E>> mf, \n            K<Validation<F>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<F, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Validation<F>, A> ma,\n            K<Validation<F>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<FF, A, B, C, D, E, F>(K<Validation<FF>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Validation<FF>, Func<A, B, C, D, E, F>> mf, \n            K<Validation<FF>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            K<Validation<FF>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<FF, A, B, C, D, E, F, G>(K<Validation<FF>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Validation<FF>, Func<A, B, C, D, E, F, G>> mf, \n            K<Validation<FF>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            K<Validation<FF>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<FF, A, B, C, D, E, F, G, H>(K<Validation<FF>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Validation<FF>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Validation<FF>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            K<Validation<FF>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<FF, A, B, C, D, E, F, G, H, I>(K<Validation<FF>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Validation<FF>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Validation<FF>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            K<Validation<FF>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<FF, A, B, C, D, E, F, G, H, I, J>(K<Validation<FF>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Validation<FF>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Validation<FF>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            K<Validation<FF>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<FF, A, B, C, D, E, F, G, H, I, J, K>(K<Validation<FF>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Validation<FF>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Validation<FF>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Validation<FF>, A> ma,\n            K<Validation<FF>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Operators/Validation.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    extension<F, A>(K<Validation<F>, A> self)\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, A> operator |(K<Validation<F>, A> lhs, K<Validation<F>, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, A> operator |(K<Validation<F>, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(Validation.SuccessI<F, A>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Operators/Validation.Operators.Combine.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    extension<F, A>(K<Validation<F>, A> self)\n        where F : Semigroup<F>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, A> operator +(K<Validation<F>, A> lhs, K<Validation<F>, A> rhs) =>\n            +lhs.Combine(rhs);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, A> operator +(K<Validation<F>, A> lhs, Pure<A> rhs) =>\n            +lhs.Combine(Validation.SuccessI<F, A>(rhs.Value));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, A> operator +(K<Validation<F>, A> lhs, Fail<F> rhs) =>\n            +lhs.Combine(Validation.FailI<F, A>(rhs.Value));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, A> operator +(K<Validation<F>, A> lhs, F rhs) =>\n            +lhs.Combine(Validation.FailI<F, A>(rhs));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Operators/Validation.Operators.CombineSeq.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    extension<F, A>(K<Validation<F>, A> self)\n        where F : Semigroup<F>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, Seq<A>> operator &(K<Validation<F>, A> lhs, K<Validation<F>, A> rhs) =>\n            (+lhs).CombineI(+rhs, F.Instance);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, Seq<A>> operator &(K<Validation<F>, A> lhs, Pure<A> rhs) =>\n            (+lhs).CombineI(Validation.SuccessI<F, A>(rhs.Value), F.Instance);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, Seq<A>> operator &(K<Validation<F>, A> lhs, Fail<F> rhs) =>\n            (+lhs).CombineI(Validation.FailI<F, A>(rhs.Value), F.Instance);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Validation<F, Seq<A>> operator &(K<Validation<F>, A> lhs, F rhs) =>\n            (+lhs).CombineI(Validation.FailI<F, A>(rhs), F.Instance);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Operators/Validation.Operators.Fallible.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    extension<F, A>(K<Validation<F>, A> self)\n    {\n        public static Validation<F, A> operator |(K<Validation<F>, A> lhs, CatchM<F, Validation<F>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static Validation<F, A> operator |(K<Validation<F>, A> lhs, Fail<F> rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Operators/Validation.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    extension<FF, A, B>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, B> operator *(Func<A, B> f, K<Validation<FF>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, B> operator *(K<Validation<FF>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<FF, A, B, C>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, C>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<FF, A, B, C, D>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, D>>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<FF, A, B, C, D, E>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<FF, A, B, C, D, E, F>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<FF, A, B, C, D, E, F, G>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<FF, A, B, C, D, E, F, G, H>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<FF, A, B, C, D, E, F, G, H, I>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<FF, A, B, C, D, E, F, G, H, I, J>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<FF, A, B, C, D, E, F, G, H, I, J, K>(K<Validation<FF>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Validation<FF>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Validation<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Validation<FF>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Operators/Validation.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    extension<F, A, B>(K<Validation<F>, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Validation<F, B> operator >> (K<Validation<F>, A> ma, Func<A, K<Validation<F>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Validation<F, B> operator >> (K<Validation<F>, A> lhs, K<Validation<F>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<F, A>(K<Validation<F>, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Validation<F, A> operator >> (K<Validation<F>, A> lhs, K<Validation<F>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Operators/Validation.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationExtensions\n{\n    extension<F, A>(K<Validation<F>, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Validation<F ,A> operator +(K<Validation<F>, A> ma) =>\n            (Validation<F, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Validation<F, A> operator >> (K<Validation<F>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Prelude/Validation.Prelude.apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Validation<F, B> action<F, A, B>(K<Validation<F>, A> ma, K<Validation<F>, B> mb)\n        where F : Semigroup<F> =>\n        ma.Action(mb);\n\n    /// <summary>\n    /// Applicative-functor apply-operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Validation<F, B> apply<F, A, B>(K<Validation<F>, Func<A, B>> mf, K<Validation<F>, A> ma) \n        where F : Semigroup<F> =>\n        mf.Apply(ma);\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Prelude/Validation.Prelude.cs",
    "content": "﻿\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Represents a successful operation\n    /// </summary>\n    /// <typeparam name=\"F\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"value\">Value</param>\n    /// <returns>Validation applicative</returns>\n    public static Validation<F, A> Success<F, A>(A value) \n        where F : Monoid<F> =>\n        new Validation<F, A>.Success(value);\n\n    /// <summary>\n    /// Represents a failed operation\n    /// </summary>\n    /// <typeparam name=\"F\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"value\">Error value</param>\n    /// <returns>Validation applicative</returns>\n    public static Validation<F, A> Fail<F, A>(F value) \n        where F : Monoid<F> =>\n        new Validation<F, A>.Fail(value);\n\n    /// <summary>\n    /// Represents a failed operation\n    /// </summary>\n    /// <typeparam name=\"F\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"value\">Error value</param>\n    /// <returns>Validation applicative</returns>\n    public static Validation<F, A> Fail<F, A>(Seq<F> values)\n        where F : Monoid<F> =>\n        new Validation<F, A>.Fail(Monoid.combine(values));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Prelude/Validation.Prelude.map.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Validation<F, B> map<F, A, B>(Func<A, B> f, K<Validation<F>, A> ma) =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Trait/Validation.TraitImpl.2.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Validation :\n    Coproduct<Validation>,\n    Bimonad<Validation>\n{\n    static K<Validation, A, B> CoproductCons<Validation>.Left<A, B>(A value) => \n        FailI<A, B>(value);\n\n    static K<Validation, A, B> CoproductCons<Validation>.Right<A, B>(B value) => \n        SuccessI<A, B>(value);\n\n    static C Coproduct<Validation>.Match<A, B, C>(\n        Func<A, C> Left, \n        Func<B, C> Right, \n        K<Validation, A, B> fab) => \n        fab.As2().Match(Fail: Left, Succ: Right);\n\n    static K<Validation, M, B> Bifunctor<Validation>.BiMap<L, A, M, B>(\n        Func<L, M> first, \n        Func<A, B> second, \n        K<Validation, L, A> fab) => \n        fab.As2().BiMap(Succ: second, Fail: first);\n\n    static K<Validation, Y, A> Bimonad<Validation>.BindFirst<X, Y, A>(\n        K<Validation, X, A> ma, \n        Func<X, K<Validation, Y, A>> f) => \n        ma.As2().BiBind(x => f(x).As2(), SuccessI<Y, A>);\n\n    static K<Validation, X, B> Bimonad<Validation>.BindSecond<X, A, B>(K<Validation, X, A> ma, Func<A, K<Validation, X, B>> f) => \n        ma.As2().BiBind(FailI<X, B>, x => f(x).As2());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Trait/Validation.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `Validation` \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class Validation<FAIL> :\n    Monad<Validation<FAIL>>,\n    MonoidK<Validation<FAIL>>,\n    Alternative<Validation<FAIL>>,\n    Traversable<Validation<FAIL>>,\n    Fallible<FAIL, Validation<FAIL>>\n{\n    static K<Validation<FAIL>, B> Monad<Validation<FAIL>>.Bind<A, B>(\n        K<Validation<FAIL>, A> ma,\n        Func<A, K<Validation<FAIL>, B>> f) =>\n        ma switch\n        {\n            Validation<FAIL, A>.Success (var x) => f(x),\n            Validation<FAIL, A>.Fail (var e)    => Validation.FailI<FAIL, B>(e),\n            _                                   => throw new NotSupportedException()\n        };\n\n    static K<Validation<FAIL>, B> Monad<Validation<FAIL>>.Recur<A, B>(A value, Func<A, K<Validation<FAIL>, Next<A, B>>> f)\n    {\n        while (true)\n        {\n            var mr = +f(value);\n            if (mr.IsFail) return Validation.FailI<FAIL, B>(mr.FailValue);\n            var next = (Next<A, B>)mr;\n            if(next.IsDone) return Validation.SuccessI<FAIL, B>(next.Done);\n            value = next.Loop;\n        }\n    }\n\n    static K<Validation<FAIL>, B> Functor<Validation<FAIL>>.Map<A, B>(\n        Func<A, B> f,\n        K<Validation<FAIL>, A> ma) =>\n        ma switch\n        {\n            Validation<FAIL, A>.Success (var x) => Validation.SuccessI<FAIL, B>(f(x)),\n            Validation<FAIL, A>.Fail (var e)    => Validation.FailI<FAIL, B>(e),\n            _                                   => throw new NotSupportedException()\n        };\n\n    static K<Validation<FAIL>, A> Applicative<Validation<FAIL>>.Pure<A>(A value) =>\n        Validation.SuccessI<FAIL, A>(value);\n\n    static K<Validation<FAIL>, B> Applicative<Validation<FAIL>>.Apply<A, B>(\n        K<Validation<FAIL>, Func<A, B>> mf,\n        K<Validation<FAIL>, A> ma) =>\n        mf.ApplyI(ma, SemigroupInstance<FAIL>.Instance);\n\n    static K<Validation<FAIL>, B> Applicative<Validation<FAIL>>.Apply<A, B>(\n        K<Validation<FAIL>, Func<A, B>> mf,\n        Memo<Validation<FAIL>, A> ma) =>\n        mf.ApplyI(ma.Value, SemigroupInstance<FAIL>.Instance);\n\n    static K<Validation<FAIL>, A> Alternative<Validation<FAIL>>.Empty<A>() =>\n        MonoidInstance<FAIL>.Instance switch\n        {\n            { IsSome: true, Value: { } monoid } =>\n                Validation.FailI<FAIL, A>(monoid.Empty),\n\n            _ => throw new NotSupportedException($\"{typeof(FAIL).Name} must be a Monoid\")\n        };\n\n    static K<Validation<FAIL>, A> MonoidK<Validation<FAIL>>.Empty<A>() =>\n        MonoidInstance<FAIL>.Instance switch\n        {\n            { IsSome: true, Value: { } monoid } =>\n                Validation.FailI<FAIL, A>(monoid.Empty),\n\n            _ => throw new NotSupportedException($\"{typeof(FAIL).Name} must be a Monoid\")\n        };\n\n    static K<Validation<FAIL>, A> SemigroupK<Validation<FAIL>>.Combine<A>(\n        K<Validation<FAIL>, A> ma,\n        K<Validation<FAIL>, A> mb) =>\n        ma.As().CombineFirst(mb.As(), SemigroupInstance<FAIL>.Instance);\n\n    static K<Validation<FAIL>, A> Choice<Validation<FAIL>>.Choose<A>(\n        K<Validation<FAIL>, A> ma,\n        K<Validation<FAIL>, A> mb) =>\n        (ma, mb) switch\n        {\n            (Validation<FAIL, A>.Success, _) => ma,\n            (_, Validation<FAIL, A>.Success) => mb,\n            _                                => ma\n        };\n\n    static K<Validation<FAIL>, A> Choice<Validation<FAIL>>.Choose<A>(\n        K<Validation<FAIL>, A> ma,\n        Memo<Validation<FAIL>, A> mb) =>\n        ma switch\n        {\n            Validation<FAIL, A>.Success => ma,\n            _                           => mb.Value switch\n                                           {\n                                               Validation<FAIL, A>.Success b => b,\n                                               _ => ma\n                                           }\n        };\n    \n    static S Foldable<Validation<FAIL>>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState,\n        K<Validation<FAIL>, A> ta) =>\n        ta switch\n        {\n            Validation<FAIL, A>.Success (var x) =>\n                predicate((initialState, x))\n                    ? f(x)(initialState)\n                    : initialState,\n\n            _ => initialState\n        };\n\n    static S Foldable<Validation<FAIL>>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState,\n        K<Validation<FAIL>, A> ta) =>\n        ta switch\n        {\n            Validation<FAIL, A>.Success (var x) =>\n                predicate((initialState, x))\n                    ? f(initialState)(x)\n                    : initialState,\n\n            _ => initialState\n        };\n\n    static K<F, K<Validation<FAIL>, B>> Traversable<Validation<FAIL>>.Traverse<F, A, B>(\n        Func<A, K<F, B>> f,\n        K<Validation<FAIL>, A> ta) =>\n        ta switch\n        {\n            Validation<FAIL, A>.Success (var x) => F.Map(Succ, f(x)),\n            Validation<FAIL, A>.Fail (var e)    => F.Pure(Fail<B>(e)),\n            _                                   => throw new NotSupportedException()\n        };\n\n    static K<Validation<FAIL>, A> Succ<A>(A value) =>\n        Validation.SuccessI<FAIL, A>(value);\n\n    static K<Validation<FAIL>, A> Fail<A>(FAIL value) =>\n        Validation.FailI<FAIL, A>(value);\n\n    static K<Validation<FAIL>, A> Fallible<FAIL, Validation<FAIL>>.Fail<A>(FAIL error) =>\n        Validation.FailI<FAIL, A>(error);\n\n    static K<Validation<FAIL>, A> Fallible<FAIL, Validation<FAIL>>.Catch<A>(\n        K<Validation<FAIL>, A> fa,\n        Func<FAIL, bool> Predicate,\n        Func<FAIL, K<Validation<FAIL>, A>> Fail) =>\n        fa switch\n        {\n            Validation<FAIL, A>.Success mx => mx,\n            Validation<FAIL, A>.Fail (var e) =>\n                Predicate(e)\n                    ? Fail(e)\n                    : Validation.FailI<FAIL, A>(e),\n            _ => throw new NotSupportedException()\n        };\n\n    static Fold<A, S> Foldable<Validation<FAIL>>.FoldStep<A, S>(K<Validation<FAIL>, A> ta, S initialState)\n    {\n        var ma = ta.As();\n        return ma.IsSuccess\n                   ? Fold.Loop(initialState, ma.SuccessValue, Fold.Done<A, S>)\n                   : Fold.Done<A, S>(initialState);\n    }\n        \n    static Fold<A, S> Foldable<Validation<FAIL>>.FoldStepBack<A, S>(K<Validation<FAIL>, A> ta, S initialState) =>\n        ta.FoldStep(initialState);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Validation.Fail.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\npublic abstract partial record Validation<F, A>\n{\n    public sealed record Fail(F Value) : Validation<F, A>\n    {\n        /// <summary>\n        /// Is the Validation in a Success state?\n        /// </summary>\n        [Pure]\n        public override bool IsSuccess =>\n            false;\n\n        /// <summary>\n        /// Is the Validation in a Fail state?\n        /// </summary>\n        [Pure]\n        public override bool IsFail =>\n            true;\n\n        /// <summary>\n        /// Invokes the Success or Fail function depending on the state of the Validation\n        /// </summary>\n        /// <typeparam name=\"B\">Return type</typeparam>\n        /// <param name=\"Succ\">Function to invoke if in a Success state</param>\n        /// <param name=\"Fail\">Function to invoke if in a Fail state</param>\n        /// <returns>The return value of the invoked function</returns>\n        [Pure]\n        public override B Match<B>(Func<F, B> Fail, Func<A, B> Succ) =>\n            Fail(Value);\n\n        /// <summary>\n        /// Show the structure as a string\n        /// </summary>\n        [Pure]\n        public override string ToString() =>\n            Value is null ? \"Fail(null)\" : $\"Fail({Value})\";\n\n        /// <summary>\n        /// Get a hash code for the structure\n        /// </summary>\n        [Pure]\n        public override int GetHashCode() =>\n            Value is null ? 0 : HashableDefault<F>.GetHashCode(Value);\n\n        /// <summary>\n        /// Span of left value\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<F> FailSpan() =>\n            new([Value]);\n\n        /// <summary>\n        /// Empty span\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<A> SuccessSpan() =>\n            ReadOnlySpan<A>.Empty;\n\n        /// <summary>\n        /// Compare this structure to another to find its relative ordering\n        /// </summary>\n        [Pure]\n        public override int CompareTo<OrdF, OrdA>(Validation<F, A> other) =>\n            other switch\n            {\n                Fail l => OrdF.Compare(Value, l.Value),\n                _      => -1\n            };\n\n        /// <summary>\n        /// Equality override\n        /// </summary>\n        [Pure]\n        public override bool Equals<EqF, EqA>(Validation<F, A> other) =>\n            other switch\n            {\n                Fail l => EqF.Equals(Value, l.Value),\n                _      => false\n            };\n\n        /// <summary>\n        /// Unsafe access to the right-value \n        /// </summary>\n        /// <exception cref=\"InvalidCastException\"></exception>\n        internal override A SuccessValue =>\n            throw new InvalidCastException();\n\n        /// <summary>\n        /// Unsafe access to the left-value \n        /// </summary>\n        internal override F FailValue =>\n            Value;\n\n        /// <summary>\n        /// Maps the value in the Validation if it's in a Success state\n        /// </summary>\n        /// <typeparam name=\"F\">Fail</typeparam>\n        /// <typeparam name=\"A\">Success</typeparam>\n        /// <typeparam name=\"B\">Mapped Validation type</typeparam>\n        /// <param name=\"f\">Map function</param>\n        /// <returns>Mapped Validation</returns>\n        [Pure]\n        public override Validation<F, B> Map<B>(Func<A, B> f) =>\n            new Validation<F, B>.Fail(Value);\n\n        /// <summary>\n        /// Bi-maps the value in the Validation if it's in a Success state\n        /// </summary>\n        /// <typeparam name=\"F\">Fail</typeparam>\n        /// <typeparam name=\"A\">Success</typeparam>\n        /// <typeparam name=\"L2\">Fail return</typeparam>\n        /// <typeparam name=\"R2\">Success return</typeparam>\n        /// <param name=\"Succ\">Success map function</param>\n        /// <param name=\"Fail\">Fail map function</param>\n        /// <returns>Mapped Validation</returns>\n        [Pure]\n        public override Validation<L2, R2> BiMap<L2, R2>(Func<F, L2> Fail, Func<A, R2> Succ) =>\n            new Validation<L2, R2>.Fail(Fail(Value));\n\n        /// <summary>\n        /// Monadic bind\n        /// </summary>\n        /// <typeparam name=\"F\">Fail</typeparam>\n        /// <typeparam name=\"A\">Success</typeparam>\n        /// <typeparam name=\"B\">Resulting bound value</typeparam>\n        /// <param name=\"f\">Bind function</param>\n        /// <returns>Bound Validation</returns>\n        [Pure]\n        public override Validation<F, B> Bind<B>(Func<A, Validation<F, B>> f) =>\n            new Validation<F, B>.Fail(Value);\n\n        /// <summary>\n        /// Bi-bind.  Allows mapping of both monad states\n        /// </summary>\n        [Pure]\n        public override Validation<L2, R2> BiBind<L2, R2>(\n            Func<F, Validation<L2, R2>> Fail,\n            Func<A, Validation<L2, R2>> Succ) =>\n            Fail(Value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Validation.Module.cs",
    "content": "using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Validation\n{\n    /// <summary>\n    /// Empty failure value\n    /// </summary>\n    /// <typeparam name=\"F\">Failure type</typeparam>\n    /// <typeparam name=\"A\">Success</typeparam>\n    /// <returns>Validation structure in a failed state</returns>\n    [Pure]\n    public static Validation<F, A> Empty<F, A>()\n        where F : Monoid<F> =>\n        new Validation<F, A>.Fail(F.Empty);\n\n    /// <summary>\n    /// Represents a successful operation\n    /// </summary>\n    /// <typeparam name=\"F\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"value\">Value</param>\n    /// <returns>Validation applicative</returns>\n    [Pure]\n    public static Validation<F, A> Success<F, A>(A value)  \n        where F : Monoid<F> =>\n        new Validation<F, A>.Success(value);\n\n    /// <summary>\n    /// Represents a failed operation\n    /// </summary>\n    /// <typeparam name=\"F\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"value\">Error value</param>\n    /// <returns>Validation applicative</returns>\n    [Pure]\n    public static Validation<F, A> Fail<F, A>(F value) \n        where F : Monoid<F> =>\n        new Validation<F, A>.Fail(value);\n\n    /// <summary>\n    /// Represents a failed operation\n    /// </summary>\n    /// <typeparam name=\"F\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"value\">Error value</param>\n    /// <returns>Validation applicative</returns>\n    public static Validation<F, A> Fail<F, A>(Seq<F> values)\n        where F : Monoid<F> =>\n        new Validation<F, A>.Fail(Monoid.combine(values));    \n    \n    /// <summary>\n    /// Represents a successful operation\n    /// </summary>\n    /// <typeparam name=\"F\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"value\">Value</param>\n    /// <returns>Validation applicative</returns>\n    [Pure]\n    internal static Validation<F, A> SuccessI<F, A>(A value) => \n        new Validation<F, A>.Success(value);\n\n    /// <summary>\n    /// Represents a failed operation\n    /// </summary>\n    /// <typeparam name=\"F\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"value\">Error value</param>\n    /// <returns>Validation applicative</returns>\n    [Pure]\n    internal static Validation<F, A> FailI<F, A>(F value) =>\n        new Validation<F, A>.Fail(value);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Validation.Success.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt;\n\npublic abstract partial record Validation<F, A>\n{\n    public sealed record Success(A Value) : Validation<F, A>\n    {\n        /// <summary>\n        /// Is the Validation in a Success state?\n        /// </summary>\n        [Pure]\n        public override bool IsSuccess =>\n            true;\n\n        /// <summary>\n        /// Is the Validation in a Left state?\n        /// </summary>\n        [Pure]\n        public override bool IsFail =>\n            false;\n\n        /// <summary>\n        /// Invokes the Success or Left function depending on the state of the Validation\n        /// </summary>\n        /// <typeparam name=\"B\">Return type</typeparam>\n        /// <param name=\"Left\">Function to invoke if in a Left state</param>\n        /// <param name=\"Success\">Function to invoke if in a Success state</param>\n        /// <returns>The return value of the invoked function</returns>\n        [Pure]\n        public override B Match<B>(\n            Func<F, B> Fail,\n            Func<A, B> Succ) =>\n            Succ(Value);\n\n        /// <summary>\n        /// Show the structure as a string\n        /// </summary>\n        [Pure]\n        public override string ToString() =>\n            Value is null ? \"Success(null)\" : $\"Success({Value})\";\n\n        /// <summary>\n        /// Get a hash code for the structure\n        /// </summary>\n        [Pure]\n        public override int GetHashCode() =>\n            Value is null ? 0 : HashableDefault<A>.GetHashCode(Value);\n\n        /// <summary>\n        /// Empty span\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<F> FailSpan() =>\n            ReadOnlySpan<F>.Empty;\n\n        /// <summary>\n        /// Span of right value\n        /// </summary>\n        [Pure]\n        public override ReadOnlySpan<A> SuccessSpan() =>\n            new([Value]);\n\n        /// <summary>\n        /// Compare this structure to another to find its relative ordering\n        /// </summary>\n        [Pure]\n        public override int CompareTo<OrdF, OrdA>(Validation<F, A> other) =>\n            other switch\n            {\n                Success r => OrdA.Compare(Value, r.Value),\n                _         => 1\n            };\n\n        /// <summary>\n        /// Equality override\n        /// </summary>\n        [Pure]\n        public override bool Equals<EqF, EqA>(Validation<F, A> other) =>\n            other switch\n            {\n                Success r => EqA.Equals(Value, r.Value),\n                _         => false\n            };\n\n        /// <summary>\n        /// Unsafe access to the right-value \n        /// </summary>\n        /// <exception cref=\"InvalidCastException\"></exception>\n        internal override A SuccessValue =>\n            Value;\n\n        /// <summary>\n        /// Unsafe access to the left-value \n        /// </summary>\n        /// <exception cref=\"InvalidCastException\"></exception>\n        internal override F FailValue =>\n            throw new InvalidCastException();\n\n        /// <summary>\n        /// Maps the value in the Validation if it's in a Success state\n        /// </summary>\n        /// <typeparam name=\"F\">Left</typeparam>\n        /// <typeparam name=\"A\">Success</typeparam>\n        /// <typeparam name=\"B\">Mapped Validation type</typeparam>\n        /// <param name=\"f\">Map function</param>\n        /// <returns>Mapped Validation</returns>\n        [Pure]\n        public override Validation<F, B> Map<B>(Func<A, B> f) =>\n            new Validation<F, B>.Success(f(Value));\n\n        /// <summary>\n        /// Bi-maps the value in the Validation if it's in a Success state\n        /// </summary>\n        /// <typeparam name=\"F\">Left</typeparam>\n        /// <typeparam name=\"A\">Success</typeparam>\n        /// <typeparam name=\"L2\">Left return</typeparam>\n        /// <typeparam name=\"R2\">Success return</typeparam>\n        /// <param name=\"Success\">Success map function</param>\n        /// <param name=\"Fail\">Left map function</param>\n        /// <returns>Mapped Validation</returns>\n        [Pure]\n        public override Validation<L2, R2> BiMap<L2, R2>(\n            Func<F, L2> Fail,\n            Func<A, R2> Succ) =>\n            new Validation<L2, R2>.Success(Succ(Value));\n\n        /// <summary>\n        /// Monadic bind\n        /// </summary>\n        /// <typeparam name=\"F\">Left</typeparam>\n        /// <typeparam name=\"A\">Success</typeparam>\n        /// <typeparam name=\"B\">Resulting bound value</typeparam>\n        /// <param name=\"f\">Bind function</param>\n        /// <returns>Bound Validation</returns>\n        [Pure]\n        public override Validation<F, B> Bind<B>(Func<A, Validation<F, B>> f) =>\n            f(Value);\n\n        /// <summary>\n        /// Bi-bind.  Allows mapping of both monad states\n        /// </summary>\n        [Pure]\n        public override Validation<L2, R2> BiBind<L2, R2>(\n            Func<F, Validation<L2, R2>> Fail,\n            Func<A, Validation<L2, R2>> Succ) =>\n            Succ(Value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/Validation/Validation.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing LanguageExt.Traits;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Like `Either` but collects multiple failed values\n/// </summary>\n/// <exception cref=\"TypeLoadException\">\n/// <para>\n/// Any `TypeLoadException` thrown is because the `F` type used does not derive from `Monoid〈F〉` or `Semigroup〈F〉`.\n/// This is a runtime error rather than a compile-time constraint error because we're resolving the `Monoid〈F〉` and\n/// `Semigroup〈F〉` traits ad-hoc.\n/// </para>\n/// <para>\n/// That means we delay finding out that the provided `F` type isn't compatible for `Validation〈F, A〉`.  That is\n/// annoying, we would prefer compile-time constraints, of course, but it enables much more freedom to implement the\n/// `Coproduct`, `Bifunctor`, and `Bimonad` traits which, in turn, give additional functionality for free (like\n/// `Partition`).\n/// </para>\n/// <para>\n/// Implementation of those traits would not be possible if we were to add compile-time constraints to `F`.  So, the\n/// resolution of any type-exception thrown is to only use `Monoid〈F〉` or `Semigroup〈F〉` deriving types for `F`,\n/// depending on the functionality required.\n/// </para> \n/// </exception>\n/// <typeparam name=\"F\">Failure value type: it is important that this implements `Monoid〈F〉`</typeparam>\n/// <typeparam name=\"A\">Success value type</typeparam>\n[Serializable]\npublic abstract partial record Validation<F, A> :\n    IComparable<Validation<F, A>>,\n    IComparable<A>,\n    IComparable,\n    IEquatable<Pure<A>>,\n    IComparable<Pure<A>>,\n    IEquatable<A>,\n    K<Validation<F>, A>,\n    K<Validation, F, A>\n{\n    /// <summary>\n    /// Is the Validation in a Success state?\n    /// </summary>\n    [Pure]\n    public abstract bool IsSuccess { get; }\n\n    /// <summary>\n    /// Is the Validation in a Fail state?\n    /// </summary>\n    [Pure]\n    public abstract bool IsFail { get; }\n\n    /// <summary>\n    /// Invokes the Success or Fail function depending on the state of the Validation\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Fail\">Function to invoke if in a Fail state</param>\n    /// <param name=\"Succ\">Function to invoke if in a Success state</param>\n    /// <returns>The return value of the invoked function</returns>\n    [Pure]\n    public abstract B Match<B>(Func<F, B> Fail, Func<A, B> Succ);\n\n    /// <summary>\n    /// Empty span\n    /// </summary>\n    [Pure]\n    public abstract ReadOnlySpan<F> FailSpan();\n\n    /// <summary>\n    /// Span of right value\n    /// </summary>\n    [Pure]\n    public abstract ReadOnlySpan<A> SuccessSpan();\n\n    /// <summary>\n    /// Compare this structure to another to find its relative ordering\n    /// </summary>\n    [Pure]\n    public abstract int CompareTo<OrdF, OrdA>(Validation<F, A> other)\n        where OrdF : Ord<F>\n        where OrdA : Ord<A>;\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public abstract bool Equals<EqF, EqA>(Validation<F, A> other)\n        where EqF : Eq<F>\n        where EqA : Eq<A>;\n\n    /// <summary>\n    /// Unsafe access to the right-value \n    /// </summary>\n    /// <exception cref=\"InvalidCastException\"></exception>\n    internal abstract A SuccessValue { get; }\n\n    /// <summary>\n    /// Unsafe access to the left-value \n    /// </summary>\n    /// <exception cref=\"InvalidCastException\"></exception>\n    internal abstract F FailValue { get; }\n\n    /// <summary>\n    /// Maps the value in the Validation if it's in a Success state\n    /// </summary>\n    /// <typeparam name=\"F\">Fail</typeparam>\n    /// <typeparam name=\"A\">Success</typeparam>\n    /// <typeparam name=\"B\">Mapped Validation type</typeparam>\n    /// <param name=\"f\">Map function</param>\n    /// <returns>Mapped Validation</returns>\n    [Pure]\n    public abstract Validation<F, B> Map<B>(Func<A, B> f);\n\n    /// <summary>\n    /// Bi-maps the value in the Validation if it's in a Success state\n    /// </summary>\n    /// <typeparam name=\"F\">Fail</typeparam>\n    /// <typeparam name=\"A\">Success</typeparam>\n    /// <typeparam name=\"F1\">Fail return</typeparam>\n    /// <typeparam name=\"A1\">Success return</typeparam>\n    /// <param name=\"Succ\">Success map function</param>\n    /// <param name=\"Fail\">Fail map function</param>\n    /// <returns>Mapped Validation</returns>\n    [Pure]\n    public abstract Validation<F1, A1> BiMap<F1, A1>(Func<F, F1> Fail, Func<A, A1> Succ);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <typeparam name=\"F\">Fail</typeparam>\n    /// <typeparam name=\"A\">Success</typeparam>\n    /// <typeparam name=\"B\">Resulting bound value</typeparam>\n    /// <param name=\"f\">Bind function</param>\n    /// <returns>Bound Validation</returns>\n    [Pure]\n    public abstract Validation<F, B> Bind<B>(Func<A, Validation<F, B>> f);\n\n    /// <summary>\n    /// Bi-bind.  Allows mapping of both monad states\n    /// </summary>\n    [Pure]\n    public abstract Validation<F1, A1> BiBind<F1, A1>(\n        Func<F, Validation<F1, A1>> Fail,\n        Func<A, Validation<F1, A1>> Succ);\n\n    /// <summary>\n    /// Bind the failure\n    /// </summary>\n    [Pure]\n    public Validation<F1, A> BindFail<F1>(\n        Func<F, Validation<F1, A>> Fail) \n        where F1 : Monoid<F1> =>\n        BiBind(Fail, Validation.SuccessI<F1, A>);\n\n    /// <summary>\n    /// Explicit conversion operator from `` to `R`\n    /// </summary>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"InvalidCastException\">Value is not in a Right state</exception>\n    [Pure]\n    public static explicit operator A(Validation<F, A> ma) =>\n        ma.SuccessValue;\n\n    /// <summary>\n    /// Explicit conversion operator from `Validation` to `L`\n    /// </summary>\n    /// <param name=\"value\">Value</param>\n    /// <exception cref=\"InvalidCastException\">Value is not in a Fail state</exception>\n    [Pure]\n    public static explicit operator F(Validation<F, A> ma) =>\n        ma.FailValue;\n\n    /// <summary>\n    /// Implicit conversion operator from `A` to `Validation〈F, A〉`\n    /// </summary>\n    [Pure]\n    public static implicit operator Validation<F, A>(A value) =>\n        new Success(value);\n\n    /// <summary>\n    /// Implicit conversion operator from `F` to `Validation〈F, A〉`\n    /// </summary>\n    [Pure]\n    public static implicit operator Validation<F, A>(F value) =>\n        new Fail(value);\n\n    /// <summary>\n    /// Invokes the `Succ` or `Fail` action depending on the state of the value\n    /// </summary>\n    /// <param name=\"Fail\">Action to invoke if in a Fail state</param>\n    /// <param name=\"Succ\">Action to invoke if in a Success state</param>\n    /// <returns>Unit</returns>\n    public Unit Match(Action<F> Fail, Action<A> Succ) =>\n        Match(fun(Fail), fun(Succ));\n\n    /// <summary>\n    /// Executes the `Fail` function if the value is in a Fail state.\n    /// Returns the Success value if the value is in a Success state.\n    /// </summary>\n    /// <param name=\"Fail\">Function to generate a value if in the Fail state</param>\n    /// <returns>Returns an unwrapped value</returns>\n    [Pure]\n    public A IfFail(Func<A> Fail) =>\n        Match(_ => Fail(), identity);\n\n    /// <summary>\n    /// Executes the `failMap` function if the value is in a Fail state.\n    /// Returns the Success value if in a Success state.\n    /// </summary>\n    /// <param name=\"failMap\">Function to generate a value if in the Fail state</param>\n    /// <returns>Returns an unwrapped value</returns>\n    [Pure]\n    public A IfFail(Func<F, A> failMap) =>\n        Match(failMap, identity);\n\n    /// <summary>\n    /// Returns the `successValue` if in a Fail state.\n    /// Returns the Success value if in a Success state.\n    /// </summary>\n    /// <param name=\"successValue\">Value to return if in the Fail state</param>\n    /// <returns>Returns an unwrapped value</returns>\n    [Pure]\n    public A IfFail(A successValue) =>\n        Match(_ => successValue, identity);\n\n    /// <summary>\n    /// Executes the Fail action if in a Fail state.\n    /// </summary>\n    /// <param name=\"Fail\">Function to generate a Success value if in the Fail state</param>\n    /// <returns>Unit</returns>\n    public Unit IfFail(Action<F> Fail) =>\n        Match(Fail, _ => { });\n\n    /// <summary>\n    /// Invokes the `Success` action if in a Success state, otherwise does nothing\n    /// </summary>\n    /// <param name=\"Success\">Action to invoke</param>\n    /// <returns>Unit</returns>\n    public Unit IfRight(Action<A> Success) =>\n        Match(_ => { }, Success);\n\n    [Pure]\n    public int CompareTo(object? obj) =>\n        obj is Validation<F, A> t ? CompareTo(t) : 1;\n\n    /// <summary>\n    /// Project into a `Lst〈A〉`\n    /// </summary>\n    /// <returns>If in a Success state, a `Lst` of `R` with one item.  A zero length `Lst` of `R` otherwise</returns>\n    public Lst<A> ToList() =>\n        new(SuccessSpan());\n\n    /// <summary>\n    /// Project into an `Arr〈A〉`\n    /// </summary>\n    /// <returns>If in a Success state, an `Arr` of `R` with one item.  A zero length `Arr` of `R` otherwise</returns>\n    public Arr<A> ToArray() =>\n        new(SuccessSpan());\n\n    /// <summary>\n    /// Convert to sequence of 0 or 1 success values\n    /// </summary>\n    [Pure]\n    public Seq<A> ToSeq() =>\n        new(SuccessSpan());\n\n    /// <summary>\n    /// Convert to sequence of 0 or 1 success values\n    /// </summary>\n    [Pure]\n    public Iterable<A> ToIterable() =>\n        [..SuccessSpan()];\n    \n    /// <summary>\n    /// Convert to sequence of 0 or 1 success values\n    /// </summary>\n    [Pure]\n    public IEnumerable<A> AsEnumerable() =>\n        [..SuccessSpan()];\n\n    [Pure]\n    public Either<F, A> ToEither() =>\n        this switch\n        {\n            Success (var x) => new Either<F, A>.Right(x),\n            Fail (var x)    => new Either<F, A>.Left(x),\n            _               => throw new NotSupportedException()\n        };\n\n    /// <summary>\n    /// Convert to an Option\n    /// </summary>\n    /// <returns>Some(Right) or None</returns>\n    [Pure]\n    public Option<A> ToOption() =>\n        this switch\n        {\n            Success (var x) => Option.Some(x),\n            Fail            => Option<A>.None,\n            _               => throw new NotSupportedException()\n        };\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Validation<F, A> lhs, Fail<F> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Validation<F, A> lhs, Fail<F> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Validation<F, A> lhs, Fail<F> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Validation<F, A> lhs, Fail<F> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Validation<F, A> lhs, Pure<A> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Validation<F, A> lhs, Pure<A> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Validation<F, A> lhs, Pure<A> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Validation<F, A> lhs, Pure<A> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Fail<F> lhs, Validation<F, A> rhs) =>\n        ((Validation<F, A>)lhs).CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Fail<F>  lhs, Validation<F, A> rhs) =>\n        ((Validation<F, A>)lhs).CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Fail<F> lhs, Validation<F, A>rhs) =>\n        ((Validation<F, A>)lhs).CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Fail<F> lhs, Validation<F, A>  rhs) =>\n        ((Validation<F, A>)lhs).CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Pure<A> lhs, Validation<F, A>  rhs) =>\n        ((Validation<F, A>)lhs).CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Pure<A> lhs, Validation<F, A> rhs) =>\n        ((Validation<F, A>)lhs).CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Pure<A> lhs, Validation<F, A> rhs) =>\n        ((Validation<F, A>)lhs).CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Pure<A> lhs, Validation<F, A> rhs) =>\n        ((Validation<F, A>)lhs).CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈 rhs</returns>\n    [Pure]\n    public static bool operator <(Validation<F, A> lhs, Validation<F, A> rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs〈= rhs</returns>\n    [Pure]\n    public static bool operator <=(Validation<F, A> lhs, Validation<F, A> rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉rhs</returns>\n    [Pure]\n    public static bool operator >(Validation<F, A> lhs, Validation<F, A> rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    /// <summary>\n    /// Comparison operator\n    /// </summary>\n    /// <param name=\"lhs\">The left-hand side of the operation</param>\n    /// <param name=\"rhs\">The right-hand side of the operation</param>\n    /// <returns>True if lhs 〉= rhs</returns>\n    [Pure]\n    public static bool operator >=(Validation<F, A> lhs, Validation<F, A> rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Validation<F, A> lhs, Fail<F> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Validation<F, A> lhs, Pure<A> rhs) =>\n        lhs.Equals(rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Fail<F>  lhs, Validation<F, A> rhs) =>\n        ((Validation<F, A>)lhs).Equals(rhs);\n\n    /// <summary>\n    /// Equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator ==(Pure<A> lhs, Validation<F, A>  rhs) =>\n        ((Validation<F, A>)lhs).Equals(rhs);\n        \n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Validation<F, A> lhs, Fail<F> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Validation<F, A> lhs, Pure<A> rhs) =>\n        !(lhs == rhs);\n\n\n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Fail<F> lhs, Validation<F, A> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// Non-equality operator override\n    /// </summary>\n    [Pure]\n    public static bool operator !=(Pure<A> lhs, Validation<F, A> rhs) =>\n        !(lhs == rhs);\n\n    /// <summary>\n    /// If any items are `Fail`, then the errors are collected and returned.  If they all pass, then the Success values\n    /// are collected into a `Seq`.  \n    /// </summary>\n    /// <exception cref=\"TypeLoadException\">\n    /// <para>\n    /// Any `TypeLoadException` thrown is because the `F` type used does not derive from `Semigroup〈F〉`.\n    /// This is a runtime error rather than a compile-time constraint error because we're resolving the `Semigroup〈F〉`\n    /// trait ad hoc.\n    /// </para>\n    /// <para>\n    /// That means we delay finding out that the provided `F` type isn't compatible for `Validation〈F, A〉`.  That is\n    /// annoying, we would prefer compile-time constraints, of course, but it enables much more freedom to implement the\n    /// `Coproduct`, `Bifunctor`, and `Bimonad` traits which, in turn, give additional functionality for free (like\n    /// `Partition`).\n    /// </para>\n    /// <para>\n    /// Implementation of those traits would not be possible if we were to add compile-time constraints to `F`.  So, the\n    /// resolution of any type-exception thrown is to only use `Semigroup〈F〉` deriving types for `F`.\n    /// </para> \n    /// </exception>\n    [Pure]\n    public static Validation<F, Seq<A>> operator &(Validation<F, A> lhs, Validation<F, A> rhs) =>\n        lhs.CombineI(rhs, SemigroupInstance<F>.Instance);\n\n    /// <summary>\n    /// If any items are `Fail`, then the errors are collected and returned.  If they all pass, then the Success values\n    /// are collected into a `Seq`.  \n    /// </summary>\n    /// <exception cref=\"TypeLoadException\">\n    /// <para>\n    /// Any `TypeLoadException` thrown is because the `F` type used does not derive from `Semigroup〈F〉`.\n    /// This is a runtime error rather than a compile-time constraint error because we're resolving the `Semigroup〈F〉`\n    /// trait ad hoc.\n    /// </para>\n    /// <para>\n    /// That means we delay finding out that the provided `F` type isn't compatible for `Validation〈F, A〉`.  That is\n    /// annoying, we would prefer compile-time constraints, of course, but it enables much more freedom to implement the\n    /// `Coproduct`, `Bifunctor`, and `Bimonad` traits which, in turn, give additional functionality for free (like\n    /// `Partition`).\n    /// </para>\n    /// <para>\n    /// Implementation of those traits would not be possible if we were to add compile-time constraints to `F`.  So, the\n    /// resolution of any type-exception thrown is to only use `Semigroup〈F〉` deriving types for `F`.\n    /// </para> \n    /// </exception>\n    [Pure]\n    public static Validation<F, Seq<A>> operator &(Validation<F, Seq<A>> lhs, Validation<F, A> rhs) =>\n        lhs.CombineI(rhs, SemigroupInstance<F>.Instance);\n\n    /// <summary>\n    /// If any items are `Fail`, then the errors are collected and returned.  If they all pass, then the Success values\n    /// are collected into a `Seq`.  \n    /// </summary>\n    /// <exception cref=\"TypeLoadException\">\n    /// <para>\n    /// Any `TypeLoadException` thrown is because the `F` type used does not derive from `Semigroup〈F〉`.\n    /// This is a runtime error rather than a compile-time constraint error because we're resolving the `Semigroup〈F〉`\n    /// trait ad hoc.\n    /// </para>\n    /// <para>\n    /// That means we delay finding out that the provided `F` type isn't compatible for `Validation〈F, A〉`.  That is\n    /// annoying, we would prefer compile-time constraints, of course, but it enables much more freedom to implement the\n    /// `Coproduct`, `Bifunctor`, and `Bimonad` traits which, in turn, give additional functionality for free (like\n    /// `Partition`).\n    /// </para>\n    /// <para>\n    /// Implementation of those traits would not be possible if we were to add compile-time constraints to `F`.  So, the\n    /// resolution of any type-exception thrown is to only use `Semigroup〈F〉` deriving types for `F`.\n    /// </para> \n    /// </exception>\n    [Pure]\n    public static Validation<F, Seq<A>> operator &(Validation<F, A> lhs, Validation<F, Seq<A>> rhs) =>\n        lhs.CombineI(rhs, SemigroupInstance<F>.Instance);\n\n    /// <summary>\n    /// Must exist here to make `operator true` work\n    /// </summary>\n    public static Validation<F, A> operator |(Validation<F, A> lhs, Validation<F, A> rhs) =>\n        lhs.Choose(rhs).As();\n    \n    /// <summary>\n    /// Override of the True operator to return True if the Either is Right\n    /// </summary>\n    [Pure]\n    public static bool operator true(Validation<F, A> value) =>\n        value.IsSuccess;\n\n    /// <summary>\n    /// Override of the False operator to return True if the Either is Left\n    /// </summary>\n    [Pure]\n    public static bool operator false(Validation<F, A> value) =>\n        value.IsFail;\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(Validation<F, A>? other) =>\n        other is null\n            ? 1\n            : CompareTo<OrdDefault<F>, OrdDefault<A>>(other);\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo<OrdR>(Validation<F, A> other)\n        where OrdR : Ord<A> =>\n        CompareTo<OrdDefault<F>, OrdR>(other);\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(Fail<F> other) =>\n        CompareTo((Validation<F, A>)other);\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(Pure<A> other) =>\n        CompareTo((Validation<F, A>)other);\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(A? other) =>\n        other switch\n        {\n            null => 1,\n            _    => CompareTo(Validation.SuccessI<F, A>(other))\n        };\n\n    /// <summary>\n    /// CompareTo override\n    /// </summary>\n    [Pure]\n    public int CompareTo(F? other) =>\n        other switch\n        {\n            null => 1,\n            _    => CompareTo(Fail(other))\n        };\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(A? other) =>\n        other is not null && Equals(Validation.SuccessI<F, A>(other));\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(F? other) =>\n        other is not null && Equals(Fail(other));\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public virtual bool Equals(Validation<F, A>? other) =>\n        other is not null && Equals<EqDefault<F>, EqDefault<A>>(other);\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public virtual bool Equals<EqR>(Validation<F, A> other) where EqR : Eq<A> =>\n        Equals<EqDefault<F>, EqR>(other);\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(Fail<F> other) =>\n        Equals((Validation<F, A>)other);\n\n    /// <summary>\n    /// Equality override\n    /// </summary>\n    [Pure]\n    public bool Equals(Pure<A> other) =>\n        Equals((Validation<F, A>)other);\n\n    /// <summary>\n    /// Match the Success and Fail values but as untyped objects.\n    /// </summary>\n    [Pure]\n    public B MatchUntyped<B>(Func<object?, B> Succ, Func<object?, B> Fail) =>\n        Match(x => Succ(x), x => Fail(x));\n\n    /// <summary>\n    /// Iterate the value\n    /// action is invoked if in the Success state\n    /// </summary>\n    public Unit Iter(Action<A> Succ) =>\n        Match(_ => { }, Succ);\n\n    /// <summary>\n    /// Invokes a predicate on the success value if it's in the Success state\n    /// </summary>\n    /// <returns>\n    /// True if in a `Left` state.  \n    /// `True` if the in a `Right` state and the predicate returns `True`.  \n    /// `False` otherwise.</returns>\n    [Pure]\n    public bool ForAll(Func<A, bool> Succ) =>\n        Match(_ => true, Succ);\n\n    /// <summary>\n    /// Invokes a predicate on the values \n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <param name=\"self\">Either to forall</param>\n    /// <param name=\"Succ\">Predicate</param>\n    /// <param name=\"Fail\">Predicate</param>\n    /// <returns>True if either Predicate returns true</returns>\n    [Pure]\n    public bool BiForAll(Func<F, bool> Fail, Func<A, bool> Succ) =>\n        Match(Fail, Succ);\n\n    /// <summary>\n    /// Validation types are like lists of 0 or 1 items and therefore follow the \n    /// same rules when folding.\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"Succ\">Folder function, applied if structure is in a Success state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    public S Fold<S>(S state, Func<S, A, S> Succ) =>\n        Match(_ => state, curry(Succ)(state));\n\n    /// <summary>\n    /// Either types are like lists of 0 or 1 items, and therefore follow the \n    /// Validation types are like lists of 0 or 1 items and therefore follow the \n    /// same rules when folding.\n    /// </summary>\n    /// <typeparam name=\"S\">Aggregate state type</typeparam>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"Succ\">Folder function, applied if in a Success state</param>\n    /// <param name=\"Fail\">Folder function, applied if in a Fail state</param>\n    /// <returns>The aggregate state</returns>\n    [Pure]\n    public S BiFold<S>(S state, Func<S, F, S> Fail, Func<S, A, S> Succ) =>\n        Match(curry(Fail)(state), curry(Succ)(state));\n\n    /// <summary>\n    /// Invokes a predicate on the value if it's in the Success state\n    /// </summary>\n    /// <param name=\"pred\">Predicate</param>\n    /// <returns>True if in a Success state and the predicate returns `True`.  `False` otherwise.</returns>\n    [Pure]\n    public bool Exists(Func<A, bool> pred) =>\n        Match(_ => false, pred);\n\n    /// <summary>\n    /// Impure iteration of the bound values in the structure\n    /// </summary>\n    /// <returns>\n    /// Returns the original unmodified structure\n    /// </returns>\n    public Validation<F, A> Do(Action<A> f) =>\n        Map(r => { f(r); return r; });\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<AF, Validation<F, B>> Traverse<AF, B>(Func<A, K<AF, B>> f) \n        where AF : Applicative<AF> =>\n        AF.Map(x => x.As(), Traversable.traverse(f, this));\n\n    /// <summary>\n    /// Maps the value in the Either if it's in a Left state\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <typeparam name=\"F1\">Mapped Either type</typeparam>\n    /// <param name=\"f\">Map function</param>\n    /// <returns>Mapped Either</returns>\n    [Pure]\n    public Validation<F1, A> MapFail<F1>(Func<F, F1> f) \n        where F1 : Monoid<F1> =>\n        Match(e => Validation.FailI<F1, A>(f(e)), Validation.SuccessI<F1, A>);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <typeparam name=\"L\">Left</typeparam>\n    /// <typeparam name=\"R\">Right</typeparam>\n    /// <typeparam name=\"B\"></typeparam>\n    /// <param name=\"f\"></param>\n    /// <returns>Bound Either</returns>\n    [Pure]\n    public Validation<F, B> Bind<B>(Func<A, K<Validation<F>, B>> f) =>\n        Bind(x => (Validation<F, B>)f(x));\n\n    /// <summary>\n    /// Maps the bound value \n    /// </summary>\n    [Pure]\n    public Validation<F, B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Monadic bind function\n    /// </summary>\n    [Pure]\n    public Validation<F, B> SelectMany<S, B>(Func<A, Validation<F, S>> bind, Func<A, S, B> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n        \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    // `Pure` and `Fail` support\n    //\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    [Pure]\n    public Validation<F, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Bind(x => (Validation<F, B>)f(x));\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    [Pure]\n    public Validation<F, A> Bind(Func<A, Fail<F>> f) =>\n        Bind(x => (Validation<F, A>)f(x));\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    [Pure]\n    public Validation<F, Unit> Bind(Func<A, Guard<F, Unit>> f)=>\n        Bind(a => f(a).ToValidationI());\n\n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    [Pure]\n    public Validation<F, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    [Pure]\n    public Validation<F, C> SelectMany<B, C>(Func<A, Fail<F>> bind, Func<A, B, C> _) =>\n        Bind(x => Validation.FailI<F, C>(bind(x).Value));\n    \n    /// <summary>\n    /// Monadic bind and project\n    /// </summary>\n    /// <param name=\"bind\">Bind function</param>\n    /// <param name=\"project\">Project function</param>\n    [Pure]\n    public Validation<F, C> SelectMany<C>(\n        Func<A, Guard<F, Unit>> f,\n        Func<A, Unit, C> project) =>\n        SelectMany(a => f(a).ToValidationI(), project);\n    \n    [Pure]\n    public static implicit operator Validation<F, A>(Pure<A> mr) =>\n        Validation.SuccessI<F, A>(mr.Value);\n\n    [Pure]\n    public static implicit operator Validation<F, A>(Fail<F> mr) =>\n        Validation.FailI<F, A>(mr.Value);\n\n    public override int GetHashCode() => \n        HashCode.Combine(IsSuccess, IsFail, SuccessValue, FailValue);\n}\n\n/// <summary>\n/// Context for the fluent Either matching\n/// </summary>\npublic readonly struct ValidationContext<F, A, B>\n{\n    readonly Validation<F, A> validation;\n    readonly Func<A, B> success;\n\n    internal ValidationContext(Validation<F, A> validation, Func<A, B> success)\n    {\n        this.validation = validation;\n        this.success = success;\n    }\n\n    /// <summary>\n    /// Fail match\n    /// </summary>\n    /// <param name=\"Fail\"></param>\n    /// <returns>Result of the match</returns>\n    [Pure]\n    public B Fail(Func<F, B> fail) =>\n        validation.Match(fail, success);\n}\n\n/// <summary>\n/// Context for the fluent Validation matching\n/// </summary>\npublic readonly struct ValidationUnitContext<F, A>\n{\n    readonly Validation<F, A> validation;\n    readonly Action<A> success;\n\n    internal ValidationUnitContext(Validation<F, A> validation, Action<A> success)\n    {\n        this.validation = validation;\n        this.success = success;\n    }\n\n    public Unit Left(Action<F> fail) =>\n        validation.Match(fail, success);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Extensions/ValidationT.Extensions.Apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static ValidationT<F, M, B> Action<F, M, A, B>(this ValidationT<F, M, A> ma, K<ValidationT<F, M>, B> mb)\n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static ValidationT<F, M, B> Action<F, M, A, B>(this K<ValidationT<F, M>, A> ma, K<ValidationT<F, M>, B> mb)\n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static ValidationT<F, M, B> Apply<F, M, A, B>(this ValidationT<F, M, Func<A, B>> mf, K<ValidationT<F, M>, A> ma)\n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static ValidationT<F, M, B> Apply<F, M, A, B>(this K<ValidationT<F, M>, Func<A, B>> mf, K<ValidationT<F, M>, A> ma)\n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Extensions/ValidationT.Extensions.Map.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static ValidationT<F, M, B> Map<F, M, A, B>(this Func<A, B> f, K<ValidationT<F, M>, A> ma)\n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static ValidationT<F, M, B> Map<F, M, A, B>(this Func<A, B> f, ValidationT<F, M, A> ma) \n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Extensions/ValidationT.Extensions.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// ValidationT monad transformer extensions\n/// </summary>\npublic static partial class ValidationTExtensions\n{\n    public static ValidationT<F, M, A> As<F, M, A>(this K<ValidationT<F, M>, A> ma)\n        where M : Monad<M> =>\n        (ValidationT<F, M, A>)ma;\n    \n    public static ValidationT<F, M, A> As2<F, M, A>(this K<ValidationT<M>, F, A> ma)\n        where M : Monad<M> =>\n        (ValidationT<F, M, A>)ma;\n    \n    public static K<M, Validation<F, A>> Run<F, M, A>(this K<ValidationT<F, M>, A> ma)\n        where M : Monad<M>\n        where F : Monoid<F> =>\n        ((ValidationT<F, M, A>)ma).Run(F.Instance);\n\n    public static K<M, B> Match<F, M, A, B>(\n        this K<ValidationT<F, M>, A> ma, \n        Func<F, B> Fail,\n        Func<A, B> Succ) \n        where M : Monad<M> \n        where F : Monoid<F> =>\n        ma.As().MatchI(Fail, Succ)(F.Instance);\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public static ValidationT<F1, M, A> MapFail<F, F1, M, A>(\n        this K<ValidationT<F, M>, A> ma, \n        Func<F, F1> f) \n        where M : Monad<M> \n        where F : Monoid<F> \n        where F1 : Monoid<F1> =>\n        new(_ => M.Map(mx => mx.MapFail(f), ma.Run()));\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static ValidationT<F, M, A> Flatten<F, M, A>(this ValidationT<F, M, ValidationT<F, M, A>> mma)\n        where M : Monad<M> \n        where F : Monoid<F> =>\n        mma.Bind(identity);\n\n    /// <summary>\n    /// Get the outer task and wrap it up in a new IO within the EitherT IO\n    /// </summary>\n    public static ValidationT<F, IO, A> Flatten<F, A>(this Task<ValidationT<F, IO, A>> tma)\n        where F : Monoid<F> =>\n        ValidationT\n           .lift<F, IO, ValidationT<F, IO, A>>(IO.liftAsync(async () => await tma.ConfigureAwait(false)))\n           .Flatten();\n\n    /// <summary>\n    /// Lift the task\n    /// </summary>\n    public static ValidationT<L, IO, A> ToIO<L, A>(this Task<Validation<L, A>> ma)\n        where L : Monoid<L> =>\n        liftIO(ma);\n    \n    public static OptionT<M, A> ToOption<F, M, A>(this ValidationT<F, M, A> ma)\n        where F : Monoid<F>\n        where M : Monad<M> =>\n        new(ma.runValidation(F.Instance).Map(ma => ma.ToOption()));\n\n    public static EitherT<F, M, A> ToEither<F, M, A>(this ValidationT<F, M, A> ma)\n        where F : Monoid<F>\n        where M : Monad<M> =>\n        new(ma.runValidation(F.Instance).Map(ma => ma.ToEither()));\n\n    public static FinT<M, A> ToFin<M, A>(this ValidationT<Error, M, A> ma)\n        where M : Monad<M> =>\n        new(ma.runValidation(Monoid.instance<Error>()).Map(ma => ma.ToFin()));\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    [Pure]\n    public static ValidationT<L, M, C> SelectMany<L, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<ValidationT<L, M>, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M>\n        where L : Monoid<L> =>\n        ValidationT.lift<L, M, A>(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    [Pure]\n    public static ValidationT<L, M, C> SelectMany<L, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, ValidationT<L, M, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M>\n        where L : Monoid<L> =>\n        ValidationT.lift<L, M, A>(ma).SelectMany(bind, project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Extensions/ValidationT.Guard.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class ValidationTGuardExtensions\n{\n    /// <summary>\n    /// Natural transformation to `ValidationT`\n    /// </summary>\n    public static ValidationT<F, M, Unit> ToValidationT<F, M>(this Guard<F, Unit> guard)\n        where M : Monad<M>\n        where F : Monoid<F> =>\n        guard.Flag\n            ? ValidationT.Success<F, M, Unit>(default)\n            : ValidationT.Fail<F, M, Unit>(guard.OnFalse());\n    /// <summary>\n    /// Natural transformation to `ValidationT`\n    /// </summary>\n    internal static ValidationT<F, M, Unit> ToValidationTI<F, M>(this Guard<F, Unit> guard)\n        where M : Monad<M> =>\n        guard.Flag\n            ? ValidationT.SuccessI<F, M, Unit>(default)\n            : ValidationT.FailI<F, M, Unit>(guard.OnFalse());\n \n    /// <summary>\n    /// Monadic binding support for `ValidationT`\n    /// </summary>\n    public static ValidationT<F, M, B> Bind<F, M, B>(\n        this Guard<F, Unit> guard,\n        Func<Unit, ValidationT<F, M, B>> f) \n        where M : Monad<M>\n        where F : Monoid<F> =>\n        guard.Flag\n            ? f(default).As()\n            : ValidationT.Fail<F, M, B>(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `Validation`\n    /// </summary>\n    public static ValidationT<F, M, C> SelectMany<F, M, B, C>(\n        this Guard<F, Unit> guard,\n        Func<Unit, ValidationT<F, M, B>> bind, \n        Func<Unit, B, C> project) \n        where M : Monad<M>\n        where F : Monoid<F> =>\n        guard.Flag\n            ? bind(default).As().Map(b => project(default, b))\n            : ValidationT.Fail<F, M, C>(guard.OnFalse());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Operators/ValidationT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    extension<FF, M, A, B>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static ValidationT<FF, M, B> operator >>> (K<ValidationT<FF, M>, A> ma, K<ValidationT<FF, M>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, B> operator * (K<ValidationT<FF, M>, Func<A, B>> mf, K<ValidationT<FF, M>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, B> operator * (K<ValidationT<FF, M>, A> ma, K<ValidationT<FF, M>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<FF, M, A, B, C>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, C>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, C>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<FF, M, A, B, C, D>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, D>>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C, D>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, D>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<FF, M, A, B, C, D, E>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C, D, E>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<FF, M, A, B, C, D, E, F>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<FF, M, A, B, C, D, E, F, G>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<FF, M, A, B, C, D, E, F, G, H>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<FF, M, A, B, C, D, E, F, G, H, I>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<FF, M, A, B, C, D, E, F, G, H, I, J>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<FF, M, A, B, C, D, E, F, G, H, I, J, K>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<ValidationT<FF, M>, A> ma,\n            K<ValidationT<FF, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Operators/ValidationT.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    extension<FF, M, A>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static ValidationT<FF, M, A> operator |(K<ValidationT<FF, M>, A> lhs, K<ValidationT<FF, M>, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static ValidationT<FF, M, A> operator |(K<ValidationT<FF, M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(ValidationT.SuccessI<FF, M, A>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Operators/ValidationT.Operators.Combine.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    extension<FF, M, A>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n        where FF : Semigroup<FF>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ValidationT<FF, M, A> operator +(K<ValidationT<FF, M>, A> lhs, K<ValidationT<FF, M>, A> rhs) =>\n            +lhs.Combine(rhs);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ValidationT<FF, M, A> operator +(K<ValidationT<FF, M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Combine(ValidationT.SuccessI<FF, M, A>(rhs.Value));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ValidationT<FF, M, A> operator +(K<ValidationT<FF, M>, A> lhs, Fail<FF> rhs) =>\n            +lhs.Combine(ValidationT.FailI<FF, M, A>(rhs.Value));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ValidationT<FF, M, A> operator +(K<ValidationT<FF, M>, A> lhs, FF rhs) =>\n            +lhs.Combine(ValidationT.FailI<FF, M, A>(rhs));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Operators/ValidationT.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    extension<FF, M, A>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        public static ValidationT<FF, M, A> operator |(K<ValidationT<FF, M>, A> lhs, CatchM<FF, ValidationT<FF, M>, A> rhs) =>\n            +lhs.Catch(rhs);\n\n        public static ValidationT<FF, M, A> operator |(K<ValidationT<FF, M>, A> lhs, Fail<FF> rhs) =>\n            +lhs.Catch(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Operators/ValidationT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    extension<FF, M, A, B>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, B> operator *(Func<A, B> f, K<ValidationT<FF, M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, B> operator *(K<ValidationT<FF, M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<FF, M, A, B, C>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, C>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<FF, M, A, B, C, D>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, D>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<FF, M, A, B, C, D, E>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<FF, M, A, B, C, D, E, F>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<FF, M, A, B, C, D, E, F, G>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<FF, M, A, B, C, D, E, F, G, H>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<FF, M, A, B, C, D, E, F, G, H, I>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<FF, M, A, B, C, D, E, F, G, H, I, J>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<FF, M, A, B, C, D, E, F, G, H, I, J, K>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<ValidationT<FF, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ValidationT<FF, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<ValidationT<FF, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Operators/ValidationT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    extension<FF, M, A, B>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static ValidationT<FF, M, B> operator >> (K<ValidationT<FF, M>, A> ma, Func<A, K<ValidationT<FF, M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static ValidationT<FF, M, B> operator >> (K<ValidationT<FF, M>, A> lhs, K<ValidationT<FF, M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<FF, M, A>(K<ValidationT<FF, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static ValidationT<FF, M, A> operator >> (K<ValidationT<FF, M>, A> lhs, K<ValidationT<FF, M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Operators/ValidationT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ValidationTExtensions\n{\n    extension<FF, M, A>(K<ValidationT<FF, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static ValidationT<FF, M, A> operator +(K<ValidationT<FF, M>, A> ma) =>\n            (ValidationT<FF, M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static ValidationT<FF, M, A> operator >> (K<ValidationT<FF, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Prelude/ValidationT.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static ValidationT<F, M, B> map<F, M, A, B>(Func<A, B> f, K<ValidationT<F, M>, A> ma)\n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static ValidationT<F, M, B> action<F, M, A, B>(K<ValidationT<F, M>, A> ma, K<ValidationT<F, M>, B> mb)\n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static ValidationT<F, M, B> apply<F, M, A, B>(K<ValidationT<F, M>, Func<A, B>> mf, K<ValidationT<F, M>, A> ma)\n        where F : Monoid<F> \n        where M : Monad<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Trait/ValidationT.TraitImpl.2.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing NSE = System.NotSupportedException;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `ValidationT` \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class ValidationT<M> :  \n    CoproductK<ValidationT<M>>,\n    Bimonad<ValidationT<M>> \n    where M : Monad<M>\n{\n    static K<ValidationT<M>, F, A> CoproductCons<ValidationT<M>>.Left<F, A>(F value) => \n        ValidationT.FailI<F, M, A>(value);\n\n    static K<ValidationT<M>, F, A> CoproductCons<ValidationT<M>>.Right<F, A>(A value) => \n        ValidationT.SuccessI<F, M, A>(value);\n\n    static K<ValidationT<M>, F, B> CoproductK<ValidationT<M>>.Match<F, A, B>(\n        Func<F, B> Left, \n        Func<A, B> Right, \n        K<ValidationT<M>, F, A> fab) => \n        new ValidationT<F, M, B>(monoid => fab.As2().MatchI(Left, Right)(monoid).Map(Validation.SuccessI<F, B>));\n\n    static K<ValidationT<M>, F2, B> Bifunctor<ValidationT<M>>.BiMap<F1, A, F2, B>(\n        Func<F1, F2> first,\n        Func<A, B> second,\n        K<ValidationT<M>, F1, A> fab) =>\n        new ValidationT<F2, M, B>(_ => MonoidInstance<F1>.Instance switch\n                                       {\n                                           { IsSome: true, Value: { } t } =>\n                                               fab.As2()\n                                                  .Run(t)\n                                                  .Map(v => v switch\n                                                            {\n                                                                Validation<F1, A>.Fail(var e) =>\n                                                                    Validation.FailI<F2, B>(first(e)),\n\n                                                                Validation<F1, A>.Success(var x) =>\n                                                                    Validation.SuccessI<F2, B>(second(x)),\n\n                                                                _ => throw new NSE()\n                                                            }),\n\n                                           _ => throw new NSE($\"Type {typeof(F1).Name} is not a valid monoid\")\n                                       });\n\n    static K<ValidationT<M>, F2, A> Bimonad<ValidationT<M>>.BindFirst<F1, F2, A>(\n        K<ValidationT<M>, F1, A> ma,\n        Func<F1, K<ValidationT<M>, F2, A>> f) =>\n        new ValidationT<F2, M, A>(ty => MonoidInstance<F1>.Instance switch\n                                       {\n                                           { IsSome: true, Value: { } tx } =>\n                                               ma.As2()\n                                                 .Run(tx)\n                                                 .Bind(v => v switch\n                                                            {\n                                                                Validation<F1, A>.Fail (var e) =>\n                                                                    f(e).As2().Run(ty),\n\n                                                                Validation<F1, A>.Success (var x) =>\n                                                                    M.Pure(Validation.SuccessI<F2, A>(x)),\n\n                                                                _ => throw new NSE()\n                                                            }),\n\n                                           _ => throw new NSE($\"Type {typeof(F1).Name} is not a valid monoid\")\n                                       });\n\n    static K<ValidationT<M>, F, B> Bimonad<ValidationT<M>>.BindSecond<F, A, B>(\n        K<ValidationT<M>, F, A> ma, \n        Func<A, K<ValidationT<M>, F, B>> f) =>\n        new ValidationT<F, M, B>(ty => MonoidInstance<F>.Instance switch\n                                       {\n                                           { IsSome: true, Value: { } tx } =>\n                                               ma.As2()\n                                                 .Run(tx)\n                                                 .Bind(v => v switch\n                                                            {\n                                                                Validation<F, A>.Fail (var e) =>\n                                                                    M.Pure(Validation.FailI<F, B>(e)),\n\n                                                                Validation<F, A>.Success (var x) =>\n                                                                    f(x).As2().Run(ty),\n\n                                                                _ => throw new NSE()\n                                                            }),\n\n                                           _ => throw new NSE($\"Type {typeof(F).Name} is not a valid monoid\")\n                                       });\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/Trait/ValidationT.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `ValidationT` \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class ValidationT<F, M> : \n    MonadT<ValidationT<F, M>, M>,\n    MonoidK<ValidationT<F, M>>,\n    Fallible<F, ValidationT<F, M>>, \n    Alternative<ValidationT<F, M>>,\n    MonadIO<ValidationT<F, M>>\n    where M : Monad<M>\n{\n    static K<ValidationT<F, M>, B> Monad<ValidationT<F, M>>.Bind<A, B>(\n        K<ValidationT<F, M>, A> ma, \n        Func<A, K<ValidationT<F, M>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<ValidationT<F, M>, B> Monad<ValidationT<F, M>>.Recur<A, B>(A value, Func<A, K<ValidationT<F, M>, Next<A, B>>> f) =>\n        new ValidationT<F, M, B>(semi =>\n            M.Recur<A, Validation<F, B>>(\n                value,\n                a => f(a).As()\n                         .runValidation(semi)\n                         .Map(e => e switch\n                                   {\n                                       Validation<F, Next<A, B>>.Fail(var err)               => Next.Done<A, Validation<F, B>>(err), \n                                       Validation<F, Next<A, B>>.Success({ IsDone: true } n) => Next.Done<A, Validation<F, B>>(n.Done), \n                                       Validation<F, Next<A, B>>.Success({ IsLoop: true } n) => Next.Loop<A, Validation<F, B>>(n.Loop),\n                                       _ => throw new NotSupportedException()\n                                   })));\n\n    static K<ValidationT<F, M>, B> Functor<ValidationT<F, M>>.Map<A, B>(\n        Func<A, B> f,\n        K<ValidationT<F, M>, A> ma) =>\n        new ValidationT<F, M, B>(monoid => ma.As().Run(monoid).Map(fa => fa.Map(f)));\n\n    static K<ValidationT<F, M>, A> Applicative<ValidationT<F, M>>.Pure<A>(A value) => \n        ValidationT.SuccessI<F, M, A>(value);\n\n    static K<ValidationT<F, M>, B> Applicative<ValidationT<F, M>>.Apply<A, B>(\n        K<ValidationT<F, M>, Func<A, B>> mf,\n        K<ValidationT<F, M>, A> ma) =>\n        new ValidationT<F, M, B>(monoid =>\n            from ff in mf.As().Run(monoid)\n            from fa in ma.As().Run(monoid)\n            select ff.ApplyI(fa, monoid).As());\n\n    static K<ValidationT<F, M>, B> Applicative<ValidationT<F, M>>.Apply<A, B>(\n        K<ValidationT<F, M>, Func<A, B>> mf,\n        Memo<ValidationT<F, M>, A> ma) =>\n        new ValidationT<F, M, B>(monoid =>\n            from ff in mf.As().Run(monoid)\n            from fa in ma.Value.As().Run(monoid)\n            select ff.ApplyI(fa, monoid).As());\n\n    static K<ValidationT<F, M>, A> MonadT<ValidationT<F, M>, M>.Lift<A>(K<M, A> ma) => \n        ValidationT.liftI<F, M, A>(ma);\n            \n    static K<ValidationT<F, M>, A> MonadIO<ValidationT<F, M>>.LiftIO<A>(IO<A> ma) => \n        ValidationT.liftIOI<F, M, A>(ma);\n\n    static K<ValidationT<F, M>, A> MonoidK<ValidationT<F, M>>.Empty<A>() =>\n        new ValidationT<F, M, A>(monoid => M.Pure(Validation.FailI<F, A>(monoid.Empty)));\n\n    static K<ValidationT<F, M>, A> Alternative<ValidationT<F, M>>.Empty<A>() =>\n        new ValidationT<F, M, A>(monoid => M.Pure(Validation.FailI<F, A>(monoid.Empty)));\n\n    static K<ValidationT<F, M>, A> SemigroupK<ValidationT<F, M>>.Combine<A>(\n        K<ValidationT<F, M>, A> ma,\n        K<ValidationT<F, M>, A> mb) =>\n        new ValidationT<F, M, A>(monoid => M.Bind(ma.As().Run(monoid),\n                                                  ea => ea.IsSuccess\n                                                            ? M.Pure(ea)\n                                                            : M.Map(eb => ea.CombineFirst(eb.As(), monoid), \n                                                                    mb.As().Run(monoid))));\n\n    static K<ValidationT<F, M>, A> Choice<ValidationT<F, M>>.Choose<A>(\n        K<ValidationT<F, M>, A> ma,\n        K<ValidationT<F, M>, A> mb) =>\n        new ValidationT<F, M, A>(monoid => M.Bind(ma.As().Run(monoid),\n                                                  ea => ea.IsSuccess\n                                                            ? M.Pure(ea)\n                                                            : mb.As().Run(monoid)));\n\n    static K<ValidationT<F, M>, A> Choice<ValidationT<F, M>>.Choose<A>(\n        K<ValidationT<F, M>, A> ma,\n        Memo<ValidationT<F, M>, A> mb) =>\n        new ValidationT<F, M, A>(monoid => M.Bind(ma.As().Run(monoid),\n                                                  ea => ea.IsSuccess\n                                                            ? M.Pure(ea)\n                                                            : mb.Value.As().Run(monoid)));\n\n    static K<ValidationT<F, M>, A> Fallible<F, ValidationT<F, M>>.Fail<A>(F error) => \n        ValidationT.FailI<F, M, A>(error);\n\n    static K<ValidationT<F, M>, A> Fallible<F, ValidationT<F, M>>.Catch<A>(\n        K<ValidationT<F, M>, A> fa,\n        Func<F, bool> Predicate,\n        Func<F, K<ValidationT<F, M>, A>> Fail) =>\n        fa.As().BindFail(e => Predicate(e) ? Fail(e).As() : ValidationT.FailI<F, M, A>(e));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/ValidationT.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class ValidationT\n{\n    public static ValidationT<L, M, A> Success<L, M, A>(A value)\n        where L : Monoid<L>\n        where M : Monad<M> =>\n        new (_ => M.Pure(Validation.Success<L, A>(value)));\n\n    public static ValidationT<L, M, A> Fail<L, M, A>(L value)  \n        where L : Monoid<L>\n        where M : Monad<M> =>\n        new (_ => M.Pure(Validation.Fail<L, A>(value)));\n\n    public static ValidationT<L, M, A> lift<L, M, A>(Validation<L, A> ma)\n        where L : Monoid<L>\n        where M : Monad<M> =>\n        new (_ => M.Pure(ma));\n\n    public static ValidationT<L, M, A> lift<L, M, A>(K<M, A> ma)  \n        where L : Monoid<L>\n        where M : Monad<M> =>\n        new (_ => ma.Map(Validation.Success<L, A>));\n\n    public static ValidationT<L, M, A> lift<L, M, A>(Pure<A> ma)  \n        where L : Monoid<L>\n        where M : Monad<M> =>\n        new (_ => M.Pure(Validation.Success<L, A>(ma.Value)));\n\n    public static ValidationT<L, M, A> lift<L, M, A>(Fail<L> ma)  \n        where L : Monoid<L>\n        where M : Monad<M> =>\n        new (_ => M.Pure(Validation.Fail<L, A>(ma.Value)));\n\n    public static ValidationT<L, M, A> liftIO<L, M, A>(IO<A> ma)  \n        where L : Monoid<L>\n        where M : MonadIO<M> =>\n        new (_ => M.LiftIO(ma).Map(Validation.Success<L, A>));\n    \n    public static K<M, B> match<F, M, A, B>(K<ValidationT<F, M>, A> ma, Func<F, B> Fail, Func<A, B> Succ) \n        where F : Monoid<F>\n        where M : Monad<M> =>\n        ma.Match(Fail, Succ);\n\n    internal static ValidationT<L, M, A> liftI<L, M, A>(Validation<L, A> ma)\n        where M : Monad<M> =>\n        new (_ => M.Pure(ma));\n\n    internal static ValidationT<L, M, A> liftI<L, M, A>(K<M, A> ma)  \n        where M : Monad<M> =>\n        new (_ => ma.Map(Validation.SuccessI<L, A>));\n\n    internal static ValidationT<L, M, A> liftIOI<L, M, A>(IO<A> ma)  \n        where M : Monad<M> =>\n        new (_ => M.LiftIOMaybe(ma).Map(Validation.SuccessI<L, A>));\n    \n    internal static ValidationT<L, M, A> SuccessI<L, M, A>(A value)  \n        where M : Monad<M> =>\n        new (_ => M.Pure(Validation.SuccessI<L, A>(value)));\n\n    internal static ValidationT<L, M, A> FailI<L, M, A>(L value)  \n        where M : Monad<M> =>\n        new (_ => M.Pure(Validation.FailI<L, A>(value)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Alternative Monads/ValidationT/ValidationT.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `ValidationT` monad transformer, which allows for an optional result. \n/// </summary>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"F\">Left value type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record ValidationT<F, M, A>(Func<MonoidInstance<F>, K<M, Validation<F, A>>> runValidation) : \n    K<ValidationT<F, M>, A>,\n    K<ValidationT<M>, F, A>\n    where M : Monad<M>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Match\n    //\n\n    internal Func<MonoidInstance<F>, K<M, B>> MatchI<B>(\n        Func<F, B> Fail,\n        Func<A, B> Succ) => \n        monoid => M.Map(mx => mx.Match(Fail, Succ), Run(monoid));\n    \n    public K<M, Validation<F, A>> Run(MonoidInstance<F> monoid) =>\n        runValidation(monoid);\n \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M1\">Target monad type</typeparam>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Mapped monad</returns>\n    public ValidationT<F, M1, B> MapT<M1, B>(Func<K<M, Validation<F, A>>, K<M1, Validation<F, B>>> f)\n        where M1 : Monad<M1> =>\n        new(monoid => f(runValidation(monoid)));\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    public ValidationT<F, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new(monoid => runValidation(monoid)\n               .Bind(fv => fv switch\n                           {\n                               Validation<F, A>.Success (var v) => f(M.Pure(v)).Map(Validation.SuccessI<F, B>),\n                               Validation<F, A>.Fail (var e)    => M.Pure<Validation<F, B>>(e),\n                               _                                => throw new NotSupportedException()\n                           }));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, B> Map<B>(Func<A, B> f) =>\n        new(monoid => M.Map(mx => mx.Map(f), runValidation(monoid)));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, B> Select<B>(Func<A, B> f) =>\n        new(monoid => M.Map(mx => mx.Map(f), runValidation(monoid)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, B> Bind<B>(Func<A, K<ValidationT<F, M>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, B> Bind<B>(Func<A, ValidationT<F, M, B>> f) =>\n        new(monoid => M.Bind(runValidation(monoid),\n                             ea => ea.IsSuccess switch\n                                   {\n                                       true  => f(ea.SuccessValue).runValidation(monoid),\n                                       false => M.Pure(Validation.FailI<F, B>(ea.FailValue))\n                                   }));    \n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"Succ\">Success mapping function</param>\n    /// <param name=\"Fail\">Failure mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, B> BiBind<B>(Func<A, ValidationT<F, M, B>> Succ, Func<F, ValidationT<F, M, B>> Fail) =>\n        new(monoid => M.Bind(runValidation(monoid),\n                             ea => ea.IsSuccess switch\n                                   {\n                                       true  => Succ(ea.SuccessValue).runValidation(monoid),\n                                       false => Fail(ea.FailValue).runValidation(monoid)\n                                   }));\n\n    /// <summary>\n    /// Failure bind operation\n    /// </summary>\n    /// <param name=\"Fail\">Failure mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, A> BindFail(Func<F, ValidationT<F, M, A>> Fail) =>\n        BiBind(ValidationT.SuccessI<F, M, A>, Fail);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, B> Bind<B>(Func<A, IO<B>> f) =>\n        Bind(a => ValidationT.liftIOI<F, M, B>(f(a)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(a => f(a).Value);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, C> SelectMany<B, C>(Func<A, K<ValidationT<F, M>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, C> SelectMany<B, C>(Func<A, ValidationT<F, M, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => ValidationT.liftI<F, M, B>(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, C> SelectMany<B, C>(Func<A, Validation<F, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => ValidationT.liftI<F, M, B>(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => M.LiftIOMaybe(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ValidationT`</returns>\n    public ValidationT<F, M, C> SelectMany<C>(Func<A, Guard<F, Unit>> bind, Func<A, Unit, C> project) =>\n        Bind(x => bind(x).ToValidationTI<F, M>().Map(_ => project(x, default)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n\n    public static implicit operator ValidationT<F, M, A>(Pure<A> ma) =>\n        ValidationT.SuccessI<F, M, A>(ma.Value);\n    \n    public static implicit operator ValidationT<F, M, A>(Fail<F> ma) =>\n        ValidationT.FailI<F, M, A>(ma.Value);\n\n    public static implicit operator ValidationT<F, M, A>(F fail) => \n        ValidationT.FailI<F, M, A>(fail);\n\n    public static implicit operator ValidationT<F, M, A>(IO<A> ma) =>\n        ValidationT.liftIOI<F, M, A>(ma);\n\n    public static ValidationT<F, M, Seq<A>> operator &(ValidationT<F, M, A> ma, ValidationT<F, M, A> mb) =>\n        new(monoid => M.Bind(ma.runValidation(monoid), ea => M.Map(eb => ea & eb, mb.runValidation(monoid))));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/ContT/ContT.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ContT;\n\npublic class ContT\n{\n    /// <summary>\n    /// Construct the terminal condition for the monad transformer\n    /// </summary>\n    /// <param name=\"value\">Pure value to terminate with</param>\n    /// <returns>`ContT`</returns>\n    public static ContT<A, M, A> Pure<M, A>(A value) \n        where M : Applicative<M> =>\n        new(f => f(value));\n    \n    public static ContT<R, M, A> lift<R, M, A>(Func<Func<A, K<M, R>>, K<M, R>> f) \n        where M : Applicative<M> =>\n        new(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/ContT/ContT.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.ContT;\n\n/// <summary>\n/// The continuation monad transformer.\n/// </summary>\n/// <remarks>\n/// Can be used to add continuation handling to any type constructor:\n/// the `Monad` trait-implementation and most of the operations do not\n/// require `M` to be a monad.\n/// </remarks>\n/// <param name=\"runCont\">The continuation</param>\n/// <typeparam name=\"R\"></typeparam>\n/// <typeparam name=\"M\"></typeparam>\n/// <typeparam name=\"A\"></typeparam>\npublic record ContT<R, M, A>(Func<Func<A, K<M, R>>, K<M, R>> runCont)\n    where M : Applicative<M>\n{\n    /// <summary>\n    /// Monadic bind operation\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    public ContT<R, M, B> Map<B>(Func<A, B> f) =>\n        new(c => runCont(x => c(f(x))));\n\n    /// <summary>\n    /// Monadic bind operation\n    /// </summary>\n    /// <param name=\"f\">Bind function</param>\n    public ContT<R, M, B> Bind<B>(Func<A, ContT<R, M, B>> f) =>\n        new(c => runCont(x => f(x).runCont(c)));\n\n    /// <summary>\n    /// Run the continuation, passing the final continuation\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <returns></returns>\n    public K<M, R> Run(Func<A, R> f) =>\n        runCont(x => M.Pure(f(x)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/ContT/README.md",
    "content": "## This type is currently work-in-progress.  Not ready for use."
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Extensions/Free.Extensions.MapApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FreeExtensions\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Free<F, B> Map<F, A, B>(this Func<A, B> f, K<Free<F>, A> ma) \n        where F : Functor<F> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Free<F, B> Map<F, A, B>(this Func<A, B> f, Free<F, A> ma) \n        where F : Functor<F> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Free<F, B> Action<F, A, B>(this Free<F, A> ma, K<Free<F>, B> mb) \n        where F : Functor<F> =>\n        Applicative.action(ma, mb).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Free<F, B> Action<F, A, B>(this K<Free<F>, A> ma, K<Free<F>, B> mb) \n        where F : Functor<F> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Free<F, B> Apply<F, A, B>(this Free<F, Func<A, B>> mf, K<Free<F>, A> ma)\n        where F : Functor<F> =>\n        Applicative.apply(mf, ma).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Free<F, B> Apply<F, A, B>(this K<Free<F>, Func<A, B>> mf, K<Free<F>, A> ma) \n        where F : Functor<F> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Extensions/Free.Extensions.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FreeExtensions\n{\n    public static Free<Fnctr, A> As<Fnctr, A>(this K<Free<Fnctr>, A> ma)\n        where Fnctr : Functor<Fnctr> =>\n        (Free<Fnctr, A>)ma;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Free.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class Free\n{\n    /// <summary>\n    /// Terminal case for the free monad\n    /// </summary>\n    /// <param name=\"value\">Terminal value</param>\n    /// <typeparam name=\"F\">Functor type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static Free<F, A> pure<F, A>(A value) \n        where F : Functor<F> =>\n        new Pure<F, A>(value);\n\n    /// <summary>\n    /// Lift the functor into the free monad\n    /// </summary>\n    /// <param name=\"value\">Functor that yields a `Free` monad</param>\n    /// <typeparam name=\"F\">Functor type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static Free<F, A> lift<F, A>(K<F, A> value) \n        where F : Functor<F> =>\n        new Bind<F, A>(value.Map(pure<F, A>));    \n    \n    /// <summary>\n    /// Monadic bind case for the free monad\n    /// </summary>\n    /// <param name=\"value\">Functor that yields a `Free` monad</param>\n    /// <typeparam name=\"F\">Functor type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static Free<F, A> bind<F, A>(K<F, Free<F, A>> value) \n        where F : Functor<F> =>\n        new Bind<F, A>(value);\n\n    /// <summary>\n    /// Lift a natural transformation from `F` to `G` into a natural-transformation from\n    /// `Free F` to `Free G`.\n    /// </summary>\n    /// <param name=\"fb\">Free monad in F</param>\n    /// <typeparam name=\"N\">Natural transformation</typeparam>\n    /// <typeparam name=\"F\">Functor</typeparam>\n    /// <typeparam name=\"G\">Functor</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Free monad in G</returns>\n    public static Free<G, A> hoist<F, G, A>(Free<F, A> fb)\n        where F : Functor<F>, Natural<F, G>\n        where G : Functor<G> =>\n        fb switch\n        {\n            Pure<F, A>(var x)  => pure<G, A>(x),\n            Bind<F, A>(var xs) => bind(F.Transform(xs).Map(hoist<F, G, A>)),\n            _                  => throw new NotSupportedException()\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Free.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Free monad makes any functor into a monad \n/// </summary>\n/// <typeparam name=\"F\">Functor type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record Free<F, A> : K<Free<F>, A>\n    where F : Functor<F>\n{\n    public Free<F, B> Map<B>(Func<A, B> f) =>\n        this.Kind().Map(f).As();\n    \n    public Free<F, B> Select<B>(Func<A, B> f) =>\n        this.Kind().Map(f).As();\n    \n    public Free<F, B> Bind<B>(Func<A, Free<F, B>> f) =>\n        this.Kind().Bind(f).As();\n    \n    public Free<F, B> Bind<B>(Func<A, K<Free<F>, B>> f) =>\n        this.Kind().Bind(f).As();\n    \n    public Free<F, C> SelectMany<B, C>(Func<A, K<Free<F>, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n}\n\n/// <summary>\n/// Terminal case for the free monad\n/// </summary>\n/// <param name=\"Value\">Terminal value</param>\n/// <typeparam name=\"F\">Functor type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic sealed record Pure<F, A>(A Value) : Free<F, A>\n    where F : Functor<F>;\n\n/// <summary>\n/// Monadic bind case for the free monad\n/// </summary>\n/// <param name=\"Value\">Functor that yields a `Free` monad</param>\n/// <typeparam name=\"F\">Functor type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic sealed record Bind<F, A>(K<F, Free<F, A>> Value) : Free<F, A>\n    where F : Functor<F>;\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Operators/Free.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FreeExtensions\n{\n    extension<Fun, A, B>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Free<Fun, B> operator >>> (K<Free<Fun>, A> ma, K<Free<Fun>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, B> operator * (K<Free<Fun>, Func<A, B>> mf, K<Free<Fun>, A> ma) =>\n            mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, B> operator * (K<Free<Fun>, A> ma, K<Free<Fun>, Func<A, B>> mf) =>\n            mf.Apply(ma);        \n    }\n    \n    extension<Fun, A, B, C>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, C>> operator * (\n            K<Free<Fun>, Func<A, B, C>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, C>> operator * (\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<Fun, A, B, C, D>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, D>>> operator * (\n            K<Free<Fun>, Func<A, B, C, D>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, D>>> operator * (\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<Fun, A, B, C, D, E>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Free<Fun>, Func<A, B, C, D, E>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<Fun, A, B, C, D, E, F>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Free<Fun>, Func<A, B, C, D, E, F>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<Fun, A, B, C, D, E, F, G>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Free<Fun>, Func<A, B, C, D, E, F, G>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<Fun, A, B, C, D, E, F, G, H>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Free<Fun>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<Fun, A, B, C, D, E, F, G, H, I>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Free<Fun>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<Fun, A, B, C, D, E, F, G, H, I, J>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Free<Fun>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<Fun, A, B, C, D, E, F, G, H, I, J, K>(K<Free<Fun>, A> self)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Free<Fun>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Free<Fun>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Free<Fun>, A> ma,\n            K<Free<Fun>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Operators/Free.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FreeExtensions\n{\n    extension<Fun, A, B>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, B> operator *(Func<A, B> f, K<Free<Fun>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, B> operator *(K<Free<Fun>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<Fun, A, B, C>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, C>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<Fun, A, B, C, D>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, D>>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<Fun, A, B, C, D, E>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<Fun, A, B, C, D, E, F>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<Fun, A, B, C, D, E, F, G>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<Fun, A, B, C, D, E, F, G, H>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<Fun, A, B, C, D, E, F, G, H, I>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<Fun, A, B, C, D, E, F, G, H, I, J>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<Fun, A, B, C, D, E, F, G, H, I, J, K>(K<Free<Fun>, A> _)\n        where Fun : Functor<Fun>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Free<Fun>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Free<Fun, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Free<Fun>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Operators/Free.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FreeExtensions\n{\n    extension<F, A, B>(K<Free<F>, A> self)\n        where F : Functor<F>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Free<F, B> operator >> (K<Free<F>, A> ma, Func<A, K<Free<F>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Free<F, B> operator >> (K<Free<F>, A> lhs, K<Free<F>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<F, A>(K<Free<F>, A> self)\n        where F : Functor<F>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Free<F, A> operator >> (K<Free<F>, A> lhs, K<Free<F>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Operators/Free.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IOExtensions\n{\n    extension<F, A>(K<Free<F>, A> _)\n        where F : Functor<F>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Free<F, A> operator +(K<Free<F>, A> ma) =>\n            (Free<F, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Free<F, A> operator >> (K<Free<F>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Prelude/Free.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static Free<F, B> map<F, A, B>(Func<A, B> f, K<Free<F>, A> ma) \n        where F : Functor<F> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static Free<F, B> action<F, A, B>(K<Free<F>, A> ma, K<Free<F>, B> mb) \n        where F : Functor<F> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static Free<F, B> apply<F, A, B>(K<Free<F>, Func<A, B>> mf, K<Free<F>, A> ma) \n        where F : Functor<F> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/Free/Trait/Free.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Free monad makes any functor into a monad \n/// </summary>\npublic class Free<F> : Monad<Free<F>>\n    where F : Functor<F>\n{\n    static K<Free<F>, B> Functor<Free<F>>.Map<A, B>(Func<A, B> f, K<Free<F>, A> ma)\n    {\n        return go(ma.As());\n        Free<F, B> go(Free<F, A> mx) =>\n            mx switch\n            {\n                Pure<F, A> (var a)  => new Pure<F, B>(f(a)),\n                Bind<F, A> (var fa) => new Bind<F, B>(F.Map(go, fa)),\n                _ => throw new InvalidOperationException()\n            };\n    }\n\n    static K<Free<F>, B> Monad<Free<F>>.Bind<A, B>(K<Free<F>, A> ma, Func<A, K<Free<F>, B>> f) =>\n        ma switch\n        {\n            Pure<F, A> (var a) => f(a),\n            Bind<F, A> (var m) => new Bind<F, B>(m.Map(mx => mx.Bind(f).As())),\n            _                  => throw new InvalidOperationException()\n        };\n\n    static K<Free<F>, B> Monad<Free<F>>.Recur<A, B>(A value, Func<A, K<Free<F>, Next<A, B>>> f) =>\n        Monad.unsafeRecur(value, f);\n    \n    static K<Free<F>, A> Applicative<Free<F>>.Pure<A>(A value) =>\n        new Pure<F, A>(value);\n\n    static K<Free<F>, B> Applicative<Free<F>>.Apply<A, B>(K<Free<F>, Func<A, B>> mf, K<Free<F>, A> ma) =>\n        (mf, ma) switch\n        {\n            (Pure<F, Func<A, B>> (var f), Pure<F, A> (var a)) => new Pure<F, B>(f(a)),\n            (Pure<F, Func<A, B>> (var f), Bind<F, A> (var a)) => new Bind<F, B>(a.Map(x => x.Map(f).As())),\n            (Bind<F, Func<A, B>> (var f), Bind<F, A> a)       => new Bind<F, B>(f.Map(x => x.Apply(a).As())),\n            _                                                 => throw new InvalidOperationException()\n        };\n\n    static K<Free<F>, B> Applicative<Free<F>>.Apply<A, B>(K<Free<F>, Func<A, B>> mf, Memo<Free<F>, A> ma) =>\n        (mf, ma.Value) switch\n        {\n            (Pure<F, Func<A, B>> (var f), Pure<F, A> (var a)) => new Pure<F, B>(f(a)),\n            (Pure<F, Func<A, B>> (var f), Bind<F, A> (var a)) => new Bind<F, B>(a.Map(x => x.Map(f).As())),\n            (Bind<F, Func<A, B>> (var f), Bind<F, A> a)       => new Bind<F, B>(f.Map(x => x.Apply(a).As())),\n            _                                                 => throw new InvalidOperationException()\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Identity/Extensions/Identity.Extensions.cs",
    "content": "﻿using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IdentityExtensions\n{\n    extension<A>(K<Identity, A> ma)\n    {\n        public Identity<A> As() =>\n            (Identity<A>)ma;\n\n        public A Run() =>\n            ((Identity<A>)ma).Value;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Identity/Identity.Module.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Identity\n{\n    public static Identity<A> Pure<A>(A value) =>\n        new (value);\n    \n    static K<Identity, A> PureK<A>(A value) =>\n        Pure(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Identity/Identity.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Identity monad\n/// </summary>\n/// <remarks>\n/// Simply carries the bound value through its bind expressions without imparting any additional behaviours.  It can\n/// be constructed using:\n///\n///     Identity〈int〉 ma = Id(123);\n/// \n/// </remarks>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record Identity<A>(A Value) : \n    K<Identity, A>,\n    IComparable<Identity<A>>\n{\n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<F, Identity<B>> Traverse<F, B>(Func<A, K<F, B>> f) \n        where F : Applicative<F> =>\n        F.Map(x => x.As(), Traversable.traverse(f, this));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    [Pure]\n    public K<M, Identity<B>> TraverseM<M, B>(Func<A, K<M, B>> f) \n        where M : Monad<M> =>\n        M.Map(x => x.As(), Traversable.traverseM(f, this));\n\n    [Pure]\n    public virtual bool Equals(Identity<A>? other) =>\n        other is not null && EqDefault<A>.Equals(Value, other.Value);\n\n    [Pure]\n    public override int GetHashCode() => \n        HashableDefault<A>.GetHashCode(Value);\n\n    [Pure]\n    public Identity<B> Map<B>(Func<A, B> f) =>\n        new(f(Value));\n\n    [Pure]\n    public Identity<B> Select<B>(Func<A, B> f) =>\n        new(f(Value));\n\n    [Pure]\n    public Identity<B> Bind<B>(Func<A, Identity<B>> f) =>\n        f(Value);\n\n    [Pure]\n    public Identity<B> Bind<B>(Func<A, K<Identity, B>> f) =>\n        f(Value).As();\n\n    [Pure]\n    public Identity<C> SelectMany<B, C>(Func<A, Identity<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    [Pure]\n    public Identity<C> SelectMany<B, C>(Func<A, K<Identity, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n\n    [Pure]\n    public int CompareTo(Identity<A>? other) =>\n        other is { } rhs\n            ? OrdDefault<A>.Compare(Value, rhs.Value)\n            : 1;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Identity/Operators/Identity.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class IdentityExtensions\n{\n    extension<A>(K<Identity, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Identity<A> operator +(K<Identity, A> ma) =>\n            (Identity<A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Identity<A> operator >> (K<Identity, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Identity/Trait/Identity.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Identity trait implementation\n/// </summary>\npublic partial class Identity : \n    Monad<Identity>, \n    Traversable<Identity>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monad\n    //\n    \n    static K<Identity, B> Monad<Identity>.Bind<A, B>(K<Identity, A> ma, Func<A, K<Identity, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<Identity, B> Monad<Identity>.Recur<A, B>(A value, Func<A, K<Identity, Next<A, B>>> f)\n    {\n        while (true)\n        {\n            var mr = +f(value);\n            if (mr.Value.IsDone) return new Identity<B>(mr.Value.Done);\n            value = mr.Value.Loop;\n        }\n    }\n\n    static K<Identity, B> Functor<Identity>.Map<A, B>(Func<A, B> f, K<Identity, A> ma) => \n        ma.As().Map(f);\n\n    static K<Identity, A> Applicative<Identity>.Pure<A>(A value) =>\n        new Identity<A>(value);\n\n    static K<Identity, B> Applicative<Identity>.Apply<A, B>(K<Identity, Func<A, B>> mf, K<Identity, A> ma) =>\n        mf.As().Bind(f => ma.As().Map(f));\n\n    static K<Identity, B> Applicative<Identity>.Apply<A, B>(K<Identity, Func<A, B>> mf, Memo<Identity, A> ma) =>\n        mf.As().Bind(f => ma.Value.As().Map(f));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Foldable\n    //\n\n    static S Foldable<Identity>.FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState,\n        K<Identity, A> ta)\n    {\n        var id = ta.As();\n        if (!predicate((initialState, id.Value))) return initialState;\n        return f(id.Value)(initialState);\n    }\n    \n    static S Foldable<Identity>.FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<Identity, A> ta)\n    {\n        var id = ta.As();\n        if (!predicate((initialState, id.Value))) return initialState;\n        return f(initialState)(id.Value);\n    }\n    \n    static Fold<A, S> Foldable<Identity>.FoldStep<A, S>(K<Identity, A> ta, S initialState) =>\n        Fold.Loop(initialState, ta.As().Value, Fold.Done<A, S>);\n        \n    static Fold<A, S> Foldable<Identity>.FoldStepBack<A, S>(K<Identity, A> ta, S initialState) =>\n        ta.FoldStep(initialState);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Traversable\n    //\n    \n    static K<F, K<Identity, B>> Traversable<Identity>.Traverse<F, A, B>(Func<A, K<F, B>> f, K<Identity, A> ta) =>\n        F.Map(PureK, f(ta.As().Value));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/IdentityT/IdentityT.Extensions.cs",
    "content": "﻿using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class IdentityTExt\n{\n    extension<M, A>(K<IdentityT<M>, A> ma) where M : Monad<M>\n    {\n        public IdentityT<M, A> As() =>\n            (IdentityT<M, A>)ma;\n\n        public K<M, A> Run() =>\n            ((IdentityT<M, A>)ma).Value;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/IdentityT/IdentityT.Module.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class IdentityT\n{\n    public static IdentityT<M, A> Pure<M, A>(A value) \n        where M : Monad<M> =>\n        new (M.Pure(value));\n\n    public static IdentityT<M, A> lift<M, A>(K<M, A> value) \n        where M : Monad<M> =>\n        new (value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/IdentityT/IdentityT.Monad.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Identity module\n/// </summary>\npublic class IdentityT<M> : \n    MonadT<IdentityT<M>, M>, \n    MonadUnliftIO<IdentityT<M>>\n    where M : Monad<M>\n{\n \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Monad\n    //\n    \n    static K<IdentityT<M>, B> Monad<IdentityT<M>>.Bind<A, B>(K<IdentityT<M>, A> ma, Func<A, K<IdentityT<M>, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<IdentityT<M>, B> Monad<IdentityT<M>>.Recur<A, B>(A value, Func<A, K<IdentityT<M>, Next<A, B>>> f) => \n        // TODO: Make a stack-safe version of this\n        Monad.unsafeRecur(value, f);\n\n    static K<IdentityT<M>, B> Functor<IdentityT<M>>.Map<A, B>(Func<A, B> f, K<IdentityT<M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<IdentityT<M>, A> Applicative<IdentityT<M>>.Pure<A>(A value) => \n        IdentityT.Pure<M, A>(value);\n\n    static K<IdentityT<M>, B> Applicative<IdentityT<M>>.Apply<A, B>(K<IdentityT<M>, Func<A, B>> mf, K<IdentityT<M>, A> ma) =>\n        mf.As().Bind(f => ma.As().Map(f));\n\n    static K<IdentityT<M>, B> Applicative<IdentityT<M>>.Apply<A, B>(K<IdentityT<M>, Func<A, B>> mf, Memo<IdentityT<M>, A> ma) =>\n        mf.As().Bind(f => ma.Value.As().Map(f));\n\n    static K<IdentityT<M>, A> MonadT<IdentityT<M>, M>.Lift<A>(K<M, A> ma) =>\n        IdentityT.lift(ma);\n\n    static K<IdentityT<M>, A> MonadIO<IdentityT<M>>.LiftIO<A>(IO<A> ma) => \n        IdentityT.lift(M.LiftIOMaybe(ma));\n\n    static K<IdentityT<M>, IO<A>> MonadUnliftIO<IdentityT<M>>.ToIO<A>(K<IdentityT<M>, A> ma) =>\n        new IdentityT<M, IO<A>>(M.ToIOMaybe(ma.As().Value));\n\n    static K<IdentityT<M>, B> MonadUnliftIO<IdentityT<M>>.MapIO<A, B>(K<IdentityT<M>, A> ma, Func<IO<A>, IO<B>> f) => \n        new IdentityT<M, B>(M.MapIOMaybe(ma.As().Value, f));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/IdentityT/IdentityT.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// IdentityT monad\n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record IdentityT<M, A>(K<M, A> Value) : K<IdentityT<M>, A>\n    where M : Monad<M>\n{\n    [Pure]\n    public IdentityT<M, B> Map<B>(Func<A, B> f) =>\n        new(M.Map(f, Value));\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    public IdentityT<M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new(f(Value));\n        \n    [Pure]\n    public IdentityT<M, B> Select<B>(Func<A, B> f) =>\n        new(M.Map(f, Value));\n    \n    [Pure]\n    public IdentityT<M, B> Bind<B>(Func<A, IdentityT<M, B>> f) =>\n        new(M.Bind(Value, x => f(x).Value));\n\n    [Pure]\n    public IdentityT<M, B> Bind<B>(Func<A, K<IdentityT<M>, B>> f) =>\n        new(M.Bind(Value, x => f(x).As().Value));\n\n    [Pure]\n    public IdentityT<M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        new(M.Map(x => f(x).Value, Value));\n\n    [Pure]\n    public IdentityT<M, B> Bind<B>(Func<A, IO<B>> f) =>\n        new(M.Bind(Value, x => M.LiftIOMaybe(f(x))));\n\n    [Pure]\n    public IdentityT<M, C> SelectMany<B, C>(Func<A, IdentityT<M, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    [Pure]\n    public IdentityT<M, C> SelectMany<B, C>(Func<A, K<IdentityT<M>, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n\n    [Pure]\n    public IdentityT<M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    [Pure]\n    public IdentityT<M, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n    \n    /// <summary>\n    /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n    /// as the semicolon) in C#.\n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the second action</returns>\n    public static IdentityT<M, A> operator >> (IdentityT<M, A> lhs, IdentityT<M, A> rhs) =>\n        lhs.Bind(_ => rhs);\n    \n    /// <summary>\n    /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n    /// as the semicolon) in C#.\n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the second action</returns>\n    public static IdentityT<M, A> operator >> (IdentityT<M, A> lhs, K<IdentityT<M>, A> rhs) =>\n        lhs.Bind(_ => rhs);\n    \n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static IdentityT<M, A> operator >> (IdentityT<M, A> lhs, IdentityT<M, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n\n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static IdentityT<M, A> operator >> (IdentityT<M, A> lhs, K<IdentityT<M>, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Lifting/Lift.Extensions.cs",
    "content": "using System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic static class LiftExtensions\n{\n    public static IO<A> ToIO<A>(this Lift<EnvIO, A> f) =>\n        IO.lift(f.Function);\n    \n    public static IO<A> ToIO<A>(this Lift<EnvIO, Task<A>> f) =>\n        IO.liftAsync(f.Function);    \n        \n    public static IO<A> ToIO<A>(this Lift<Task<A>> f) =>\n        IO.liftAsync(f.Function);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Lifting/Lift.Prelude.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Asynchronous IO lifting\n    //\n\n    /// <summary>\n    /// Lift an action\n    /// </summary>\n    /// <param name=\"action\">Function</param>\n    /// <returns>Value that can be used with monadic types in LINQ expressions</returns>\n    public static Lift<Unit> lift(Action action) =>\n        lift<Unit>(() =>\n                   {\n                       action();\n                       return default;\n                   });\n\n    /// <summary>\n    /// Lift a function \n    /// </summary>\n    /// <param name=\"function\">Function</param>\n    /// <returns>Value that can be used with monadic types in LINQ expressions</returns>\n    public static Lift<A> lift<A>(Func<A> function) =>\n        new(function);\n\n    /// <summary>\n    /// Lift a function \n    /// </summary>\n    /// <param name=\"function\">Function</param>\n    /// <returns>Value that can be used with monadic types in LINQ expressions</returns>\n    public static Lift<A, B> lift<A, B>(Func<A, B> function) =>\n        new(function);\n    \n    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Asynchronous IO lifting\n    //\n\n    /// <summary>\n    /// Lift a asynchronous IO action\n    /// </summary>\n    /// <param name=\"action\">Function</param>\n    /// <returns>Value that can be used with monadic types in LINQ expressions</returns>\n    public static IO<Unit> liftIO(Func<Task> action) =>\n        IO.liftAsync(async _ =>\n                     {\n                         await action().ConfigureAwait(false);\n                         return unit;\n                     });\n\n    /// <summary>\n    /// Lift a asynchronous IO action\n    /// </summary>\n    /// <param name=\"action\">Action</param>\n    /// <returns>Value that can be used with monadic types in LINQ expressions</returns>\n    public static IO<Unit> liftIO(Func<EnvIO, Task> action) =>\n        IO.liftAsync(async env =>\n                     {\n                         await action(env).ConfigureAwait(false);\n                         return unit;\n                     });\n\n    /// <summary>\n    /// Lift an asynchronous IO function \n    /// </summary>\n    /// <param name=\"function\">Function</param>\n    /// <returns>Value that can be used with monadic types in LINQ expressions</returns>\n    public static IO<A> liftIO<A>(Func<Task<A>> function) =>\n        IO.liftAsync(async () => await function().ConfigureAwait(false));\n\n    /// <summary>\n    /// Lift an asynchronous IO function \n    /// </summary>\n    /// <param name=\"function\">Function</param>\n    /// <returns>Value that can be used with monadic types in LINQ expressions</returns>\n    public static IO<A> liftIO<A>(Func<EnvIO, Task<A>> function) =>\n        IO.liftAsync<A>(async e => await function(e).ConfigureAwait(false));\n\n    /// <summary>\n    /// Lift an option into an `OptionT IO` \n    /// </summary>\n    public static OptionT<IO, A> liftIO<A>(Option<A> ma) =>\n        OptionT.lift<IO, A>(ma);\n\n    /// <summary>\n    /// Lift an Option into an `OptionT IO` \n    /// </summary>\n    public static OptionT<IO, A> liftIO<A>(Task<Option<A>> ma) =>\n        new(IO.liftAsync(async () => await ma.ConfigureAwait(false)));\n\n    /// <summary>\n    /// Lift an `Either` into a `EitherT IO` \n    /// </summary>\n    public static EitherT<L, IO, A> liftIO<L, A>(Either<L, A> ma) =>\n        EitherT.lift<L, IO, A>(ma);\n\n    /// <summary>\n    /// Lift an `Either` into a `EitherT IO` \n    /// </summary>\n    public static EitherT<L, IO, A> liftIO<L, A>(Task<Either<L, A>> ma) =>\n        new(IO.liftAsync(async () => await ma.ConfigureAwait(false)));\n\n    /// <summary>\n    /// Lift an `Either` into a `EitherT IO` \n    /// </summary>\n    public static FinT<IO, A> liftIO<A>(Task<Fin<A>> ma) =>\n        new(IO.liftAsync(async () => await ma.ConfigureAwait(false)));\n\n    /// <summary>\n    /// Lift a `Validation` into a `ValidationT IO` \n    /// </summary>\n    public static ValidationT<L, IO, A> liftIO<L, A>(Validation<L, A> ma) \n        where L : Monoid<L> =>\n        ValidationT.lift<L, IO, A>(ma);\n\n    /// <summary>\n    /// Lift a `Validation` into a `ValidationT IO` \n    /// </summary>\n    public static ValidationT<L, IO, A> liftIO<L, A>(Task<Validation<L, A>> ma) \n        where L : Monoid<L> =>\n        new(_ => IO.liftAsync(async () => await ma.ConfigureAwait(false)));\n    \n    /// <summary>\n    /// Lift the IO monad into a transformer-stack with an IO as its innermost monad.\n    /// </summary>\n    public static K<T, A> liftIO<T, M, A>(IO<A> ma)\n        where T : MonadT<T, M>\n        where M : Monad<M> => \n        T.Lift(M.LiftIOMaybe(ma));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Lifting/Lift.cs",
    "content": "\nusing System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Lifts a function into a type that can be used with other\n/// monadic types (in LINQ expressions, for example) and with implicit\n/// conversions.\n/// </summary>\npublic record Lift<A>(Func<A> Function)\n{\n    public K<F, A> ToApplicative<F>() \n        where F : Applicative<F> =>\n        F.Pure(unit).Map(_ => Function());\n\n    public IO<A> ToIO() =>\n        IO.lift(_ => Function());\n\n    public Eff<A> ToEff() =>\n        Eff<A>.Lift(Function);\n\n    public Eff<RT, A> ToEff<RT>() =>\n        Eff<RT, A>.Lift(Function);\n\n    public Lift<B> Map<B>(Func<A, B> f) =>\n        new (() => f(Function()));\n\n    public Lift<B> Bind<B>(Func<A, Lift<B>> f) =>\n        new(() => f(Function()).Function());\n\n    public Lift<B> Bind<B>(Func<A, Pure<B>> f) =>\n        new (() => f(Function()).Value);\n\n    public K<M, B> Bind<M, B>(Func<A, K<M, B>> f)\n        where M : Monad<M> =>\n        M.Pure(unit).Map(_ => Function()).Bind(f);\n\n    public IO<B> Bind<B>(Func<A, IO<B>> f) =>\n        ToIO().Bind(f);\n\n    public Lift<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    public IO<C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) => \n        ToIO().SelectMany(bind, project);\n\n    public K<M, C> SelectMany<M, B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project)  \n        where M : Monad<M> =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    public Lift<C> SelectMany<B, C>(Func<A, Lift<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    public Lift<C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n}\n\n/// <summary>\n/// Lifts a function into a type that can be used with other\n/// monadic types (in LINQ expressions, for example) and with implicit\n/// conversions.\n/// </summary>\npublic record Lift<A, B>(Func<A, B> Function)\n{\n    public Lift<A, C> Map<C>(Func<B, C> f) =>\n        new (x => f(Function(x)));\n\n    public Lift<A, C> Bind<C>(Func<B, Lift<A, C>> f) =>\n        new(x => f(Function(x)).Function(x));\n\n    public Lift<A, C> Bind<C>(Func<B, Pure<C>> f) =>\n        new (x => f(Function(x)).Value);\n\n    public Lift<A, C> Select<C>(Func<B, C> f) =>\n        Map(f);\n\n    public Lift<A, D> SelectMany<C, D>(Func<B, Pure<C>> bind, Func<B, C, D> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Monadic conditionals/Prelude.guard.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Guard against continuing an applicative expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <returns>Applicative that yields `()` if `flag` is `true`; otherwise it yields `Applicative.Empty` - \n    /// shortcutting the expression</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static K<F, Unit> guard<F>(bool flag)\n        where F : MonoidK<F>, Applicative<F> =>\n        flag ? F.Pure(unit) : F.Empty<Unit>();\n    \n    /// <summary>\n    /// Guard against continuing an applicative expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <returns>Applicative that yields `()` if `flag` is `true`; otherwise it yields `Applicative.Empty` - \n    /// shortcutting the expression</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IO<Unit> guardIO(bool flag) =>\n        flag ? IO.pure(unit) : IO.empty<Unit>();\n    \n    /// <summary>\n    /// Guard against continuing a monadic expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <param name=\"False\">If the flag is false, this provides the error</param>\n    /// <returns>Guard</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Guard<E, Unit> guard<E>(bool flag, Func<E> False) =>\n        new (flag, False);\n\n    /// <summary>\n    /// Guard against continuing a monadic expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <param name=\"False\">If the flag is false, this provides the error</param>\n    /// <returns>Guard</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Guard<E, Unit> guard<E>(bool flag, E False) =>\n        new (flag, False);\n\n    /// <summary>\n    /// Guard against continuing a monadic expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <param name=\"False\">If the flag is false, this provides the error</param>\n    /// <returns>Guard</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Guard<Error, Unit> guard(bool flag, Func<Error> False) =>\n        new (flag, False);\n\n    /// <summary>\n    /// Guard against continuing a monadic expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <param name=\"False\">If the flag is false, this provides the error</param>\n    /// <returns>Guard</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Guard<Error, Unit> guard(bool flag, Error False) =>\n        new (flag, False);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Monadic conditionals/Prelude.guardnot.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Guard against continuing a monadic expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <param name=\"True\">If the flag is false, this provides the error</param>\n    /// <returns>Guard</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Guard<E, Unit> guardnot<E>(bool flag, Func<E> True) =>\n        new (!flag, True);\n\n    /// <summary>\n    /// Guard against continuing a monadic expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <param name=\"True\">If the flag is false, this provides the error</param>\n    /// <returns>Guard</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Guard<E, Unit> guardnot<E>(bool flag, E True) =>\n        new (!flag, True);\n\n    /// <summary>\n    /// Guard against continuing a monadic expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <param name=\"True\">If the flag is false, this provides the error</param>\n    /// <returns>Guard</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Guard<Error, Unit> guardnot(bool flag, Func<Error> True) =>\n        new (!flag, True);\n\n    /// <summary>\n    /// Guard against continuing a monadic expression\n    /// </summary>\n    /// <param name=\"flag\">Flag for continuing</param>\n    /// <param name=\"True\">If the flag is false, this provides the error</param>\n    /// <returns>Guard</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Guard<Error, Unit> guardnot(bool flag, Error True) =>\n        new (!flag, True);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Monadic conditionals/Prelude.iff.cs",
    "content": "using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<M, A> Then, K<M, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? Then : Else);\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<M, A> Then, K<IO, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? Then : M.LiftIOMaybe(Else));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<IO, A> Then, K<M, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.LiftIOMaybe(Then) : Else);\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<IO, A> Then, K<IO, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.LiftIOMaybe(Then) : M.LiftIOMaybe(Else));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<M, A> Then, Pure<A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? Then : M.Pure(Else.Value));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, Pure<A> Then, K<M, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.Pure(Then.Value) : Else);\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, Pure<A> Then, Pure<A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.Pure(Then.Value) : M.Pure(Else.Value));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, Pure<A> Then, K<IO, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.Pure(Then.Value) : M.LiftIOMaybe(Else));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<IO, A> Then, Pure<A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.LiftIOMaybe(Then) : M.Pure(Else.Value));\n\n    /// <summary>\n    /// If this then that for higher-kinds\n    /// </summary>\n    /// <param name=\"Pred\">Boolean flag to be computed</param>\n    /// <param name=\"Then\">Then branch if the flag computes to `true`</param>\n    /// <param name=\"Else\">Else branch if the flag computes to `false`</param>\n    /// <typeparam name=\"F\">Trait type</typeparam>\n    /// <typeparam name=\"A\">Bound return value</typeparam>\n    /// <returns>Returns either the `then` or `else` branches depending on the computed `flag`</returns>\n    public static K<F, A> iff<F, A>(bool Pred, K<F, A> Then, K<F, A> Else) =>\n        Pred ? Then : Else;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Monadic conditionals/Prelude.unless.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Conditional execution of `Applicative` expressions\n    /// \n    /// Run the `alternative` when the `flag` is `false`, return `pure ()` when `true`\n    /// </summary>\n    /// <param name=\"flag\">If `false` the `alternative` is run</param>\n    /// <param name=\"alternative\">Computation to run if the flag is `false`</param>\n    /// <returns>Either the result of the `alternative` computation if the `flag` is `false` or `Unit`</returns>\n    /// <example>\n    ///\n    ///     from x in ma\n    ///     from _ in unless(x == 100, Console.writeLine〈RT〉(\"x should be 100!\"))\n    ///     select x;\n    /// \n    /// </example>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static K<F, Unit> unless<F>(bool flag, K<F, Unit> alternative)\n        where F : Applicative<F> =>\n        Applicative.unless(flag, alternative);\n    \n    /// <summary>\n    /// When the predicate evaluates to `false`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> unless<M>(K<M, bool> Pred, K<M, Unit> Then)\n        where M : Monad<M> =>\n        Pred.Bind(f => Applicative.unless(f, Then));\n\n    /// <summary>\n    /// When the predicate evaluates to `false`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> unless<M>(K<M, bool> Pred, K<IO, Unit> Then)\n        where M : MonadIO<M> =>\n        Pred.Bind(f => Applicative.unless(f, Then).As());\n\n    /// <summary>\n    /// When the predicate evaluates to `false`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> unless<M>(K<M, bool> Pred, Pure<Unit> Then)\n        where M : Monad<M> =>\n        Pred.Bind(f => Applicative.unless(f, M.Pure(unit)));\n    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Monadic conditionals/Prelude.when.cs",
    "content": "using System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Conditional execution of `Applicative` expressions\n    /// \n    /// Run the `alternative` when the `flag` is `true`, return `pure ()` when `false`\n    /// </summary>\n    /// <param name=\"flag\">If `true` the `alternative` is run</param>\n    /// <param name=\"alternative\">Computation to run if the `flag` is `true`</param>\n    /// <returns>Either the result of the `alternative` computation if the `flag` is `true` or `Unit`</returns>\n    /// <example>\n    ///\n    ///     from x in ma\n    ///     from _ in when(x == 100, Console.writeLine〈RT〉(\"x is 100, finally!\"))\n    ///     select x;\n    /// \n    /// </example>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static K<F, Unit> when<F>(bool flag, K<F, Unit> alternative)\n        where F : Applicative<F> =>\n        Applicative.when(flag, alternative);\n    \n    /// <summary>\n    /// When the predicate evaluates to `true`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> when<M>(K<M, bool> Pred, K<M, Unit> Then)\n        where M : Monad<M> =>\n        Pred.Bind(f => Applicative.when(f, Then));\n\n    /// <summary>\n    /// When the predicate evaluates to `true`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> when<M>(K<M, bool> Pred, K<IO, Unit> Then)\n        where M : MonadIO<M> =>\n        Pred.Bind(f => Applicative.when(f, Then).As());\n\n    /// <summary>\n    /// When the predicate evaluates to `true`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> when<M>(K<M, bool> Pred, Pure<Unit> Then)\n        where M : Monad<M> =>\n        Pred.Bind(f => Applicative.when(f, M.Pure(unit)));    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Monadic conditionals/README.md",
    "content": "`guard`, `when`, and `unless` allow for conditional operations and short-cutting in monadic expressions.\n\n## Guards\n\nGuards are used to stop the monadic expression continuing if a flag is `true` (for `guard`) or `false` (for `guardnot`).  \n\nThey only work with monads that have an _'alternative value'_ (which is usually used as the error condition: `Left` in \n`Either` for example).  An alternative value is provided when the guard triggers:  \n\n    from x in ma\n    from _ in guard(x == 100, Error.New(\"x should be 100\"))\n    select x;\n\nSupported monads are:\n\n    Either\n    EitherUnsafe\n    EitherAsync\n    Fin\n    Validation\n    Aff\n    Eff\n\n## When and Unless\n\n`when` and `unless` are similar to guards, but instead of providing _the_ alternative value, you provide an alternative monad \nto run.  This monad could be in a failed state, or it could run a successful _side effect_ (an `Eff` calling `Console<RT>.writeLine()` \nfor example).\n\n    from x in ma\n    from _ in when(x == 100, Console.writeLine<RT>(\"x is 100, finally!\"))\n    select x;\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Prelude.cs",
    "content": "﻿using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Construct identity monad\n    /// </summary>\n    public static Identity<A> Id<A>(A value) =>\n        Identity.Pure(value);\n\n    /// <summary>\n    /// Construct identity monad\n    /// </summary>\n    public static IdentityT<M, A> Id<M, A>(A value) \n        where M : Monad<M>, Choice<M> =>\n        IdentityT.Pure<M, A>(value);\n\n    /// <summary>\n    /// Create a new Pure monad.  This monad doesn't do much, but when combined with\n    /// other monads, it allows for easier construction of pure lifted values.\n    ///\n    /// There are various bind operators that make it work with these types:\n    ///\n    ///     * Option\n    ///     * Eff\n    ///     * Either\n    ///     * Fin\n    ///     * IO\n    ///     * Validation\n    ///     \n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Pure monad</returns>\n    public static Pure<A> Pure<A>(A value) =>\n        new(value);\n\n    /// <summary>\n    /// Create a new Fail monad: the monad that always fails.  This monad doesn't do much,\n    /// but when combined with other monads, it allows for easier construction of lifted \n    /// failure values.\n    ///\n    /// There are various bind operators that make it work with these types:\n    ///\n    ///     * Option\n    ///     * Eff\n    ///     * Either\n    ///     * Fin\n    ///     * IO\n    ///     * Validation\n    ///     \n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Pure monad</returns>\n    public static Fail<E> Fail<E>(E error) =>\n        new(error);\n\n    /// <summary>\n    /// Extractor for types that support lowering via operators  \n    /// </summary>\n    /// <example>\n    /// For example:\n    ///\n    ///     Pure(123) >> lower == 123\n    /// </example>\n    public static readonly Lower lower = default;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/README.md",
    "content": "Not all of the monadic types are in this section, but most of them \nare.  The other monadic types are [the collections](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/index.html), and the\n[effect-system monads of `IO`, `Eff`, `StreamT`](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/index.html), \nand [`Pipes`](https://louthy.github.io/language-ext/LanguageExt.Pipes/index.html)\n\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Extensions/RWST.Extensions.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class RWSTExtensions\n{\n    public static RWST<R, W, S, M, A> As<R, W, S, M, A>(this K<RWST<R, W, S, M>, A> ma) \n        where M : Monad<M>\n        where W : Monoid<W> =>\n        (RWST<R, W, S, M, A>)ma;\n    \n    public static K<M, (A Value, W Output, S State)> Run<R, W, S, M, A>(\n        this K<RWST<R, W, S, M>, A> ma, R env, W output, S state) \n        where M : Monad<M>\n        where W : Monoid<W> =>\n        ma.As().runRWST((env, output, state));\n    \n    public static K<M, (A Value, W Output, S State)> Run<R, W, S, M, A>(\n        this K<RWST<R, W, S, M>, A> ma, R env, S state) \n        where M : Monad<M>\n        where W : Monoid<W> =>\n        ma.As().runRWST((env, W.Empty, state));\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static RWST<R, W, S, M, A> Flatten<R, W, S, M, A>(this RWST<R, W, S, M, RWST<R, W, S, M, A>> mma)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        mma.Bind(x => x);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static RWST<R, W, S, M, A> Flatten<R, W, S, M, A>(this RWST<R, W, S, M, K<RWST<R, W, S, M>, A>> mma)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        mma.Bind(x => x);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public static RWST<R, W, S, M, C> SelectMany<R, W, S, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<RWST<R, W, S, M>, B>> bind, \n        Func<A, B, C> project)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        RWST<R, W, S, M, A>.Lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public static RWST<R, W, S, M, C> SelectMany<R, W, S, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, RWST<R, W, S, M, B>> bind, \n        Func<A, B, C> project)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        RWST<R, W, S, M, A>.Lift(ma).SelectMany(bind, project);    \n    \n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public static RWST<R, W, S, M, C> SelectMany<R, W, S, M, A, B, C>(\n        this K<IO, A> ma, \n        Func<A, K<RWST<R, W, S, M>, B>> bind, \n        Func<A, B, C> project)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        RWST<R, W, S, M, A>.LiftIO(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public static RWST<R, W, S, M, C> SelectMany<R, W, S, M, A, B, C>(\n        this K<IO, A> ma, \n        Func<A, RWST<R, W, S, M, B>> bind, \n        Func<A, B, C> project)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        RWST<R, W, S, M, A>.LiftIO(ma).SelectMany(bind, project);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Operators/RWST.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class RWSTExtensions\n{\n    extension<R, W, S, M, A, B>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static RWST<R, W, S, M, B> operator >>> (K<RWST<R, W, S, M>, A> ma, K<RWST<R, W, S, M>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, B> operator * (K<RWST<R, W, S, M>, Func<A, B>> mf, K<RWST<R, W, S, M>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, B> operator * (K<RWST<R, W, S, M>, A> ma, K<RWST<R, W, S, M>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<R, W, S, M, A, B, C>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, C>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, C>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<R, W, S, M, A, B, C, D>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, D>>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C, D>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, D>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<R, W, S, M, A, B, C, D, E>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<R, W, S, M, A, B, C, D, E, F>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<R, W, S, M, A, B, C, D, E, F, G>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<R, W, S, M, A, B, C, D, E, F, G, H>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<R, W, S, M, A, B, C, D, E, F, G, H, I>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<R, W, S, M, A, B, C, D, E, F, G, H, I, J>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<R, W, S, M, A, B, C, D, E, F, G, H, I, J, K>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<RWST<R, W, S, M>, A> ma,\n            K<RWST<R, W, S, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Operators/RWST.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class RWSTExtensions\n{\n    extension<R, W, S, M, A>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>, Choice<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static RWST<R, W, S, M, A> operator |(K<RWST<R, W, S, M>, A> lhs, K<RWST<R, W, S, M>, A> rhs) =>\n            new (env => lhs.As().runRWST(env) | rhs.As().runRWST(env));\n\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static RWST<R, W, S, M, A> operator |(K<RWST<R, W, S, M>, A> lhs, Pure<A> rhs) =>\n            new (env => lhs.As().runRWST(env) | rhs.Map(x => (x, env.Output, env.State)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Operators/RWST.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class RWSTExtensions\n{\n    extension<R, W, S, E, M, A>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>, Fallible<E, M>\n        where W : Monoid<W>\n    {\n        public static RWST<R, W, S, M, A> operator |(K<RWST<R, W, S, M>, A> lhs, CatchM<E, M, A> rhs) =>\n            new(env => lhs.As().runRWST(env) | rhs.Map(a => (a, env.Output, env.State)));\n\n        public static RWST<R, W, S, M, A> operator |(K<RWST<R, W, S, M>, A> lhs, Fail<E> rhs) =>\n            new(env => lhs.As().runRWST(env) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Operators/RWST.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class RWSTExtensions\n{\n    extension<R, W, S, X, M, A>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>, Final<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static RWST<R, W, S, M, A> operator |(K<RWST<R, W, S, M>, A> lhs, Finally<M, X> rhs) =>\n            new(env => lhs.As().runRWST(env) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Operators/RWST.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class RWSTExtensions\n{\n    extension<R, W, S, M, A, B>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, B> operator *(Func<A, B> f, K<RWST<R, W, S, M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, B> operator *(K<RWST<R, W, S, M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<R, W, S, M, A, B, C>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, C>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<R, W, S, M, A, B, C, D>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, D>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<R, W, S, M, A, B, C, D, E>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<R, W, S, M, A, B, C, D, E, F>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<R, W, S, M, A, B, C, D, E, F, G>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<R, W, S, M, A, B, C, D, E, F, G, H>(K<RWST<R, W, S, M>, A> _)\n        where W : Monoid<W>\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<R, W, S, M, A, B, C, D, E, F, G, H, I>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<R, W, S, M, A, B, C, D, E, F, G, H, I, J>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<R, W, S, M, A, B, C, D, E, F, G, H, I, J, K>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<RWST<R, W, S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static RWST<R, W, S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<RWST<R, W, S, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Operators/RWST.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class RWSTExtensions\n{\n    extension<R, W, S, M, A, B>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static RWST<R, W, S, M, B> operator >> (K<RWST<R, W, S, M>, A> ma, Func<A, K<RWST<R, W, S, M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static RWST<R, W, S, M, B> operator >> (K<RWST<R, W, S, M>, A> lhs, K<RWST<R, W, S, M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<R, W, S, M, A>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static RWST<R, W, S, M, A> operator >> (K<RWST<R, W, S, M>, A> lhs, K<RWST<R, W, S, M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Operators/RWST.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class RWSTExtensions\n{\n    extension<R, W, S, M, A>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static RWST<R, W, S, M, A> operator +(K<RWST<R, W, S, M>, A> lhs, K<RWST<R, W, S, M>, A> rhs) =>\n            new(env => lhs.As().runRWST(env) + rhs.As().runRWST(env));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static RWST<R, W, S, M, A> operator +(K<RWST<R, W, S, M>, A> lhs, Pure<A> rhs) =>\n            new(env => lhs.As().runRWST(env) + M.Pure((rhs.Value, env.Output, env.State)));\n    }\n    \n    extension<E, R, W, S, M, A>(K<RWST<R, W, S, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Fallible<E, M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static RWST<R, W, S, M, A> operator +(K<RWST<R, W, S, M>, A> lhs, Fail<E> rhs) =>\n            new(env => lhs.As().runRWST(env) + M.Fail<(A, W, S)>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Operators/RWST.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class RWSTExtensions\n{\n    extension<R, W, S, M, A>(K<RWST<R, W, S, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static RWST<R, W, S, M, A> operator +(K<RWST<R, W, S, M>, A> ma) =>\n            (RWST<R, W, S, M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static RWST<R, W, S, M, A> operator >> (K<RWST<R, W, S, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/RWST.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class RWST\n{\n    public static RWST<R, W, S, M, A> pure<R, W, S, M, A>(A value)  \n        where W : Monoid<W>\n        where M : Monad<M> => \n        RWST<R, W, S, M, A>.Pure(value);\n\n    public static RWST<R, W, S, M, A> lift<R, W, S, M, A>(K<M, A> ma)  \n        where W : Monoid<W>\n        where M : Monad<M> => \n        RWST<R, W, S, M, A>.Lift(ma);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"effect\">Monad to lift</param>\n    /// <returns>`ReaderT`</returns>\n    public static RWST<R, W, S, M, A> liftIO<R, W, S, M, A>(IO<A> effect)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        RWST<R, W, S, M, A>.LiftIO(effect);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Reader behaviours\n    //\n    \n    public static RWST<R, W, S, M, R> ask<R, W, S, M>() \n        where W : Monoid<W>\n        where M : Monad<M> => \n        Readable.ask<RWST<R, W, S, M>, R>().As();\n\n    public static RWST<R, W, S, M, A> asks<R, W, S, M, A>(Func<R, A> f)  \n        where W : Monoid<W>\n        where M : Monad<M> => \n        Readable.asks<RWST<R, W, S, M>, R, A>(f).As();\n\n    public static RWST<R, W, S, M, A> asksM<R, W, S, M, A>(Func<R, K<M, A>> f)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        RWST<R, W, S, M, A>.AsksM(f);\n\n    public static RWST<R, W, S, M, A> asksM<R, W, S, M, A>(Func<R, K<RWST<R, W, S, M>, A>> f)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        Readable.asksM(f).As();\n\n    public static RWST<R, W, S, M, A> local<R, W, S, M, A>(Func<R, R> f, K<RWST<R, W, S, M>, A> ma)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        Readable.local(f, ma).As();\n\n    public static RWST<R, W, S, M, A> with<R, R1, W, S, M, A>(Func<R, R1> f, K<RWST<R1, W, S, M>, A> ma) \n        where W : Monoid<W>\n        where M : Monad<M> => \n        ma.As().With(f);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Writer behaviours\n    //\n\n    /// <summary>\n    /// Tell is an action that produces the writer output\n    /// </summary>\n    /// <param name=\"item\">Item to tell</param>\n    /// <typeparam name=\"W\">Writer type</typeparam>\n    /// <returns>Structure with the told item</returns>\n    public static RWST<R, W, S, M, Unit> tell<R, W, S, M>(W item)\n        where M : Monad<M>\n        where W : Monoid<W> =>\n        Writable.tell<RWST<R, W, S, M>, W>(item).As();\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static RWST<R, W, S, M, A> write<R, W, S, M, A>((A, W) item)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        Writable.write<W, RWST<R, W, S, M>, A>(item).As();\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static RWST<R, W, S, M, A> write<R, W, S, M, A>(A value, W item)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        Writable.write<W, RWST<R, W, S, M>, A>(value, item).As();\n\n    /// <summary>\n    /// `pass` is an action that executes the `action`, which returns a value and a\n    /// function; it then returns the value with the output having been applied to\n    /// the function.\n    /// </summary>\n    public static RWST<R, W, S, M, A> pass<R, W, S, M, A>(RWST<R, W, S, M, (A Value, Func<W, W> Function)> action)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        Writable.pass(action).As();\n\n    /// <summary>\n    /// `listen` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static RWST<R, W, S, M, (A Value, W Output)> listen<R, W, S, M, A>(RWST<R, W, S, M, A> ma)\n        where M : Monad<M>\n        where W : Monoid<W> =>\n        Writable.listen<W, RWST<R, W, S, M>, A>(ma).As();\n\n    /// <summary>\n    /// `listens` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static RWST<R, W, S, M, (A Value, B Output)> listens<R, W, S, M, A, B>(Func<W, B> f, RWST<R, W, S, M, A> ma)\n        where M : Monad<M>\n        where W : Monoid<W> =>\n        Writable.listens(f, ma).As();\n\n    /// <summary>\n    /// `censor` executes the action `ma` and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public static RWST<R, W, S, M, A> censor<R, W, S, M, A>(Func<W, W> f, RWST<R, W, S, M, A> ma)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        Writable.censor(f, ma).As();    \n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  State behaviours\n    //\n    \n    public static RWST<R, W, S, M, S> get<R, W, S, M>()\n        where W : Monoid<W>\n        where M : Monad<M> => \n        Stateful.get<RWST<R, W, S, M>, S>().As();\n    \n    public static RWST<R, W, S, M, A> gets<R, W, S, M, A>(Func<S, A> f) \n        where W : Monoid<W>\n        where M : Monad<M> => \n        Stateful.gets<RWST<R, W, S, M>, S, A>(f).As();\n\n    public static RWST<R, W, S, M, A> getsM<R, W, S, M, A>(Func<S, K<M, A>> f) \n        where W : Monoid<W>\n        where M : Monad<M> => \n        RWST<R, W, S, M, A>.GetsM(f);\n\n    public static RWST<R, W, S, M, A> getsM<R, W, S, M, A>(Func<S, K<RWST<R, W, S, M>, A>> f) \n        where W : Monoid<W>\n        where M : Monad<M> => \n        Stateful.getsM(f).As();\n\n    public static RWST<R, W, S, M, Unit> put<R, W, S, M>(S state)  \n        where W : Monoid<W>\n        where M : Monad<M> => \n        Stateful.put<RWST<R, W, S, M>, S>(state).As();\n\n    public static RWST<R, W, S, M, Unit> modify<R, W, S, M>(Func<S, S> f)  \n        where W : Monoid<W>\n        where M : Monad<M> => \n        Stateful.modify<RWST<R, W, S, M>, S>(f).As();\n\n    public static RWST<R, W, S, M, Unit> modifyM<R, W, S, M>(Func<S, K<M, S>> f)  \n        where W : Monoid<W>\n        where M : Monad<M> =>\n        RWST<R, W, S, M, Unit>.ModifyM(f);\n\n    public static RWST<R, W, S, M, Unit> modifyM<R, W, S, M>(Func<S, K<RWST<R, W, S, M>, S>> f)  \n        where W : Monoid<W>\n        where M : Monad<M> =>\n        Stateful.modifyM(f).As();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/RWST.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Reader / Write / State monad-transformer\n/// </summary>\n/// <typeparam name=\"R\">Reader environment type</typeparam>\n/// <typeparam name=\"W\">Writer output type</typeparam>\n/// <typeparam name=\"S\">State type</typeparam>\n/// <typeparam name=\"M\">Lifted monad type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record RWST<R, W, S, M, A>(Func<(R Env, W Output, S State), K<M, (A Value, W Output, S State)>> runRWST): \n    K<RWST<R, W, S, M>, A>\n    where M : Monad<M>\n    where W : Monoid<W>\n{\n    public static RWST<R, W, S, M, A> Pure(A value) =>\n        new (input => M.Pure((value, input.Output, input.State)));\n    \n    public static RWST<R, W, S, M, A> Lift(K<M, A> ma) =>\n        new (input => ma.Map(a => (a, input.Output, input.State)));\n    \n    public static RWST<R, W, S, M, A> Lift(Pure<A> ma) =>\n        new (input => M.Pure((ma.Value, input.Output, input.State)));\n    \n    public static RWST<R, W, S, M, A> LiftIO(K<IO, A> ma) =>\n        new (input => M.LiftIOMaybe(ma).Map(a => (a, input.Output, input.State)));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Reader behaviours\n    //\n    \n    /// <summary>\n    /// Extracts the environment value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">Environment mapping function</param>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, A> Asks(Func<R, A> f) =>\n        new(input => M.Pure((f(input.Env), input.Output, input.State)));\n\n    /// <summary>\n    /// Extracts the environment value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">Environment mapping function</param>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, A> AsksM(Func<R, K<M, A>> f) =>\n        new(input => f(input.Env).Map(a => (a, input.Output, input.State)));\n\n    /// <summary>\n    /// Maps the Reader's environment value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`RWST`</returns>\n    public RWST<R1, W, S, M, A> With<R1>(Func<R1, R> f) =>\n        new(input => runRWST((f(input.Env), input.Output, input.State)));\n\n    /// <summary>\n    /// Maps the Reader's environment value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, A> Local(Func<R, R> f) =>\n        new(input => runRWST((f(input.Env), input.Output, input.State)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Writer behaviours\n    //\n\n    /// <summary>\n    /// Construct a writer computation from a (result, output) pair.\n    /// </summary>\n    /// <remarks>\n    /// The inverse of `Run()`\n    /// </remarks>\n    /// <param name=\"result\">Result / Output pair</param>\n    public static RWST<R, W, S, M, A> Write((A Value, W Output) result) =>\n        Writable.write<W, RWST<R, W, S, M>, A>(result).As();\n\n    /// <summary>\n    /// Construct a writer computation from a (result, output) pair.\n    /// </summary>\n    /// <remarks>\n    /// The inverse of `Run()`\n    /// </remarks>\n    /// <param name=\"result\">Result / Output pair</param>\n    public static RWST<R, W, S, M, A> Write(A value, W output) =>\n        Writable.write<W, RWST<R, W, S, M>, A>(value, output).As();\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public RWST<R, W, S, M, (A Value, W Output)> Listen =>\n        Writable.listen<W, RWST<R, W, S, M>, A>(this).As();\n\n    /// <summary>\n    /// `Listens` executes the action and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public RWST<R, W, S, M, (A Value, B Output)> Listens<B>(Func<W, B> f) =>\n        Writable.listens(f, this).As();\n\n    /// <summary>\n    /// `Censor` executes the action and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public RWST<R, W, S, M, A> Censor(Func<W, W> f) =>\n        Writable.censor(f, this).As();\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  State behaviours\n    //\n\n    /// <summary>\n    /// Extracts the state value, maps it, and then puts it back into\n    /// the monadic state.\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, Unit> Modify(Func<S, S> f) =>\n        new(input => M.Pure((unit, input.Output, f(input.State))));\n\n    /// <summary>\n    /// Extracts the state value, maps it, and then puts it back into\n    /// the monadic state.\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, Unit> ModifyM(Func<S, K<M, S>> f) =>\n        new(input => f(input.State).Map(s => (unit, input.Output, s)));\n\n    /// <summary>\n    /// Writes the value into the monadic state\n    /// </summary>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, Unit> Put(S value) =>\n        new(input => M.Pure((unit, input.Output, value)));\n\n    /// <summary>\n    /// Writes a value and state into the monad\n    /// </summary>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, A> State(A value, S state) =>\n        new(input => M.Pure((value, input.Output, state)));\n\n    /// <summary>\n    /// Writes a value and state into the monad\n    /// </summary>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, A> State((A Value, S State) ma) =>\n        new(input => M.Pure((ma.Value, input.Output, ma.State)));\n\n    /// <summary>\n    /// Extracts the state value and returns it as the bound value\n    /// </summary>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, S> Get { get; } =\n        new(input => M.Pure((input.State, input.Output, input.State)));\n\n    /// <summary>\n    /// Extracts the state value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, A> Gets(Func<S, A> f) =>\n        new(input => M.Pure((f(input.State), input.Output, input.State)));\n\n    /// <summary>\n    /// Extracts the state value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`RWST`</returns>\n    public static RWST<R, W, S, M, A> GetsM(Func<S, K<M, A>> f) =>\n        new(input => M.Map(v => (v, input.Output, input.State), f(input.State)));\n    \n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, B> Map<B>(Func<A, B> f) =>\n        Functor.map(f, this).As();\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, B> Select<B>(Func<A, B> f) =>\n        Functor.map(f, this).As();\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, B> Bind<B>(Func<A, K<RWST<R, W, S, M>, B>> f) =>\n        Monad.bind(this, f).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, B> Bind<B>(Func<A, RWST<R, W, S, M, B>> f) =>\n        Monad.bind(this, f).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, B> Bind<B>(Func<A, Ask<R, B>> f) =>\n        Bind(x => (RWST<R, W, S, M, B>)f(x));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, B> Bind<B>(Func<A, IO<B>> f) =>\n        Bind(x => RWST<R, W, S, M, B>.LiftIO(f(x)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, B> Bind<B>(Func<A, K<IO, B>> f) =>\n        Bind(x => RWST<R, W, S, M, B>.LiftIO(f(x)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<B, C>(Func<A, RWST<R, W, S, M, B>> bind, Func<A, B, C> project) =>\n        new(input => runRWST(input).Bind(\n                output1 => bind(output1.Value)\n                          .runRWST((input.Env, output1.Output, output1.State))\n                          .Map(output2 => (project(output1.Value, output2.Value), output2.Output, output2.State)))); \n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<B, C>(Func<A, K<RWST<R, W, S, M>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => RWST<R, W, S, M, B>.Lift(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => RWST<R, W, S, M, B>.LiftIO(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<B, C>(Func<A, K<IO, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => RWST<R, W, S, M, B>.LiftIO(bind(x)), project);\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<B, C>(Func<A, Ask<R, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).ToReadable<RWST<R, W, S, M>>(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<C>(Func<A, Put<S>> bind, Func<A, Unit, C> project) =>\n        SelectMany(x => bind(x).ToStateful<RWST<R, W, S, M>>(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<B, C>(Func<A, Gets<S, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).ToStateful<RWST<R, W, S, M>>(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<C>(Func<A, Modify<S>> bind, Func<A, Unit, C> project) =>\n        SelectMany(x => bind(x).ToStateful<RWST<R, W, S, M>>(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`RWST`</returns>\n    public RWST<R, W, S, M, C> SelectMany<C>(Func<A, Tell<W>> bind, Func<A, Unit, C> project) =>\n        SelectMany(x => bind(x).ToWritable<RWST<R, W, S, M>>(), project);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n    \n    public static implicit operator RWST<R, W, S, M, A>(Pure<A> ma) =>\n        Pure(ma.Value);\n    \n    public static implicit operator RWST<R, W, S, M, A>(Ask<R, A> ma) =>\n        Asks(ma.F);\n\n    public static implicit operator RWST<R, W, S, M, A>(IO<A> ma) =>\n        LiftIO(ma);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Run the RWST\n    //\n\n    /// <summary>\n    /// Run the monad \n    /// </summary>\n    public K<M, (A Value, W Output, S State)> Run(R env, W output, S state) => \n        runRWST((env, output, state));\n    \n    /// <summary>\n    /// Run the monad \n    /// </summary>\n    public K<M, (A Value, W Output, S State)> Run(R env, S state) => \n        runRWST((env, W.Empty, state));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/RWS/RWST/Trait/RWST.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Reader / Write / State monad-transformer trait implementations\n/// </summary>\n/// <typeparam name=\"R\">Reader environment type</typeparam>\n/// <typeparam name=\"W\">Writer output type</typeparam>\n/// <typeparam name=\"S\">State type</typeparam>\n/// <typeparam name=\"M\">Lifted monad type</typeparam>\npublic class RWST<R, W, S, M> :\n    MonadT<RWST<R, W, S, M>, M>, \n    Readable<RWST<R, W, S, M>, R>,\n    Writable<RWST<R, W, S, M>, W>,\n    Stateful<RWST<R, W, S, M>, S>\n    where M : Monad<M>\n    where W : Monoid<W>\n{\n    static K<RWST<R, W, S, M>, B> Monad<RWST<R, W, S, M>>.Bind<A, B>(\n        K<RWST<R, W, S, M>, A> ma,\n        Func<A, K<RWST<R, W, S, M>, B>> f) =>\n        new RWST<R, W, S, M, B>(\n            input => ma.As().runRWST(input)\n                       .Bind(x => f(x.Value).As().runRWST((input.Env, x.Output, x.State))));\n\n    static K<RWST<R, W, S, M>, B> Monad<RWST<R, W, S, M>>.Recur<A, B>(A value, Func<A, K<RWST<R, W, S, M>, Next<A, B>>> f) =>\n        new RWST<R, W, S, M, B>(\n            input =>\n            {\n                return M.Recur(f(value).As().runRWST(input), go);\n\n                K<M, Next<K<M, (Next<A, B>, W, S)>, (B, W, S)>> go(K<M, (Next<A, B> Next, W Output, S State)> ma) =>\n                    ma >> (n => n.Next switch\n                                {\n                                   { IsDone: true, Done: var x } =>\n                                        M.Pure(Next.Done<K<M, (Next<A, B>, W, S)>, (B, W, S)>((x, n.Output, n.State))),\n\n                                    { IsLoop: true, Loop: var x } =>\n                                        M.Pure(Next.Loop<K<M, (Next<A, B>, W, S)>, (B, W, S)>(f(x).As().Run(input.Env, n.Output, n.State))),\n\n                                    _ => throw new NotSupportedException()\n                                });\n            });\n\n\n    static K<RWST<R, W, S, M>, B> Functor<RWST<R, W, S, M>>.Map<A, B>(\n        Func<A, B> f, \n        K<RWST<R, W, S, M>, A> ma) => \n        new RWST<R, W, S, M, B>(\n            input => ma.As().runRWST(input)\n                       .Map(x => (f(x.Value), x.Output, x.State)));\n\n    static K<RWST<R, W, S, M>, A> Applicative<RWST<R, W, S, M>>.Pure<A>(A value) => \n        new RWST<R, W, S, M, A>(input => M.Pure((value, input.Output, input.State)));\n\n    static K<RWST<R, W, S, M>, B> Applicative<RWST<R, W, S, M>>.Apply<A, B>(\n        K<RWST<R, W, S, M>, Func<A, B>> mf,\n        K<RWST<R, W, S, M>, A> ma) =>\n        new RWST<R, W, S, M, B>(\n            input => from rf in mf.As().runRWST(input)\n                     from ra in ma.As().runRWST((input.Env, rf.Output, rf.State))\n                     select (rf.Value(ra.Value), ra.Output, ra.State));\n\n    static K<RWST<R, W, S, M>, B> Applicative<RWST<R, W, S, M>>.Apply<A, B>(\n        K<RWST<R, W, S, M>, Func<A, B>> mf,\n        Memo<RWST<R, W, S, M>, A> ma) =>\n        new RWST<R, W, S, M, B>(\n            input => from rf in mf.As().runRWST(input)\n                     from ra in ma.Value.As().runRWST((input.Env, rf.Output, rf.State))\n                     select (rf.Value(ra.Value), ra.Output, ra.State));\n\n    static K<RWST<R, W, S, M>, A> MonadT<RWST<R, W, S, M>, M>.Lift<A>(K<M, A> ma) => \n        new RWST<R, W, S, M, A>(input => ma.Map(value => (value, input.Output, input.State)));\n\n    static K<RWST<R, W, S, M>, A> Readable<RWST<R, W, S, M>, R>.Asks<A>(Func<R, A> f) => \n        new RWST<R, W, S, M, A>(input => M.Pure((f(input.Env), input.Output, input.State)));\n\n    static K<RWST<R, W, S, M>, A> Readable<RWST<R, W, S, M>, R>.Local<A>(\n        Func<R, R> f,\n        K<RWST<R, W, S, M>, A> ma) =>\n        new RWST<R, W, S, M, A>(\n            input => ma.As().runRWST((f(input.Env), input.Output, input.State)));\n\n    static K<RWST<R, W, S, M>, Unit> Writable<RWST<R, W, S, M>, W>.Tell(W item) => \n        new RWST<R, W, S, M, Unit>(\n            input => M.Pure((unit, input.Output.Combine(item), input.State)));\n\n    static K<RWST<R, W, S, M>, (A Value, W Output)> Writable<RWST<R, W, S, M>, W>.Listen<A>(\n        K<RWST<R, W, S, M>, A> ma) =>\n        new RWST<R, W, S, M, (A Value, W Output)>(\n            input => ma.As()\n                       .runRWST(input)\n                       .Map(output => ((output.Value, output.Output), output.Output, output.State)));\n\n    static K<RWST<R, W, S, M>, A> Writable<RWST<R, W, S, M>, W>.Pass<A>(\n        K<RWST<R, W, S, M>, (A Value, Func<W, W> Function)> action) => \n        new RWST<R, W, S, M, A>(\n            input => action.As()\n                           .runRWST(input)\n                           .Map(output => (output.Value.Value, \n                                           output.Output + output.Value.Function(output.Output),\n                                           output.State)));\n\n    static K<RWST<R, W, S, M>, Unit> Stateful<RWST<R, W, S, M>, S>.Put(S value) =>\n        new RWST<R, W, S, M, Unit>(input => M.Pure((unit, input.Output, value)));\n\n    static K<RWST<R, W, S, M>, Unit> Stateful<RWST<R, W, S, M>, S>.Modify(Func<S, S> f) => \n        new RWST<R, W, S, M, Unit>(input => M.Pure((unit, input.Output, f(input.State))));\n\n    static K<RWST<R, W, S, M>, A> Stateful<RWST<R, W, S, M>, S>.Gets<A>(Func<S, A> f) => \n        new RWST<R, W, S, M, A>(input => M.Pure((f(input.State), input.Output, input.State)));\n\n    static K<RWST<R, W, S, M>, A> Maybe.MonadIO<RWST<R, W, S, M>>.LiftIOMaybe<A>(K<IO, A> ma) => \n        new RWST<R, W, S, M, A>(input => M.LiftIOMaybe(ma).Map(a => (a, input.Output, input.State)));\n\n    static K<RWST<R, W, S, M>, A> Maybe.MonadIO<RWST<R, W, S, M>>.LiftIOMaybe<A>(IO<A> ma) => \n        new RWST<R, W, S, M, A>(input => M.LiftIOMaybe(ma).Map(a => (a, input.Output, input.State)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Ask.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Reader ask\n/// </summary>\n/// <remarks>\n/// This is a convenience type that is created by the Prelude `ask` function.  It avoids\n/// the need for lots of generic parameters when used in `ReaderT` and `Reader` based\n/// monads.\n/// </remarks>\n/// <param name=\"F\">Mapping from the environment</param>\n/// <typeparam name=\"Env\">Reader environment type</typeparam>\n/// <typeparam name=\"A\">Type to map to </typeparam>\npublic readonly record struct Ask<Env, A>(Func<Env, A> F)\n{\n    /// <summary>\n    /// Use a `Readable` trait to convert to an `M〈A〉`\n    /// </summary>\n    public K<M, A> ToReadable<M>()\n        where M : Readable<M, Env> =>\n        Readable.asks<M, Env, A>(F);\n\n    /// <summary>\n    /// Convert to a `Reader`\n    /// </summary>\n    public Reader<Env, A> ToReader() =>\n        ToReadable<Reader<Env>>().As();\n    \n    /// <summary>\n    /// Convert to a `ReaderT`\n    /// </summary>\n    public ReaderT<Env, M, A> ToReaderT<M>()\n        where M : Monad<M> =>\n        ToReadable<ReaderT<Env, M>>().As();\n    \n    /// <summary>\n    /// Convert to a `RWS`\n    /// </summary>\n    //public RWS<Env, W, S, A> ToRWS() =>\n    //    ToReadable<RWS<Env, W, S>>().As();\n    \n    /// <summary>\n    /// Convert to a `RWST`\n    /// </summary>\n    public RWST<Env, W, S, M, A> ToRWST<W, S, M>()\n        where W : Monoid<W>\n        where M : Monad<M>, Choice<M> =>\n        ToReadable<RWST<Env, W, S, M>>().As();\n    \n    /// <summary>\n    /// Monadic bind with any `Reader`\n    /// </summary>\n    public K<M, C> SelectMany<M, B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project)\n        where M : Monad<M>, Readable<M, Env> =>\n        M.Bind(M.Asks(F), x => M.Map(y => project(x, y), bind(x)));\n    \n    /// <summary>\n    /// Monadic bind with `ReaderT`\n    /// </summary>\n    public ReaderT<Env, M, C> SelectMany<M, B, C>(Func<A, ReaderT<Env, M, B>> bind, Func<A, B, C> project)\n        where M : Monad<M> =>\n        ToReaderT<M>().SelectMany(bind, project);\n    \n    /// <summary>\n    /// Monadic bind with `ReaderT`\n    /// </summary>\n    public ReaderT<Env, M, C> SelectMany<M, B, C>(Func<A, K<ReaderT<Env, M>, B>> bind, Func<A, B, C> project)\n        where M : Monad<M> =>\n        ToReaderT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind with `Reader`\n    /// </summary>\n    public Reader<Env, C> SelectMany<B, C>(Func<A, Reader<Env, B>> bind, Func<A, B, C> project) =>\n         ToReader().SelectMany(bind, project).As();\n\n    /// <summary>\n    /// Monadic bind with `Reader`\n    /// </summary>\n    public Reader<Env, C> SelectMany<B, C>(Func<A, K<Reader<Env>, B>> bind, Func<A, B, C> project) =>\n        ToReader().SelectMany(bind, project).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public RWST<Env, W, S, M, C> SelectMany<W, S, M, B, C>(\n        Func<A, RWST<Env, W, S, M, B>> bind, \n        Func<A, B, C> project)\n        where W : Monoid<W>\n        where M : Monad<M>, Choice<M> =>\n        RWST<Env, W, S, M, A>.Asks(F).SelectMany(bind, project);    \n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public RWST<Env, W, S, M, C> SelectMany<W, S, M, B, C>(\n        Func<A, K<RWST<Env, W, S, M>, B>> bind, \n        Func<A, B, C> project)\n        where W : Monoid<W>\n        where M : Monad<M>, Choice<M> =>\n        RWST<Env, W, S, M, A>.Asks(F).SelectMany(bind, project);      \n}\n\npublic static class AskExtensions\n{\n    /// <summary>\n    /// Monadic bind with any `Reader`\n    /// </summary>\n    public static K<M, C> SelectMany<Env, M, A, B, C>(\n        this K<M, A> ma,\n        Func<A, Ask<Env, B>> bind,\n        Func<A, B, C> project)\n        where M : Monad<M>, Readable<M, Env> =>\n        M.Bind(ma, a => M.Map(b => project(a, b), M.Asks(bind(a).F)));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Reader/Extensions/Reader.Extensions.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Reader monad extensions\n/// </summary>\npublic static partial class ReaderExtensions\n{\n    public static Reader<Env, A> As<Env, A>(this K<Reader<Env>, A> ma) =>\n        (Reader<Env, A>)ma;\n\n    /// <summary>\n    /// Run the reader monad \n    /// </summary>\n    /// <param name=\"env\">Input environment</param>\n    public static A Run<Env, A>(this K<Reader<Env>, A> ma, Env env) =>\n        ((Reader<Env, A>)ma).runReader(env);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Reader<Env, A> Flatten<Env, A>(this Reader<Env, Reader<Env, A>> mma) =>\n        mma.Bind(identity);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Reader/Operators/Reader.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderExtensions\n{\n    extension<Env, A, B>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Reader<Env, B> operator >>> (K<Reader<Env>, A> ma, K<Reader<Env>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, B> operator * (K<Reader<Env>, Func<A, B>> mf, K<Reader<Env>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, B> operator * (K<Reader<Env>, A> ma, K<Reader<Env>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<Env, A, B, C>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, C>> operator * (\n            K<Reader<Env>, Func<A, B, C>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, C>> operator * (\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<Env, A, B, C, D>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, D>>> operator * (\n            K<Reader<Env>, Func<A, B, C, D>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, D>>> operator * (\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<Env, A, B, C, D, E>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Reader<Env>, Func<A, B, C, D, E>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<Env, A, B, C, D, E, F>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Reader<Env>, Func<A, B, C, D, E, F>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<Env, A, B, C, D, E, F, G>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Reader<Env>, Func<A, B, C, D, E, F, G>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<Env, A, B, C, D, E, F, G, H>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Reader<Env>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<Env, A, B, C, D, E, F, G, H, I>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Reader<Env>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<Env, A, B, C, D, E, F, G, H, I, J>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Reader<Env>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<Env, A, B, C, D, E, F, G, H, I, J, K>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Reader<Env>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Reader<Env>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Reader<Env>, A> ma,\n            K<Reader<Env>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Reader/Operators/Reader.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderExtensions\n{\n    extension<Env, A, B>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, B> operator *(Func<A, B> f, K<Reader<Env>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, B> operator *(K<Reader<Env>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<Env, A, B, C>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, C>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<Env, A, B, C, D>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, D>>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<Env, A, B, C, D, E>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<Env, A, B, C, D, E, F>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<Env, A, B, C, D, E, F, G>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<Env, A, B, C, D, E, F, G, H>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<Env, A, B, C, D, E, F, G, H, I>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<Env, A, B, C, D, E, F, G, H, I, J>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<Env, A, B, C, D, E, F, G, H, I, J, K>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Reader<Env>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Reader<Env, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Reader<Env>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Reader/Operators/Reader.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderExtensions\n{\n    extension<Env, A, B>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Reader<Env, B> operator >> (K<Reader<Env>, A> ma, Func<A, K<Reader<Env>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Reader<Env, B> operator >> (K<Reader<Env>, A> lhs, K<Reader<Env>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<Env, A>(K<Reader<Env>, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Reader<Env, A> operator >> (K<Reader<Env>, A> lhs, K<Reader<Env>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Reader/Operators/Reader.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderExtensions\n{\n    extension<Env, A>(K<Reader<Env>, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Reader<Env, A> operator +(K<Reader<Env>, A> ma) =>\n            (Reader<Env, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Reader<Env, A> operator >> (K<Reader<Env>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Reader/Reader.Module.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\npublic partial class Reader\n{\n    public static Reader<Env, A> pure<Env, A>(A value) =>  \n        Reader<Env, A>.Pure(value);\n\n    public static Reader<Env, Env> ask<Env>() => \n        Reader<Env, Env>.Asks(Prelude.identity);\n\n    public static Reader<Env, A> asks<Env, A>(Func<Env, A> f) =>  \n        Reader<Env, A>.Asks(f);\n\n    public static Reader<Env, A> asksM<Env, A>(Func<Env, Reader<Env, A>> f) =>\n        Reader<Env, A>.AsksM(f);\n\n    public static Reader<Env, A> local<Env, A>(Func<Env, Env> f, Reader<Env, A> ma) => \n        ma.As().Local(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Reader/Reader.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `Reader` monad transformer, which adds a static environment to a given monad. \n/// </summary>\n/// <typeparam name=\"Env\">Reader environment type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record Reader<Env, A>(Func<Env, A> runReader) : K<Reader<Env>, A>\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`Reader`</returns>\n    public static Reader<Env, A> Pure(A value) =>\n        new(_ => value);\n\n    /// <summary>\n    /// Extracts the environment value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">Environment mapping function</param>\n    /// <returns>`Reader`</returns>\n    public static Reader<Env, A> Asks(Func<Env, A> f) =>\n        new(f);\n\n    /// <summary>\n    /// Extracts the environment value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">Environment mapping function</param>\n    /// <returns>`Reader`</returns>\n    public static Reader<Env, A> AsksM(Func<Env, Reader<Env, A>> f) =>\n        Reader<Env, Reader<Env, A>>.Asks(f).Flatten();\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`Reader`</returns>\n    public static Reader<Env, A> Lift(Pure<A> monad) =>\n        Pure(monad.Value);\n    \n    /// <summary>\n    /// Lifts a unit function into the transformer \n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`Reader`</returns>\n    public static Reader<Env, A> Lift(Func<A> f) =>\n        new (_ => f());\n\n    /// <summary>\n    /// Maps the Reader's environment value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`Reader`</returns>\n    public Reader<Env1, A> With<Env1>(Func<Env1, Env> f) =>\n        new (e => runReader(f(e)));\n\n    /// <summary>\n    /// Maps the Reader's environment value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, A> Local(Func<Env, Env> f) =>\n        new (e => runReader(f(e)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, B> Map<B>(Func<A, B> f) =>\n        new(e => f(runReader(e)));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, B> Select<B>(Func<A, B> f) =>\n        new(e => f(runReader(e)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, B> Bind<B>(Func<A, K<Reader<Env>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, B> Bind<B>(Func<A, Reader<Env, B>> f) =>\n        new(e => f(runReader(e)).runReader(e));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, B> Bind<B>(Func<A, Ask<Env, B>> f) =>\n        Bind(x => (Reader<Env, B>)f(x));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, C> SelectMany<B, C>(Func<A, K<Reader<Env>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, C> SelectMany<B, C>(Func<A, Reader<Env, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y))); \n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`Reader`</returns>\n    public Reader<Env, C> SelectMany<B, C>(Func<A, Ask<Env, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).ToReader(), project);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n\n    public static implicit operator Reader<Env, A>(Pure<A> ma) =>\n        Pure(ma.Value);\n    \n    public static implicit operator Reader<Env, A>(Ask<Env, A> ma) =>\n        Asks(ma.F);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Run the reader\n    //\n\n    /// <summary>\n    /// Run the reader monad \n    /// </summary>\n    /// <param name=\"env\">Input environment</param>\n    /// <returns>Computed value</returns>\n    public A Run(Env env) =>\n        runReader(env);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/Reader/Trait/Reader.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Trait implementation for `Reader` \n/// </summary>\n/// <typeparam name=\"Env\">Reader environment type</typeparam>\npublic partial class Reader<Env> : \n    Monad<Reader<Env>>,\n    Readable<Reader<Env>, Env> \n{\n    static K<Reader<Env>, B> Monad<Reader<Env>>.Bind<A, B>(K<Reader<Env>, A> ma, Func<A, K<Reader<Env>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<Reader<Env>, B> Monad<Reader<Env>>.Recur<A, B>(A value, Func<A, K<Reader<Env>, Next<A, B>>> f) =>\n        new Reader<Env, B>(env =>\n                           {\n                               while (true)\n                               {\n                                   var mr = f(value).Run(env);\n                                   if (mr.IsDone) return mr.Done;\n                                   value = mr.Loop;\n                               }\n                           });\n\n    static K<Reader<Env>, B> Functor<Reader<Env>>.Map<A, B>(Func<A, B> f, K<Reader<Env>, A> ma) => \n        ma.As().Map(f);\n\n    static K<Reader<Env>, A> Applicative<Reader<Env>>.Pure<A>(A value) => \n        Reader<Env, A>.Pure(value);\n\n    static K<Reader<Env>, B> Applicative<Reader<Env>>.Apply<A, B>(K<Reader<Env>, Func<A, B>> mf, K<Reader<Env>, A> ma) => \n        mf.As().Bind(x => ma.As().Map(x));\n\n    static K<Reader<Env>, B> Applicative<Reader<Env>>.Apply<A, B>(K<Reader<Env>, Func<A, B>> mf, Memo<Reader<Env>, A> ma) => \n        mf.As().Bind(x => ma.Value.As().Map(x));\n\n    static K<Reader<Env>, Env> Readable<Reader<Env>, Env>.Ask =>\n        Reader<Env, Env>.Asks(Prelude.identity);\n\n    static K<Reader<Env>, A> Readable<Reader<Env>, Env>.Asks<A>(Func<Env, A> f) => \n        Reader<Env, A>.Asks(f);\n\n    static K<Reader<Env>, A> Readable<Reader<Env>, Env>.Local<A>(Func<Env, Env> f, K<Reader<Env>, A> ma) =>\n        ma.As().Local(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Extensions/ReaderT.Extensions.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Reader monad extensions\n/// </summary>\npublic static partial class ReaderTExtensions\n{\n     // public static Reader<Env, A> As<Env, A>(this K<ReaderT<Env, Identity>, A> ma) =>\n     //    (Reader<Env, A>)ma;\n    \n    public static ReaderT<Env, M, A> As<Env, M, A>(this K<ReaderT<Env, M>, A> ma)\n        where M : Monad<M> =>\n        (ReaderT<Env, M, A>)ma;\n\n    /// <summary>\n    /// Run the reader monad \n    /// </summary>\n    /// <param name=\"env\">Input environment</param>\n    /// <returns>Bound monad</returns>\n    public static K<M, A> Run<Env, M, A>(this K<ReaderT<Env, M>, A> ma, Env env)\n        where M : Monad<M> =>\n        ((ReaderT<Env, M, A>)ma).runReader(env);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static ReaderT<Env, M, A> Flatten<Env, M, A>(this ReaderT<Env, M, ReaderT<Env, M, A>> mma)\n        where M : Monad<M> =>\n        mma.Bind(identity);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static ReaderT<Env, M, A> Flatten<Env, M, A>(this ReaderT<Env, M, K<ReaderT<Env, M>, A>> mma)\n        where M : Monad<M> =>\n        mma.Bind(identity);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, C> SelectMany<Env, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<ReaderT<Env, M>, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        ReaderT<Env, M, A>.Lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, C> SelectMany<Env, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, ReaderT<Env, M, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        ReaderT<Env, M, A>.Lift(ma).SelectMany(bind, project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Operators/ReaderT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderTExtensions\n{\n    extension<Env, M, A, B>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static ReaderT<Env, M, B> operator >>> (K<ReaderT<Env, M>, A> ma, K<ReaderT<Env, M>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, B> operator * (K<ReaderT<Env, M>, Func<A, B>> mf, K<ReaderT<Env, M>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, B> operator * (K<ReaderT<Env, M>, A> ma, K<ReaderT<Env, M>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<Env, M, A, B, C>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, C>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, C>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<Env, M, A, B, C, D>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, D>>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C, D>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, D>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<Env, M, A, B, C, D, E>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C, D, E>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<Env, M, A, B, C, D, E, F>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<Env, M, A, B, C, D, E, F, G>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<Env, M, A, B, C, D, E, F, G, H>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<Env, M, A, B, C, D, E, F, G, H, I>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<Env, M, A, B, C, D, E, F, G, H, I, J>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<Env, M, A, B, C, D, E, F, G, H, I, J, K>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<ReaderT<Env, M>, A> ma,\n            K<ReaderT<Env, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Operators/ReaderT.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderTExtensions\n{\n    extension<Env, M, A>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>, Choice<M>\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static ReaderT<Env, M, A> operator |(K<ReaderT<Env, M>, A> lhs, K<ReaderT<Env, M>, A> rhs) =>\n            new (env => lhs.As().runReader(env) | rhs.As().runReader(env));\n\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static ReaderT<Env, M, A> operator |(K<ReaderT<Env, M>, A> lhs, Pure<A> rhs) =>\n            new (env => lhs.As().runReader(env) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Operators/ReaderT.Operators.Fallible.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderTExtensions\n{\n    extension<Env, E, M, A>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>, Fallible<E, M>\n    {\n        public static ReaderT<Env, M, A> operator |(K<ReaderT<Env, M>, A> lhs, CatchM<E, M, A> rhs) =>\n            new(env => lhs.As().runReader(env) | rhs);\n\n        public static ReaderT<Env, M, A> operator |(K<ReaderT<Env, M>, A> lhs, Fail<E> rhs) =>\n            new(env => lhs.As().runReader(env) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Operators/ReaderT.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class ReaderTExtensions\n{\n    extension<X, Env, M, A>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>, Final<M>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static ReaderT<Env, M, A> operator |(K<ReaderT<Env, M>, A> lhs, Finally<M, X> rhs) =>\n            new(env => lhs.As().runReader(env) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Operators/ReaderT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderTExtensions\n{\n    extension<Env, M, A, B>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, B> operator *(Func<A, B> f, K<ReaderT<Env, M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, B> operator *(K<ReaderT<Env, M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<Env, M, A, B, C>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, C>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<Env, M, A, B, C, D>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, D>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<Env, M, A, B, C, D, E>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<Env, M, A, B, C, D, E, F>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<Env, M, A, B, C, D, E, F, G>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<Env, M, A, B, C, D, E, F, G, H>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<Env, M, A, B, C, D, E, F, G, H, I>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<Env, M, A, B, C, D, E, F, G, H, I, J>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<Env, M, A, B, C, D, E, F, G, H, I, J, K>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<ReaderT<Env, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static ReaderT<Env, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<ReaderT<Env, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Operators/ReaderT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderTExtensions\n{\n    extension<Env, M, A, B>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static ReaderT<Env, M, B> operator >> (K<ReaderT<Env, M>, A> ma, Func<A, K<ReaderT<Env, M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static ReaderT<Env, M, B> operator >> (K<ReaderT<Env, M>, A> lhs, K<ReaderT<Env, M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<Env, M, A>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static ReaderT<Env, M, A> operator >> (K<ReaderT<Env, M>, A> lhs, K<ReaderT<Env, M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Operators/ReaderT.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderTExtensions\n{\n    extension<Env, M, A>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ReaderT<Env, M, A> operator +(K<ReaderT<Env, M>, A> lhs, K<ReaderT<Env, M>, A> rhs) =>\n            new(env => lhs.As().runReader(env) + rhs.As().runReader(env));\n\n        //+lhs.Combine(rhs);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ReaderT<Env, M, A> operator +(K<ReaderT<Env, M>, A> lhs, Pure<A> rhs) =>\n            new(env => lhs.As().runReader(env) + M.Pure(rhs.Value));\n    }\n    \n    extension<E, Env, M, A>(K<ReaderT<Env, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Fallible<E, M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static ReaderT<Env, M, A> operator +(K<ReaderT<Env, M>, A> lhs, Fail<E> rhs) =>\n            new(env => lhs.As().runReader(env) + M.Fail<A>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Operators/ReaderT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderTExtensions\n{\n    extension<Env, M, A>(K<ReaderT<Env, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static ReaderT<Env, M, A> operator +(K<ReaderT<Env, M>, A> ma) =>\n            (ReaderT<Env, M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static ReaderT<Env, M, A> operator >> (K<ReaderT<Env, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Prelude/ReaderT.Prelude.mapapply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped functor</returns>\n    public static ReaderT<Env, M, B> map<Env, M, A, B>(Func<A, B> f, K<ReaderT<Env, M>, A> ma) \n        where M : Monad<M>, Alternative<M> =>\n        Functor.map(f, ma).As();\n    \n    /// <summary>\n    /// Applicative action: runs the first applicative, ignores the result, and returns the second applicative\n    /// </summary>\n    public static ReaderT<Env, M, B> action<Env, M, A, B>(K<ReaderT<Env, M>, A> ma, K<ReaderT<Env, M>, B> mb) \n        where M : Monad<M>, Alternative<M> =>\n        Applicative.action(ma, mb).As();\n\n    /// <summary>\n    /// Applicative functor apply operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the `ma` applicative-functor, passes it to the unwrapped function(s) within `mf`, and\n    /// then takes the resulting value and wraps it back up into a new applicative-functor.\n    /// </remarks>\n    /// <param name=\"ma\">Value(s) applicative functor</param>\n    /// <param name=\"mf\">Mapping function(s)</param>\n    /// <returns>Mapped applicative functor</returns>\n    public static ReaderT<Env, M, B> apply<Env, M, A, B>(K<ReaderT<Env, M>, Func<A, B>> mf, K<ReaderT<Env, M>, A> ma) \n        where M : Monad<M>, Alternative<M> =>\n        Applicative.apply(mf, ma).As();\n}    \n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/ReaderT.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n\n/// <summary>\n/// `MonadReaderT` trait implementation for `ReaderT` \n/// </summary>\n/// <typeparam name=\"Env\">Reader environment type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic class ReaderT<Env>\n{\n    public static ReaderT<Env, M, A> lift<M, A>(K<M, A> ma)  \n        where M : Monad<M> => \n        ReaderT<Env, M, A>.Lift(ma);\n}\n\npublic partial class ReaderT<Env, M>\n{\n    public static ReaderT<Env, M, A> pure<A>(A value) => \n        ReaderT<Env, M, A>.Pure(value);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"effect\">Monad to lift</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> liftIO<A>(IO<A> effect) =>\n        ReaderT<Env, M, A>.LiftIO(effect);\n}\n\n/// <summary>\n/// `MonadReaderT` trait implementation for `ReaderT` \n/// </summary>\n/// <typeparam name=\"Env\">Reader environment type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic class ReaderT\n{\n    public static ReaderT<Env, M, A> pure<Env, M, A>(A value)  \n        where M : Monad<M> => \n        ReaderT<Env, M, A>.Pure(value);\n\n    public static ReaderT<Env, M, A> lift<Env, M, A>(K<M, A> ma)  \n        where M : Monad<M> => \n        ReaderT<Env, M, A>.Lift(ma);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"effect\">Monad to lift</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> liftIO<Env, M, A>(IO<A> effect)\n        where M : Monad<M> =>\n        ReaderT<Env, M, A>.LiftIO(effect);\n    \n    public static ReaderT<Env, M, Env> ask<M, Env>() \n        where M : Monad<M> => \n        ReaderT<Env, M, Env>.Asks(Prelude.identity);\n\n    public static ReaderT<Env, M, A> asks<M, A, Env>(Func<Env, A> f)  \n        where M : Monad<M> => \n        ReaderT<Env, M, A>.Asks(f);\n\n    public static ReaderT<Env, M, A> asksM<M, Env, A>(Func<Env, K<M, A>> f)\n        where M : Monad<M> =>\n        ReaderT<Env, M, A>.AsksM(f);\n\n    public static ReaderT<Env, M, A> local<Env, M, A>(Func<Env, Env> f, ReaderT<Env, M, A> ma) \n        where M : Monad<M> => \n        ma.As().Local(f);\n\n    public static ReaderT<Env, M, A> with<Env, SubEnv, M, A>(Func<Env, SubEnv> f, ReaderT<SubEnv, M, A> ma) \n        where M : Monad<M> => \n        ma.As().With(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/ReaderT.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `ReaderT` monad transformer, which adds a static environment to a given monad. \n/// </summary>\n/// <typeparam name=\"Env\">Reader environment type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record ReaderT<Env, M, A>(Func<Env, K<M, A>> runReader) : K<ReaderT<Env, M>, A>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> Pure(A value) =>\n        Lift(M.Pure(value));\n\n    /// <summary>\n    /// Extracts the environment value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">Environment mapping function</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> Asks(Func<Env, A> f) =>\n        new(env => M.Pure(f(env)));\n\n    /// <summary>\n    /// Extracts the environment value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">Environment mapping function</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> AsksM(Func<Env, K<M, A>> f) =>\n        new(f);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> Lift(Pure<A> monad) =>\n        Pure(monad.Value);\n    \n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> Lift(K<M, A> monad) =>\n        new(_ => monad);\n    \n    /// <summary>\n    /// Lifts a unit function into the transformer \n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> Lift(Func<A> f) =>\n        new (_ => M.Pure(f()));\n    \n    /// <summary>\n    /// Lifts a unit function into the transformer \n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`ReaderT`</returns>\n    public static ReaderT<Env, M, A> LiftIO(IO<A> ma) =>\n        new (_ => M.LiftIOMaybe(ma));\n\n    /// <summary>\n    /// Maps the Reader's environment value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env1, M, A> With<Env1>(Func<Env1, Env> f) =>\n        new (env1 => runReader(f(env1)));\n\n    /// <summary>\n    /// Maps the Reader's environment value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, A> Local(Func<Env, Env> f) =>\n        new (env1 => runReader(f(env1)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M1\">Trait of the monad to map to</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M1, B> MapM<M1, B>(Func<K<M, A>, K<M1, B>> f)\n        where M1 : Monad<M1>, Alternative<M1> =>\n        new (env => f(runReader(env)));\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, B> Map<B>(Func<A, B> f) =>\n        new(env => M.Map(f, runReader(env)));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, B> Select<B>(Func<A, B> f) =>\n        new(env => M.Map(f, runReader(env)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, B> Bind<B>(Func<A, K<ReaderT<Env, M>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, B> Bind<B>(Func<A, ReaderT<Env, M, B>> f) =>\n        new(env => M.Bind(runReader(env), x => f(x).runReader(env)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, B> Bind<B>(Func<A, Ask<Env, B>> f) =>\n        Bind(x => (ReaderT<Env, M, B>)f(x));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, B> Bind<B>(Func<A, IO<B>> f) =>\n        Bind(x => ReaderT<Env, M, B>.LiftIO(f(x)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, C> SelectMany<B, C>(Func<A, K<ReaderT<Env, M>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, C> SelectMany<B, C>(Func<A, ReaderT<Env, M, B>> bind, Func<A, B, C> project) =>\n        new(env => M.Bind(runReader(env), x => M.Map(y => project(x, y), bind(x).runReader(env))));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        new(env => M.Bind(runReader(env), x => M.Map(y => project(x, y), bind(x))));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, C> SelectMany<B, C>(Func<A, Ask<Env, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).ToReaderT<M>(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`ReaderT`</returns>\n    public ReaderT<Env, M, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n    \n    public static implicit operator ReaderT<Env, M, A>(Pure<A> ma) =>\n        Pure(ma.Value);\n    \n    public static implicit operator ReaderT<Env, M, A>(Ask<Env, A> ma) =>\n        Asks(ma.F);\n\n    public static implicit operator ReaderT<Env, M, A>(IO<A> ma) =>\n        LiftIO(ma);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Run the reader\n    //\n\n    /// <summary>\n    /// Run the reader monad \n    /// </summary>\n    /// <param name=\"env\">Input environment</param>\n    /// <returns>Bound monad</returns>\n    public K<M, A> Run(Env env) =>\n        runReader(env);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Reader/ReaderT/Trait/ReaderT.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `MonadReaderT` trait implementation for `ReaderT` \n/// </summary>\n/// <typeparam name=\"Env\">Reader environment type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class ReaderT<Env, M> :\n    MonadT<ReaderT<Env, M>, M>,\n    Readable<ReaderT<Env, M>, Env>, \n    MonadUnliftIO<ReaderT<Env, M>>\n    where M : Monad<M>\n{\n    static K<ReaderT<Env, M>, B> Monad<ReaderT<Env, M>>.Bind<A, B>(\n        K<ReaderT<Env, M>, A> ma,\n        Func<A, K<ReaderT<Env, M>, B>> f) =>\n        new ReaderT<Env, M, B>(env => ma.As().runReader(env).Bind(a => f(a).As().runReader(env)));\n\n    static K<ReaderT<Env, M>, B> Monad<ReaderT<Env, M>>.\n        Recur<A, B>(A value, Func<A, K<ReaderT<Env, M>, Next<A, B>>> f) =>\n        new ReaderT<Env, M, B>(env =>\n                               {\n                                   return M.Recur(f(value).Run(env), go);\n\n                                   K<M, Next<K<M, Next<A, B>>, B>> go(K<M, Next<A, B>> ma) =>\n                                       ma >> (n =>\n                                        n switch\n                                                 {\n                                                     { IsDone: true, Done: var x } => \n                                                         M.Pure(Next.Done<K<M, Next<A, B>>, B>(x)),\n                                                     \n                                                     { IsLoop: true, Loop: var x } => \n                                                         M.Pure(Next.Loop<K<M, Next<A, B>>, B>(f(x).Run(env))),\n                                                     \n                                                     _ => throw new NotSupportedException()\n                                                 });\n                               });\n\n    static K<ReaderT<Env, M>, B> Functor<ReaderT<Env, M>>.Map<A, B>(Func<A, B> f, K<ReaderT<Env, M>, A> ma) => \n        new ReaderT<Env, M, B>(env => ma.As().runReader(env).Map(f));\n\n    static K<ReaderT<Env, M>, A> Applicative<ReaderT<Env, M>>.Pure<A>(A value) => \n        new ReaderT<Env, M, A>(_ => M.Pure(value));\n\n    static K<ReaderT<Env, M>, B> Applicative<ReaderT<Env, M>>.Apply<A, B>(K<ReaderT<Env, M>, Func<A, B>> mf, K<ReaderT<Env, M>, A> ma) => \n        new ReaderT<Env, M, B>(env => mf.As().runReader(env).Apply(ma.As().runReader(env)));\n\n    static K<ReaderT<Env, M>, B> Applicative<ReaderT<Env, M>>.Apply<A, B>(K<ReaderT<Env, M>, Func<A, B>> mf, Memo<ReaderT<Env, M>, A> ma) => \n        new ReaderT<Env, M, B>(env => mf.As().runReader(env).Apply(ma.Value.As().runReader(env)));\n\n    static K<ReaderT<Env, M>, A> MonadT<ReaderT<Env, M>, M>.Lift<A>(K<M, A> ma) => \n        new ReaderT<Env, M, A>(_ => ma);\n\n    static K<ReaderT<Env, M>, Env> Readable<ReaderT<Env, M>, Env>.Ask =>\n        new ReaderT<Env, M, Env>(M.Pure);\n\n    static K<ReaderT<Env, M>, A> Readable<ReaderT<Env, M>, Env>.Asks<A>(Func<Env, A> f) =>\n        new ReaderT<Env, M, A>(env => M.Pure(f(env)));\n\n    static K<ReaderT<Env, M>, A> Readable<ReaderT<Env, M>, Env>.Local<A>(Func<Env, Env> f, K<ReaderT<Env, M>, A> ma) =>\n        new ReaderT<Env, M, A>(env => ma.As().runReader(f(env)));\n\n    static K<ReaderT<Env, M>, A> MonadIO<ReaderT<Env, M>>.LiftIO<A>(IO<A> ma) =>\n        new ReaderT<Env, M, A>(_ => M.LiftIOMaybe(ma));\n\n    static K<ReaderT<Env, M>, IO<A>> MonadUnliftIO<ReaderT<Env, M>>.ToIO<A>(K<ReaderT<Env, M>, A> ma) =>\n        new ReaderT<Env, M, IO<A>>(env => M.ToIOMaybe(ma.As().runReader(env)));\n\n    static K<ReaderT<Env, M>, B> MonadUnliftIO<ReaderT<Env, M>>.MapIO<A, B>(K<ReaderT<Env, M>, A> ma, Func<IO<A>, IO<B>> f) => \n        new ReaderT<Env, M, B>(env => M.MapIOMaybe(ma.As().runReader(env), f));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/PutGet.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// State put\n/// </summary>\n/// <remarks>\n/// This is a convenience type that is created by the Prelude `put` function.  It avoids\n/// the need for lots of generic parameters when used in `StateT` and `State` based\n/// monads.\n/// </remarks>\n/// <param name=\"F\">Mapping from the environment</param>\n/// <typeparam name=\"S\">State type</typeparam>\npublic readonly record struct Put<S>(S Value)\n{\n    /// <summary>\n    /// Convert to a `Stateful`\n    /// </summary>\n    public K<M, Unit> ToStateful<M>()\n        where M : Stateful<M, S> =>\n        Stateful.put<M, S>(Value);\n    \n    /// <summary>\n    /// Convert to a `StateT`\n    /// </summary>\n    public StateT<S, M, Unit> ToStateT<M>()\n        where M : Monad<M> =>\n        Stateful.put<StateT<S, M>, S>(Value).As();\n    \n    /// <summary>\n    /// Convert to a `State`\n    /// </summary>\n    public State<S, Unit> ToState() =>\n        Stateful.put<State<S>, S>(Value).As();\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public StateT<S, M, C> SelectMany<M, B, C>(Func<Unit, StateT<S, M, B>> bind, Func<Unit, B, C> project)\n        where M : Monad<M> =>\n        ToStateT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public StateT<S, M, C> SelectMany<M, B, C>(Func<Unit, K<StateT<S, M>, B>> bind, Func<Unit, B, C> project)\n        where M : Monad<M> =>\n        ToStateT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public State<S, C> SelectMany<B, C>(Func<Unit, State<S, B>> bind, Func<Unit, B, C> project) =>\n        ToState().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public State<S, C> SelectMany<B, C>(Func<Unit, K<State<S>, B>> bind, Func<Unit, B, C> project) =>\n        ToState().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public RWST<R, W, S, M, C> SelectMany<R, W, M, B, C>(Func<Unit, RWST<R, W, S, M, B>> bind, Func<Unit, B, C> project) \n        where W : Monoid<W>\n        where M : Stateful<M, S>, Monad<M>, Choice<M> =>\n        ToStateful<RWST<R, W, S, M>>().SelectMany(bind, project).As();\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public RWST<R, W, S, M, C> SelectMany<R, W, M, B, C>(Func<Unit, K<RWST<R, W, S, M>, B>> bind, Func<Unit, B, C> project) \n        where W : Monoid<W>\n        where M : Stateful<M, S>, Monad<M>, Choice<M> =>\n        ToStateful<RWST<R, W, S, M>>().SelectMany(bind, project).As();\n}\n\n/// <summary>\n/// State modify\n/// </summary>\n/// <remarks>\n/// This is a convenience type that is created by the Prelude `modify` function.  It avoids\n/// the need for lots of generic parameters when used in `StateT` and `State` based\n/// monads.\n/// </remarks>\n/// <param name=\"f\">Mapping from the environment</param>\n/// <typeparam name=\"S\">State type</typeparam>\npublic readonly record struct Modify<S>(Func<S, S> f)\n{\n    /// <summary>\n    /// Convert with `Stateful`\n    /// </summary>\n    public K<M, Unit> ToStateful<M>()\n        where M : Stateful<M, S> =>\n        Stateful.modify<M, S>(f);\n    \n    /// <summary>\n    /// Convert to a `StateT`\n    /// </summary>\n    public StateT<S, M, Unit> ToStateT<M>()\n        where M : Monad<M> =>\n        StateT<S, M, Unit>.Modify(f);\n    \n    /// <summary>\n    /// Convert to a `State`\n    /// </summary>\n    public State<S, Unit> ToState() =>\n        State<S, Unit>.Modify(f);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public StateT<S, M, C> SelectMany<M, B, C>(Func<Unit, StateT<S, M, B>> bind, Func<Unit, B, C> project)\n        where M : Monad<M> =>\n        ToStateT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public StateT<S, M, C> SelectMany<M, B, C>(Func<Unit, K<StateT<S, M>, B>> bind, Func<Unit, B, C> project)\n        where M : Monad<M> =>\n        ToStateT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public State<S, C> SelectMany<B, C>(Func<Unit, State<S, B>> bind, Func<Unit, B, C> project) =>\n        ToState().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public State<S, C> SelectMany<B, C>(Func<Unit, K<State<S>, B>> bind, Func<Unit, B, C> project) =>\n        ToState().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public RWST<R, W, S, M, C> SelectMany<R, W, M, B, C>(Func<Unit, RWST<R, W, S, M, B>> bind, Func<Unit, B, C> project) \n        where W : Monoid<W>\n        where M : Stateful<M, S>, Monad<M>, Choice<M> =>\n        ToStateful<RWST<R, W, S, M>>().SelectMany(bind, project).As();\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public RWST<R, W, S, M, C> SelectMany<R, W, M, B, C>(Func<Unit, K<RWST<R, W, S, M>, B>> bind, Func<Unit, B, C> project) \n        where W : Monoid<W>\n        where M : Stateful<M, S>, Monad<M>, Choice<M> =>\n        ToStateful<RWST<R, W, S, M>>().SelectMany(bind, project).As();\n}\n\n\n/// <summary>\n/// State modify\n/// </summary>\n/// <remarks>\n/// This is a convenience type that is created by the Prelude `modify` function.  It avoids\n/// the need for lots of generic parameters when used in `StateT` and `State` based\n/// monads.\n/// </remarks>\n/// <param name=\"f\">Mapping from the environment</param>\n/// <typeparam name=\"S\">State type</typeparam>\npublic readonly record struct Gets<S, A>(Func<S, A> f)\n{\n    /// <summary>\n    /// Convert with `Stateful`\n    /// </summary>\n    public K<M, A> ToStateful<M>()\n        where M : Stateful<M, S> =>\n        Stateful.gets<M, S, A>(f);\n    \n    /// <summary>\n    /// Convert ot a `StateT`\n    /// </summary>\n    public StateT<S, M, A> ToStateT<M>()\n        where M : Monad<M> =>\n        StateT<S, M, A>.Gets(f);\n    \n    /// <summary>\n    /// Convert ot a `State`\n    /// </summary>\n    public State<S, A> ToState() =>\n        State<S, A>.Gets(f);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public StateT<S, M, C> SelectMany<M, B, C>(Func<A, StateT<S, M, B>> bind, Func<A, B, C> project)\n        where M : Monad<M> =>\n        ToStateT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public StateT<S, M, C> SelectMany<M, B, C>(Func<A, K<StateT<S, M>, B>> bind, Func<A, B, C> project)\n        where M : Monad<M> =>\n        ToStateT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public State<S, C> SelectMany<B, C>(Func<A, State<S, B>> bind, Func<A, B, C> project) =>\n        ToState().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public State<S, C> SelectMany<B, C>(Func<A, K<State<S>, B>> bind, Func<A, B, C> project) =>\n        ToState().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public RWST<R, W, S, M, C> SelectMany<R, W, M, B, C>(Func<A, RWST<R, W, S, M, B>> bind, Func<A, B, C> project) \n        where W : Monoid<W>\n        where M : Stateful<M, S>, Monad<M>, Choice<M> =>\n        ToStateful<RWST<R, W, S, M>>().SelectMany(bind, project).As();\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public RWST<R, W, S, M, C> SelectMany<R, W, M, B, C>(Func<A, K<RWST<R, W, S, M>, B>> bind, Func<A, B, C> project) \n        where W : Monoid<W>\n        where M : Stateful<M, S>, Monad<M>, Choice<M> =>\n        ToStateful<RWST<R, W, S, M>>().SelectMany(bind, project).As();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/State/Extensions/State.Extensions.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// State monad extensions\n/// </summary>\npublic static partial class StateExtensions\n{\n    public static State<S, A> As<S, A>(this K<State<S>, A> ma) =>\n        (State<S, A>)ma;\n\n    /// <summary>\n    /// Run the state monad \n    /// </summary>\n    /// <param name=\"state\">Initial state</param>\n    public static (A Value, S State) Run<S, A>(this K<State<S>, A> ma, S state) =>\n        ((State<S, A>)ma).runState(state);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static State<S, A> Flatten<S, A>(this State<S, State<S, A>> mma) =>\n        mma.Bind(x => x);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static State<S, A> Flatten<S, A>(this State<S, K<State<S>, A>> mma) =>\n        mma.Bind(x => x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/State/Operators/State.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class StateExtensions\n{\n    extension<S, A, B>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static State<S, B> operator >>> (K<State<S>, A> ma, K<State<S>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, B> operator * (K<State<S>, Func<A, B>> mf, K<State<S>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, B> operator * (K<State<S>, A> ma, K<State<S>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<S, A, B, C>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, C>> operator * (\n            K<State<S>, Func<A, B, C>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, C>> operator * (\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<S, A, B, C, D>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, D>>> operator * (\n            K<State<S>, Func<A, B, C, D>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, D>>> operator * (\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<S, A, B, C, D, E>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<State<S>, Func<A, B, C, D, E>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<S, A, B, C, D, E, F>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<State<S>, Func<A, B, C, D, E, F>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<S, A, B, C, D, E, F, G>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<State<S>, Func<A, B, C, D, E, F, G>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<S, A, B, C, D, E, F, G, H>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<State<S>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<S, A, B, C, D, E, F, G, H, I>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<State<S>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<S, A, B, C, D, E, F, G, H, I, J>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<State<S>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<S, A, B, C, D, E, F, G, H, I, J, K>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<State<S>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<State<S>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<State<S>, A> ma,\n            K<State<S>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/State/Operators/State.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class StateExtensions\n{\n    extension<S, A, B>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, B> operator *(Func<A, B> f, K<State<S>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, B> operator *(K<State<S>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<S, A, B, C>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, C>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<S, A, B, C, D>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, D>>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<S, A, B, C, D, E>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<S, A, B, C, D, E, F>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<S, A, B, C, D, E, F, G>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<S, A, B, C, D, E, F, G, H>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<S, A, B, C, D, E, F, G, H, I>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<S, A, B, C, D, E, F, G, H, I, J>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<S, A, B, C, D, E, F, G, H, I, J, K>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<State<S>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static State<S, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<State<S>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/State/Operators/State.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterExtensions\n{\n    extension<W, A, B>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Writer<W, B> operator >> (K<Writer<W>, A> ma, Func<A, K<Writer<W>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Writer<W, B> operator >> (K<Writer<W>, A> lhs, K<Writer<W>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<W, A>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Writer<W, A> operator >> (K<Writer<W>, A> lhs, K<Writer<W>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/State/Operators/State.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class StateExtensions\n{\n    extension<S, A>(K<State<S>, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static State<S, A> operator +(K<State<S>, A> ma) =>\n            (State<S, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static State<S, A> operator >> (K<State<S>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/State/State.Module.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\npublic partial class State<S>\n{\n    public static State<S, A> pure<A>(A value) => \n        State<S, A>.Pure(value);\n}\n\npublic class State\n{\n    public static State<S, A> pure<S, A>(A value) =>  \n        State<S, A>.Pure(value);\n\n    public static State<S, S> get<S>() => \n        State<S, S>.Get;\n    \n    public static State<S, A> gets<S, A>(Func<S, A> f) => \n        State<S, A>.Gets(f);\n    \n    public static State<S, A> getsM<S, A>(Func<S, State<S, A>> f) => \n        State<S, A>.GetsM(f);\n\n    public static State<S, Unit> put<S>(S state) =>  \n        State<S, Unit>.Put(state);\n\n    public static State<S, Unit> modify<S>(Func<S, S> f) =>  \n        State<S, Unit>.Modify(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/State/State.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `State` monad transformer, which adds a modifiable state to a given monad. \n/// </summary>\n/// <typeparam name=\"S\">State type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record State<S, A>(Func<S, (A Value, S State)> runState) : K<State<S>, A>\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`State`</returns>\n    public static State<S, A> Pure(A value) =>\n        new (s => (value, s));\n\n    /// <summary>\n    /// Extracts the state value, maps it, and then puts it back into\n    /// the monadic state.\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`State`</returns>\n    public static State<S, Unit> Modify(Func<S, S> f) =>\n        new (s => (unit, f(s)));\n\n    /// <summary>\n    /// Writes the value into the monadic state\n    /// </summary>\n    /// <returns>`State`</returns>\n    public static State<S, Unit> Put(S value) =>\n        new (_ => (unit, value));\n\n    /// <summary>\n    /// Extracts the state value and returns it as the bound value\n    /// </summary>\n    /// <returns>`State`</returns>\n    public static State<S, S> Get { get; } =\n        new (s => (s, s));\n\n    /// <summary>\n    /// Extracts the state value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`State`</returns>\n    public static State<S, A> Gets(Func<S, A> f) =>\n        new (s => (f(s), s));\n\n    /// <summary>\n    /// Extracts the state value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`State`</returns>\n    public static State<S, A> GetsM(Func<S, State<S, A>> f) =>\n        State<S, State<S, A>>.Gets(f).Flatten();\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`State`</returns>\n    public static State<S, A> Lift(Pure<A> monad) =>\n        Pure(monad.Value);\n\n    /// <summary>\n    /// Lifts a function into the transformer \n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`State`</returns>\n    public static State<S, A> Lift(Func<A> f) =>\n        new(s => (f(), s));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, B> Map<B>(Func<A, B> f) =>\n        new(s => mapFirst(f, runState(s)));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, B> Select<B>(Func<A, B> f) =>\n        new(s => mapFirst(f, runState(s)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, B> Bind<B>(Func<A, K<State<S>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, B> Bind<B>(Func<A, State<S, B>> f) =>\n        new(s =>\n            {\n                var (a, s1) = runState(s);\n                return f(a).runState(s1);\n            });\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, B> Bind<B>(Func<A, Gets<S, B>> f) =>\n        Bind(x => f(x).ToState());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, Unit> Bind(Func<A, Put<S>> f) =>\n        Bind(x => f(x).ToState());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, Unit> Bind(Func<A, Modify<S>> f) =>\n        Bind(x => f(x).ToState());\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, C> SelectMany<B, C>(Func<A, K<State<S>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, C> SelectMany<B, C>(Func<A, State<S, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, C> SelectMany<C>(Func<A, Put<S>> bind, Func<A, Unit, C> project) =>\n        SelectMany(x => bind(x).ToState(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, C> SelectMany<B, C>(Func<A, Gets<S, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).ToState(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`State`</returns>\n    public State<S, C> SelectMany<C>(Func<A, Modify<S>> bind, Func<A, Unit, C> project) =>\n        SelectMany(x => bind(x).ToState(), project);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n\n    public static implicit operator State<S, A>(Pure<A> ma) =>\n        Pure(ma.Value);\n\n    public static State<S, A> operator >> (State<S, A> lhs, State<S, A> rhs) =>\n        lhs.Bind(_ => rhs);\n    \n    public static State<S, A> operator >> (State<S, A> lhs, K<State<S>, A> rhs) =>\n        lhs.Bind(_ => rhs);\n\n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static State<S, A> operator >> (State<S, A> lhs, State<S, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static State<S, A> operator >> (State<S, A> lhs, K<State<S>, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Run the monad\n    //\n\n    /// <summary>\n    /// Run the state monad \n    /// </summary>\n    /// <param name=\"state\">Initial state</param>\n    /// <returns>Bound monad</returns>\n    public (A Value, S State) Run(S state) =>\n        runState(state);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/State/Trait/State.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Traits implementation for `State` \n/// </summary>\n/// <typeparam name=\"S\">State environment type</typeparam>\npublic partial class State<S> : \n    Monad<State<S>>, \n    Stateful<State<S>, S>\n{\n    static K<State<S>, B> Monad<State<S>>.Bind<A, B>(K<State<S>, A> ma, Func<A, K<State<S>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<State<S>, B> Monad<State<S>>.Recur<A, B>(A value, Func<A, K<State<S>, Next<A, B>>> f) => \n        new State<S, B>(state =>\n                        {\n                            while (true)\n                            {\n                                (var mr, state) = f(value).Run(state);\n                                if (mr.IsDone) return (mr.Done, state);\n                                value = mr.Loop;\n                            }\n                        });\n\n    static K<State<S>, B> Functor<State<S>>.Map<A, B>(Func<A, B> f, K<State<S>, A> ma) => \n        ma.As().Map(f);\n\n    static K<State<S>, A> Applicative<State<S>>.Pure<A>(A value) => \n        State<S, A>.Pure(value);\n\n    static K<State<S>, B> Applicative<State<S>>.Apply<A, B>(K<State<S>, Func<A, B>> mf, K<State<S>, A> ma) => \n        mf.As().Bind(x => ma.As().Map(x));\n\n    static K<State<S>, B> Applicative<State<S>>.Apply<A, B>(K<State<S>, Func<A, B>> mf, Memo<State<S>, A> ma) => \n        mf.As().Bind(x => ma.Value.As().Map(x));\n\n    static K<State<S>, Unit> Stateful<State<S>, S>.Modify(Func<S, S> modify) => \n        State<S, S>.Modify(modify);\n\n    static K<State<S>, A> Stateful<State<S>, S>.Gets<A>(Func<S, A> f) => \n        State<S, A>.Gets(f);\n\n    static K<State<S>, Unit> Stateful<State<S>, S>.Put(S value) => \n        State<S, S>.Put(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Extensions/StateT.Extensions.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// State monad extensions\n/// </summary>\npublic static partial class StateTExtensions\n{\n    extension<S, M, A>(K<StateT<S, M>, A> ma) where M : Monad<M>\n    {\n        public StateT<S, M, A> As() =>\n            (StateT<S, M, A>)ma;\n\n        /// <summary>\n        /// Run the state monad \n        /// </summary>\n        /// <param name=\"state\">Initial state</param>\n        /// <returns>Bound monad</returns>\n        public K<M, (A Value, S State)> Run(S state) =>\n            ((StateT<S, M, A>)ma).runState(state);\n    }\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static StateT<S, M, A> Flatten<S, M, A>(this StateT<S, M, StateT<S, M, A>> mma)\n        where M : Monad<M> =>\n        mma.Bind(x => x);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, C> SelectMany<S, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<StateT<S, M>, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        StateT<S, M, A>.Lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, C> SelectMany<S, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, StateT<S, M, B>> bind, \n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        StateT<S, M, A>.Lift(ma).SelectMany(bind, project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Operators/StateT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class StateTExtensions\n{\n    extension<S, M, A, B>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static StateT<S, M, B> operator >>> (K<StateT<S, M>, A> ma, K<StateT<S, M>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, B> operator * (K<StateT<S, M>, Func<A, B>> mf, K<StateT<S, M>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, B> operator * (K<StateT<S, M>, A> ma, K<StateT<S, M>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<S, M, A, B, C>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, C>> operator * (\n            K<StateT<S, M>, Func<A, B, C>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, C>> operator * (\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<S, M, A, B, C, D>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, D>>> operator * (\n            K<StateT<S, M>, Func<A, B, C, D>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, D>>> operator * (\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<S, M, A, B, C, D, E>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<StateT<S, M>, Func<A, B, C, D, E>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<S, M, A, B, C, D, E, F>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<StateT<S, M>, Func<A, B, C, D, E, F>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<S, M, A, B, C, D, E, F, G>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<S, M, A, B, C, D, E, F, G, H>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<S, M, A, B, C, D, E, F, G, H, I>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<S, M, A, B, C, D, E, F, G, H, I, J>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<S, M, A, B, C, D, E, F, G, H, I, J, K>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<StateT<S, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<StateT<S, M>, A> ma,\n            K<StateT<S, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Operators/StateT.Operators.Choice.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class StateTExtensions\n{\n    extension<S, M, A>(K<StateT<S, M>, A> self)\n        where M : Monad<M>, Choice<M>\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static StateT<S, M, A> operator |(K<StateT<S, M>, A> lhs, K<StateT<S, M>, A> rhs) =>\n            new (s => lhs.As().runState(s) | rhs.As().runState(s));\n\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static StateT<S, M, A> operator |(K<StateT<S, M>, A> lhs, Pure<A> rhs) =>\n            new (s => lhs.As().runState(s) | rhs.Map(x => (x, env: s)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Operators/StateT.Operators.Fallible.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class StateTExtensions\n{\n    extension<S, E, M, A>(K<StateT<S, M>, A> self)\n        where M : Monad<M>, Fallible<E, M>\n    {\n        public static StateT<S, M, A> operator |(K<StateT<S, M>, A> lhs, CatchM<E, M, A> rhs) =>\n            new(s => lhs.As().runState(s) | rhs.Map(a => (a, env: s)));\n\n        public static StateT<S, M, A> operator |(K<StateT<S, M>, A> lhs, Fail<E> rhs) =>\n            new(s => lhs.As().runState(s) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Operators/StateT.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class StateTExtensions\n{\n    extension<S, X, M, A>(K<StateT<S, M>, A> _)\n        where M : Monad<M>, Final<M>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static StateT<S, M, A> operator |(K<StateT<S, M>, A> lhs, Finally<M, X> rhs) =>\n            new(s => lhs.As().runState(s) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Operators/StateT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class StateTExtensions\n{\n    extension<S, M, A, B>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, B> operator *(Func<A, B> f, K<StateT<S, M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, B> operator *(K<StateT<S, M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<S, M, A, B, C>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, C>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<S, M, A, B, C, D>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, D>>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<S, M, A, B, C, D, E>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<S, M, A, B, C, D, E, F>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<S, M, A, B, C, D, E, F, G>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<S, M, A, B, C, D, E, F, G, H>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<S, M, A, B, C, D, E, F, G, H, I>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<S, M, A, B, C, D, E, F, G, H, I, J>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<S, M, A, B, C, D, E, F, G, H, I, J, K>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<StateT<S, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static StateT<S, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<StateT<S, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Operators/StateT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class StateTExtensions\n{\n    extension<S, M, A, B>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static StateT<S, M, B> operator >> (K<StateT<S, M>, A> ma, Func<A, K<StateT<S, M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static StateT<S, M, B> operator >> (K<StateT<S, M>, A> lhs, K<StateT<S, M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<S, M, A>(K<StateT<S, M>, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static StateT<S, M, A> operator >> (K<StateT<S, M>, A> lhs, K<StateT<S, M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Operators/StateT.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class StateTExtensions\n{\n    extension<S, M, A>(K<StateT<S, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static StateT<S, M, A> operator +(K<StateT<S, M>, A> lhs, K<StateT<S, M>, A> rhs) =>\n            new(s => lhs.As().runState(s) + rhs.As().runState(s));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static StateT<S, M, A> operator +(K<StateT<S, M>, A> lhs, Pure<A> rhs) =>\n            new(s => lhs.As().runState(s) + M.Pure((rhs.Value, env: s)));\n    }\n    \n    extension<E, S, M, A>(K<StateT<S, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Fallible<E, M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static StateT<S, M, A> operator +(K<StateT<S, M>, A> lhs, Fail<E> rhs) =>\n            new(s => lhs.As().runState(s) + M.Fail<(A, S)>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Operators/StateT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class StateTExtensions\n{\n    extension<S, M, A>(K<StateT<S, M>, A> _)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static StateT<S, M, A> operator +(K<StateT<S, M>, A> ma) =>\n            (StateT<S, M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static StateT<S, M, A> operator >> (K<StateT<S, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/StateT.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class StateT<S>\n{\n    public static StateT<S, M, A> lift<M, A>(K<M, A> ma)  \n        where M : Monad<M> => \n        StateT<S, M, A>.Lift(ma);\n}\n\npublic partial class StateT<S, M>\n{\n    public static StateT<S, M, A> pure<A>(A value) => \n        StateT<S, M, A>.Pure(value);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"effect\">Monad to lift</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> liftIO<A>(IO<A> effect) =>\n        StateT<S, M, A>.LiftIO(effect);\n}\n\npublic class StateT\n{\n    public static StateT<S, M, A> pure<S, M, A>(A value)  \n        where M : Monad<M> => \n        StateT<S, M, A>.Pure(value);\n\n    public static StateT<S, M, A> lift<S, M, A>(K<M, A> ma)  \n        where M : Monad<M> => \n        StateT<S, M, A>.Lift(ma);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"effect\">Monad to lift</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> liftIO<S, M, A>(IO<A> effect)\n        where M : Monad<M> =>\n        StateT<S, M, A>.LiftIO(effect);\n    \n    public static StateT<S, M, S> get<M, S>() \n        where M : Monad<M> => \n        StateT<S, M, S>.Get;\n    \n    public static StateT<S, M, A> gets<M, S, A>(Func<S, A> f) \n        where M : Monad<M> => \n        StateT<S, M, A>.Gets(f);\n\n    public static StateT<S, M, A> getsM<M, S, A>(Func<S, K<M, A>> f) \n        where M : Monad<M> => \n        StateT<S, M, A>.GetsM(f);\n\n    public static StateT<S, M, Unit> put<M, S>(S state)  \n        where M : Monad<M> => \n        StateT<S, M, Unit>.Put(state);\n\n    public static StateT<S, M, Unit> modify<M, S>(Func<S, S> f)  \n        where M : Monad<M> => \n        StateT<S, M, Unit>.Modify(f);\n\n    public static StateT<S, M, Unit> modifyM<M, S>(Func<S, K<M, S>> f)  \n        where M : Monad<M> => \n        StateT<S, M, Unit>.ModifyM(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/StateT.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `StateT` monad transformer, which adds a modifiable state to a given monad. \n/// </summary>\n/// <param name=\"runState\">Function that represents the transformer operation</param>\n/// <typeparam name=\"S\">State type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record StateT<S, M, A>(Func<S, K<M, (A Value, S State)>> runState) : K<StateT<S, M>, A>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> Pure(A value) =>\n        Lift(M.Pure(value));\n\n    /// <summary>\n    /// Extracts the state value, maps it, and then puts it back into\n    /// the monadic state.\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, Unit> Modify(Func<S, S> f) =>\n        new(state => M.Pure((unit, f(state))));\n\n    /// <summary>\n    /// Extracts the state value, maps it, and then puts it back into\n    /// the monadic state.\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, Unit> ModifyM(Func<S, K<M, S>> f) =>\n        new(state => f(state).Map(s => (unit, s)));\n\n    /// <summary>\n    /// Writes the value into the monadic state\n    /// </summary>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, Unit> Put(S value) =>\n        new(_ => M.Pure((unit, value)));\n\n    /// <summary>\n    /// Writes a value and state into the monad\n    /// </summary>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> State(A value, S state) =>\n        new(_ => M.Pure((value, state)));\n\n    /// <summary>\n    /// Writes a value and state into the monad\n    /// </summary>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> State((A value, S state) ma) =>\n        new(_ => M.Pure(ma));\n\n    /// <summary>\n    /// Extracts the state value and returns it as the bound value\n    /// </summary>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, S> Get { get; } =\n        new(state => M.Pure((state, state)));\n\n    /// <summary>\n    /// Extracts the state value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> Gets(Func<S, A> f) =>\n        new(state => M.Pure((f(state), state)));\n\n    /// <summary>\n    /// Extracts the state value and maps it to the bound value\n    /// </summary>\n    /// <param name=\"f\">State mapping function</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> GetsM(Func<S, K<M, A>> f) =>\n        new(state => M.Map(v => (v, state), f(state)));\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> Lift(Pure<A> monad) =>\n        Pure(monad.Value);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> Lift(K<M, A> monad) =>\n        new(state => M.Map(value => (value, state), monad));\n\n    /// <summary>\n    /// Lifts a function into the transformer \n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> Lift(Func<A> f) =>\n        new(state => M.Pure((f(), state)));\n    \n    /// <summary>\n    /// Lifts an IO monad into the monad \n    /// </summary>\n    /// <remarks>NOTE: If the IO monad isn't the innermost monad of the transformer\n    /// stack then this will throw an exception.</remarks>\n    /// <param name=\"ma\">IO monad to lift</param>\n    /// <returns>`StateT`</returns>\n    public static StateT<S, M, A> LiftIO(IO<A> ma) =>\n        Lift(M.LiftIOMaybe(ma));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M1\">Trait of the monad to map to</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M1, B> MapT<M1, B>(Func<K<M, (A Value, S State)>, K<M1, (B Value, S State)>> f)\n        where M1 : Monad<M1>, Choice<M1> =>\n        new (state => f(runState(state)));\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new(state =>\n                runState(state)\n                   .Bind(vs => f(M.Pure(vs.Value)).Map(x => (x, vs.State))));\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, B> Map<B>(Func<A, B> f) =>\n        new(state => M.Map(x => (f(x.Value), x.State), runState(state)));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, B> Select<B>(Func<A, B> f) =>\n        new(state => M.Map(x => (f(x.Value), x.State), runState(state)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, B> Bind<B>(Func<A, K<StateT<S, M>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, B> Bind<B>(Func<A, StateT<S, M, B>> f) =>\n        new(state => M.Bind(runState(state), x => f(x.Value).runState(x.State)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, B> Bind<B>(Func<A, Gets<S, B>> f) =>\n        Bind(x => f(x).ToStateT<M>());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, Unit> Bind(Func<A, Put<S>> f) =>\n        Bind(x => f(x).ToStateT<M>());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, Unit> Bind(Func<A, Modify<S>> f) =>\n        Bind(x => f(x).ToStateT<M>());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, B> Bind<B>(Func<A, IO<B>> f) =>\n        Bind(x => StateT<S, M, B>.LiftIO(f(x)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, B> Bind<B>(Func<A, K<IO, B>> f) =>\n        Bind(x => StateT<S, M, B>.LiftIO(f(x).As()));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<B, C>(Func<A, K<StateT<S, M>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<B, C>(Func<A, StateT<S, M, B>> bind, Func<A, B, C> project) =>\n        new(state => M.Bind(runState(state), \n                            x => M.Map(y => (project(x.Value, y.Value), y.State), \n                                       bind(x.Value).runState(x.State))));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        new(state => M.Bind(runState(state), x => M.Map(y => (project(x.Value, y), x.State), bind(x.Value))));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<C>(Func<A, Put<S>> bind, Func<A, Unit, C> project) =>\n        Bind(x => bind(x).ToStateT<M>().Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<B, C>(Func<A, Gets<S, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).ToStateT<M>().Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<C>(Func<A, Modify<S>> bind, Func<A, Unit, C> project) =>\n        Bind(x => bind(x).ToStateT<M>().Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public StateT<S, M, C> SelectMany<B, C>(Func<A, K<IO, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).As().Map(y => project(x, y)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n\n    /// <summary>\n    /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n    /// as the semicolon) in C#.\n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the second action</returns>\n    public static StateT<S, M, A> operator >> (StateT<S, M, A> lhs, StateT<S, M, A> rhs) =>\n        lhs.Bind(_ => rhs);\n    \n    /// <summary>\n    /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n    /// as the semicolon) in C#.\n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the second action</returns>\n    public static StateT<S, M, A> operator >> (StateT<S, M, A> lhs, K<StateT<S, M>, A> rhs) =>\n        lhs.Bind(_ => rhs);\n\n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static StateT<S, M, A> operator >> (StateT<S, M, A> lhs, StateT<S, M, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static StateT<S, M, A> operator >> (StateT<S, M, A> lhs, K<StateT<S, M>, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    public static implicit operator StateT<S, M, A>(Pure<A> ma) =>\n        Pure(ma.Value);\n    \n    public static implicit operator StateT<S, M, A>(IO<A> ma) =>\n        LiftIO(ma);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Run the monad\n    //\n\n    /// <summary>\n    /// Run the state monad \n    /// </summary>\n    /// <param name=\"state\">Initial state</param>\n    /// <returns>Bound monad</returns>\n    public K<M, (A Value, S State)> Run(S state) =>\n        runState(state);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/State/StateT/Trait/StateT.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `MonadStateT` trait implementation for `StateT` \n/// </summary>\n/// <typeparam name=\"S\">State environment type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class StateT<S, M> : \n    MonadT<StateT<S, M>, M>, \n    Stateful<StateT<S, M>, S>\n    where M : Monad<M>\n{\n    static K<StateT<S, M>, B> Monad<StateT<S, M>>.Bind<A, B>(K<StateT<S, M>, A> ma, Func<A, K<StateT<S, M>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<StateT<S, M>, B> Monad<StateT<S, M>>.Recur<A, B>(A value, Func<A, K<StateT<S, M>, Next<A, B>>> f) => \n        new StateT<S, M, B>(\n            input =>\n            {\n                return M.Recur(f(value).As().runState(input), go);\n\n                K<M, Next<K<M, (Next<A, B>, S)>, (B, S)>> go(K<M, (Next<A, B> Next, S State)> ma) =>\n                    ma >> (n => n.Next switch\n                                {\n                                    { IsDone: true, Done: var x } =>\n                                        M.Pure(Next.Done<K<M, (Next<A, B>, S)>, (B, S)>((x, n.State))),\n\n                                    { IsLoop: true, Loop: var x } =>\n                                        M.Pure(Next.Loop<K<M, (Next<A, B>, S)>, (B, S)>(f(x).As().Run(n.State))),\n\n                                    _ => throw new NotSupportedException()\n                                });\n            });\n\n    static K<StateT<S, M>, B> Functor<StateT<S, M>>.Map<A, B>(Func<A, B> f, K<StateT<S, M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<StateT<S, M>, A> Applicative<StateT<S, M>>.Pure<A>(A value) => \n        StateT<S, M, A>.Pure(value);\n\n    static K<StateT<S, M>, B> Applicative<StateT<S, M>>.Apply<A, B>(K<StateT<S, M>, Func<A, B>> mf, K<StateT<S, M>, A> ma) => \n        mf.As().Bind(x => ma.As().Map(x));\n\n    static K<StateT<S, M>, B> Applicative<StateT<S, M>>.Apply<A, B>(K<StateT<S, M>, Func<A, B>> mf, Memo<StateT<S, M>, A> ma) => \n        mf.As().Bind(x => ma.Value.As().Map(x));\n\n    static K<StateT<S, M>, A> MonadT<StateT<S, M>, M>.Lift<A>(K<M, A> ma) => \n        StateT<S, M, A>.Lift(ma);\n\n    static K<StateT<S, M>, Unit> Stateful<StateT<S, M>, S>.Modify(Func<S, S> modify) => \n        StateT<S, M, S>.Modify(modify);\n\n    static K<StateT<S, M>, A> Stateful<StateT<S, M>, S>.Gets<A>(Func<S, A> f) => \n        StateT<S, M, A>.Gets(f);\n\n    static K<StateT<S, M>, Unit> Stateful<StateT<S, M>, S>.Put(S value) => \n        StateT<S, M, S>.Put(value);\n\n    static K<StateT<S, M>, A> Maybe.MonadIO<StateT<S, M>>.LiftIOMaybe<A>(IO<A> ma) =>\n        StateT<S, M, A>.Lift(M.LiftIOMaybe(ma));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Tell.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// State put\n/// </summary>\n/// <remarks>\n/// This is a convenience type that is created by the Prelude `put` function.  It avoids\n/// the need for lots of generic parameters when used in `WriterT` and `State` based\n/// monads.\n/// </remarks>\n/// <param name=\"F\">Mapping from the environment</param>\n/// <typeparam name=\"S\">State type</typeparam>\npublic record Tell<W>(W Value) where W : Monoid<W>\n{\n    /// <summary>\n    /// Convert with `Writable`\n    /// </summary>\n    public K<M, Unit> ToWritable<M>()\n        where M : Writable<M, W> =>\n        Writable.tell<M, W>(Value);\n\n    /// <summary>\n    /// Convert to a `WriterT`\n    /// </summary>\n    public WriterT<W, M, Unit> ToWriterT<M>()\n        where M : Monad<M> =>\n        Writable.tell<WriterT<W, M>, W>(Value).As();\n    \n    /// <summary>\n    /// Convert to a `WriterT`\n    /// </summary>\n    public Writer<W, Unit> ToWriter() =>\n        Writable.tell<Writer<W>, W>(Value).As();\n\n    /// <summary>\n    /// Monadic bind with `WriterT`\n    /// </summary>\n    public WriterT<W, M, C> SelectMany<M, B, C>(Func<Unit, WriterT<W, M, B>> bind, Func<Unit, B, C> project)\n        where M : Monad<M> =>\n        ToWriterT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind with `WriterT`\n    /// </summary>\n    public WriterT<W, M, C> SelectMany<M, B, C>(Func<Unit, K<WriterT<W, M>, B>> bind, Func<Unit, B, C> project)\n        where M : Monad<M> =>\n        ToWriterT<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind with `Writer`\n    /// </summary>\n    public Writer<W, C> SelectMany<B, C>(Func<Unit, Writer<W, B>> bind, Func<Unit, B, C> project) =>\n        ToWriter().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind with `Writer`\n    /// </summary>\n    public Writer<W, C> SelectMany<B, C>(Func<Unit, K<Writer<W>, B>> bind, Func<Unit, B, C> project) =>\n        ToWriter().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind with `RWST`\n    /// </summary>\n    public RWST<R, W, S, M, C> SelectMany<R, S, M, B, C>(Func<Unit, RWST<R, W, S, M, B>> bind, Func<Unit, B, C> project)\n        where M : Writable<M, W>, Monad<M>, Choice<M> =>\n        ToWritable<M>().SelectMany(bind, project);\n\n    /// <summary>\n    /// Monadic bind with `RWST`\n    /// </summary>\n    public RWST<R, W, S, M, C> SelectMany<R, S, M, B, C>(Func<Unit, K<RWST<R, W, S, M>, B>> bind, Func<Unit, B, C> project)\n        where M : Writable<M, W>, Monad<M>, Choice<M> =>\n        ToWritable<M>().SelectMany(bind, project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Extensions/Writer.Extensions.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterExtensions\n{\n    extension<W, A>(K<Writer<W>, A> ma) where W : Monoid<W>\n    {\n        public Writer<W, A> As() =>\n            (Writer<W, A>)ma;\n\n        /// <summary>\n        /// Run the writer \n        /// </summary>\n        /// <returns>Bound monad</returns>\n        public (A Value, W Output) Run(W initial) =>\n            ((Writer<W, A>)ma).runWriter(initial);\n\n        /// <summary>\n        /// Run the writer \n        /// </summary>\n        /// <returns>Bound monad</returns>\n        public (A Value, W Output) Run() =>\n            ((Writer<W, A>)ma).runWriter(W.Empty);\n    }\n\n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static Writer<W, A> Flatten<W, A>(this Writer<W, Writer<W, A>> mma)\n        where W : Monoid<W> =>\n        mma.Bind(x => x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Operators/Writer.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class WriterExtensions\n{\n    extension<W, A, B>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Writer<W, B> operator >>> (K<Writer<W>, A> ma, K<Writer<W>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, B> operator * (K<Writer<W>, Func<A, B>> mf, K<Writer<W>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, B> operator * (K<Writer<W>, A> ma, K<Writer<W>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<W, A, B, C>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, C>> operator * (\n            K<Writer<W>, Func<A, B, C>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, C>> operator * (\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<W, A, B, C, D>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, D>>> operator * (\n            K<Writer<W>, Func<A, B, C, D>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, D>>> operator * (\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<W, A, B, C, D, E>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Writer<W>, Func<A, B, C, D, E>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<W, A, B, C, D, E, F>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Writer<W>, Func<A, B, C, D, E, F>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<W, A, B, C, D, E, F, G>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Writer<W>, Func<A, B, C, D, E, F, G>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<W, A, B, C, D, E, F, G, H>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Writer<W>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<W, A, B, C, D, E, F, G, H, I>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Writer<W>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<W, A, B, C, D, E, F, G, H, I, J>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Writer<W>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<W, A, B, C, D, E, F, G, H, I, J, K>(K<Writer<W>, A> self)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Writer<W>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Writer<W>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Writer<W>, A> ma,\n            K<Writer<W>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Operators/Writer.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class WriterExtensions\n{\n    extension<W, A, B>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, B> operator *(Func<A, B> f, K<Writer<W>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, B> operator *(K<Writer<W>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<W, A, B, C>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, C>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<W, A, B, C, D>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, D>>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<W, A, B, C, D, E>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<W, A, B, C, D, E, F>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<W, A, B, C, D, E, F, G>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<W, A, B, C, D, E, F, G, H>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<W, A, B, C, D, E, F, G, H, I>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<W, A, B, C, D, E, F, G, H, I, J>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<W, A, B, C, D, E, F, G, H, I, J, K>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Writer<W>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Writer<W, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Writer<W>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Operators/Writer.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ReaderExtensions\n{\n    extension<S, A, B>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static State<S, B> operator >> (K<State<S>, A> ma, Func<A, K<State<S>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static State<S, B> operator >> (K<State<S>, A> lhs, K<State<S>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<S, A>(K<State<S>, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static State<S, A> operator >> (K<State<S>, A> lhs, K<State<S>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Operators/Writer.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterExtensions\n{\n    extension<W, A>(K<Writer<W>, A> _)\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Writer<W, A> operator +(K<Writer<W>, A> ma) =>\n            (Writer<W, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Writer<W, A> operator >> (K<Writer<W>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Prelude/Writer.Prelude.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Prelude\n{\n    /// <summary>\n    /// Tell is an action that produces the writer output\n    /// </summary>\n    /// <param name=\"item\">Item to tell</param>\n    /// <typeparam name=\"W\">Writer type</typeparam>\n    /// <returns>Structure with the told item</returns>\n    public static Writer<W, Unit> tell<W>(W item)\n        where W : Monoid<W> =>\n        new (w => (default, w + item));\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static Writer<W, A> write<W, A>((A, W) item) \n        where W : Monoid<W> =>\n        Writable.write<W, Writer<W>, A>(item).As();\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static Writer<W, A> write<W, A>(A value, W item)\n        where W : Monoid<W> =>\n        Writable.write<W, Writer<W>, A>(value, item).As();\n\n    /// <summary>\n    /// `pass` is an action that executes the `action`, which returns a value and a\n    /// function; it then returns the value with the output having been applied to\n    /// the function.\n    /// </summary>\n    public static Writer<W, A> pass<W, A>(Writer<W, (A Value, Func<W, W> Function)> action)\n        where W : Monoid<W> =>\n        Writable.pass(action).As();\n\n    /// <summary>\n    /// `listen` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static Writer<W, (A Value, W Output)> listen<W, A>(Writer<W, A> ma)\n        where W : Monoid<W> =>\n        Writable.listen<W, Writer<W>, A>(ma).As();\n\n    /// <summary>\n    /// `listens` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static Writer<W, (A Value, B Output)> listens<W, A, B>(Func<W, B> f, Writer<W, A> ma)\n        where W : Monoid<W> =>\n        Writable.listens(f, ma).As();\n\n    /// <summary>\n    /// `censor` executes the action `ma` and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public static Writer<W, A> censor<W, A>(Func<W, W> f, Writer<W, A> ma)\n        where W : Monoid<W> =>\n        Writable.censor(f, ma).As();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Trait/Writer.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `MonadStateT` trait implementation for `StateT` \n/// </summary>\n/// <typeparam name=\"S\">State environment type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class Writer<W> : \n    Monad<Writer<W>>, \n    Writable<Writer<W>, W>\n    where W : Monoid<W>\n{\n    static K<Writer<W>, B> Monad<Writer<W>>.Bind<A, B>(K<Writer<W>, A> ma, Func<A, K<Writer<W>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<Writer<W>, B> Monad<Writer<W>>.Recur<A, B>(A value, Func<A, K<Writer<W>, Next<A, B>>> f) => \n        new Writer<W, B>(output =>\n                         {\n                             while (true)\n                             {\n                                 (var mr, output) = f(value).Run(output);\n                                 if (mr.IsDone) return (mr.Done, output);\n                                 value = mr.Loop;\n                             }\n                         });\n\n    static K<Writer<W>, B> Functor<Writer<W>>.Map<A, B>(Func<A, B> f, K<Writer<W>, A> ma) => \n        ma.As().Map(f);\n\n    static K<Writer<W>, A> Applicative<Writer<W>>.Pure<A>(A value) => \n        Writer<W, A>.Pure(value);\n\n    static K<Writer<W>, B> Applicative<Writer<W>>.Apply<A, B>(K<Writer<W>, Func<A, B>> mf, K<Writer<W>, A> ma) => \n        mf.As().Bind(x => ma.As().Map(x));\n\n    static K<Writer<W>, B> Applicative<Writer<W>>.Apply<A, B>(K<Writer<W>, Func<A, B>> mf, Memo<Writer<W>, A> ma) => \n        mf.As().Bind(x => ma.Value.As().Map(x));\n\n    static K<Writer<W>, Unit> Writable<Writer<W>, W>.Tell(W item) =>\n        new Writer<W, Unit>(w => (unit, w + item));\n\n    static K<Writer<W>, (A Value, W Output)> Writable<Writer<W>, W>.Listen<A>(K<Writer<W>, A> ma) =>\n        ma.As().Listen();\n\n    static K<Writer<W>, A> Writable<Writer<W>, W>.Pass<A>(\n        K<Writer<W>, (A Value, Func<W, W> Function)> action) =>\n        new Writer<W, A>(\n            w =>\n            {\n                var ((a, f), w1) = action.As().Run();\n                return (a, w + f(w1));\n            });\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Writer.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Writer<W>\n{\n    public static Writer<W, A> pure<A>(A value) => \n        Writer<W, A>.Pure(value);\n}\n\npublic class Writer\n{\n    public static Writer<W, A> pure<W, A>(A value)  \n        where W : Monoid<W> => \n        Writer<W, A>.Pure(value);\n\n    /// <summary>\n    /// Tell is an action that produces the writer output\n    /// </summary>\n    /// <param name=\"item\">Item to tell</param>\n    /// <typeparam name=\"W\">Writer type</typeparam>\n    /// <returns>Structure with the told item</returns>\n    public static Writer<W, Unit> tell<W>(W item)\n        where W : Monoid<W> =>\n        new (w => (default, w + item));\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static Writer<W, A> write<W, A>((A, W) item) \n        where W : Monoid<W> =>\n        Writable.write<W, Writer<W>, A>(item).As();\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static Writer<W, A> write<W, A>(A value, W item)\n        where W : Monoid<W> =>\n        Writable.write<W, Writer<W>, A>(value, item).As();\n\n    /// <summary>\n    /// `pass` is an action that executes the `action`, which returns a value and a\n    /// function; it then returns the value with the output having been applied to\n    /// the function.\n    /// </summary>\n    public static Writer<W, A> pass<W, A>(Writer<W, (A Value, Func<W, W> Function)> action)\n        where W : Monoid<W> =>\n        Writable.pass(action).As();\n\n    /// <summary>\n    /// `listen` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static Writer<W, (A Value, W Output)> listen<W, A>(Writer<W, A> ma)\n        where W : Monoid<W> =>\n        Writable.listen<W, Writer<W>, A>(ma).As();\n\n    /// <summary>\n    /// `listens` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static Writer<W, (A Value, B Output)> listens<W, A, B>(Func<W, B> f, Writer<W, A> ma)\n        where W : Monoid<W> =>\n        Writable.listens(f, ma).As();\n\n    /// <summary>\n    /// `censor` executes the action `ma` and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public static Writer<W, A> censor<W, A>(Func<W, W> f, Writer<W, A> ma)\n        where W : Monoid<W> =>\n        Writable.censor(f, ma).As();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/Writer/Writer.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `Writer` monad transformer, which adds a modifiable state to a given monad. \n/// </summary>\n/// <typeparam name=\"S\">State type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record Writer<W, A>(Func<W, (A Value, W Output)> runWriter) : K<Writer<W>, A>\n    where W : Monoid<W>\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`Writer`</returns>\n    public static Writer<W, A> Pure(A value) =>\n        new (w => (value, w));\n\n    /// <summary>\n    /// Construct a writer computation from a (result, output) pair.\n    /// </summary>\n    /// <remarks>\n    /// The inverse of `Run()`\n    /// </remarks>\n    /// <param name=\"result\">Result / Output pair</param>\n    public Writer<W, A> Write((A Value, W Output) result) =>\n        new(w => (result.Value, w.Combine(result.Output)));\n\n    /// <summary>\n    /// Construct a writer computation from a (result, output) pair.\n    /// </summary>\n    /// <remarks>\n    /// The inverse of `Run()`\n    /// </remarks>\n    /// <param name=\"result\">Result / Output pair</param>\n    public Writer<W, A> Write(A value, W output) =>\n        new(w => (value, w.Combine(output)));\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public Writer<W, (A Value, W Output)> Listen() =>\n        Listens(x => x);\n\n    /// <summary>\n    /// `Listens` executes the action and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public Writer<W, (A Value, B Output)> Listens<B>(Func<W, B> f) =>\n        new(w =>\n            {\n                var (a, w1) = Run();\n                return ((a, f(w1)), w + w1);\n            });\n\n    /// <summary>\n    /// `Censor` executes the action and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public Writer<W, A> Censor(Func<W, W> f) =>\n        new (w =>\n             {\n                 var (a, w1) = Run();\n                 return (a, w + f(w1));\n             });\n    \n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`Writer`</returns>\n    public static Writer<W, A> Lift(Pure<A> monad) =>\n        Pure(monad.Value);\n\n    /// <summary>\n    /// Lifts a function into the transformer \n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`Writer`</returns>\n    public static Writer<W, A> Lift(Func<A> f) =>\n        new(w => (f(), w));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, B> Map<B>(Func<A, B> f) =>\n        new(w => mapFirst(f, runWriter(w)));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, B> Select<B>(Func<A, B> f) =>\n        new(w => mapFirst(f, runWriter(w)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, B> Bind<B>(Func<A, K<Writer<W>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, B> Bind<B>(Func<A, Writer<W, B>> f) =>\n        new(w =>\n            {\n                var (a, w1) = runWriter(w);\n                return f(a).runWriter(w1);\n            });\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, Unit> Bind<B>(Func<A, Tell<W>> f) =>\n        Bind(x => f(x).ToWriter());\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, C> SelectMany<B, C>(Func<A, K<Writer<W>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, C> SelectMany<B, C>(Func<A, Writer<W, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`Writer`</returns>\n    public Writer<W, C> SelectMany<C>(Func<A, Tell<W>> bind, Func<A, Unit, C> project) =>\n        SelectMany(x => bind(x).ToWriter(), project);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n\n    /// <summary>\n    /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n    /// as the semicolon) in C#.\n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the second action</returns>\n    public static Writer<W, A> operator >> (Writer<W, A> lhs, Writer<W, A> rhs) =>\n        lhs.Bind(_ => rhs);\n    \n    /// <summary>\n    /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n    /// as the semicolon) in C#.\n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the second action</returns>\n    public static Writer<W, A> operator >> (Writer<W, A> lhs, K<Writer<W>, A> rhs) =>\n        lhs.Bind(_ => rhs);\n\n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static Writer<W, A> operator >> (Writer<W, A> lhs, Writer<W, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static Writer<W, A> operator >> (Writer<W, A> lhs, K<Writer<W>, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    public static implicit operator Writer<W, A>(Pure<A> ma) =>\n        Pure(ma.Value);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Run the monad\n    //\n\n    /// <summary>\n    /// Run the writer \n    /// </summary>\n    /// <returns>Bound monad</returns>\n    public (A Value, W Output) Run() =>\n        runWriter(W.Empty);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Extensions/WriterT.Extensions.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterTExtensions\n{\n    public static WriterT<W, M, A> As<W, M, A>(this K<WriterT<W, M>, A> ma)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        (WriterT<W, M, A>)ma;\n\n    /// <summary>\n    /// Run the writer \n    /// </summary>\n    /// <returns>Bound monad</returns>\n    public static K<M, (A Value, W Output)> Run<W, M, A>(this K<WriterT<W, M>, A> ma) \n        where M : Monad<M> \n        where W : Monoid<W> =>\n        ((WriterT<W, M, A>)ma).runWriter(W.Empty);\n\n    /// <summary>\n    /// Run the writer \n    /// </summary>\n    /// <returns>Bound monad</returns>\n    public static K<M, (A Value, W Output)> Run<W, M, A>(this K<WriterT<W, M>, A> ma, W initial) \n        where M : Monad<M> \n        where W : Monoid<W> =>\n        ((WriterT<W, M, A>)ma).runWriter(initial);\n    \n    /// <summary>\n    /// Monadic join\n    /// </summary>\n    [Pure]\n    public static WriterT<W, M, A> Flatten<W, M, A>(this WriterT<W, M, WriterT<W, M, A>> mma)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        mma.Bind(x => x);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public static WriterT<W, M, C> SelectMany<W, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, K<WriterT<W, M>, B>> bind, \n        Func<A, B, C> project)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        WriterT<W, M, A>.Lift(ma).SelectMany(bind, project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`StateT`</returns>\n    public static WriterT<W, M, C> SelectMany<W, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, WriterT<W, M, B>> bind, \n        Func<A, B, C> project)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        WriterT<W, M, A>.Lift(ma).SelectMany(bind, project);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Operators/WriterT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class StateTExtensions\n{\n    extension<W, M, A, B>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static WriterT<W, M, B> operator >>> (K<WriterT<W, M>, A> ma, K<WriterT<W, M>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, B> operator * (K<WriterT<W, M>, Func<A, B>> mf, K<WriterT<W, M>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, B> operator * (K<WriterT<W, M>, A> ma, K<WriterT<W, M>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<W, M, A, B, C>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, C>> operator * (\n            K<WriterT<W, M>, Func<A, B, C>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, C>> operator * (\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<W, M, A, B, C, D>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, D>>> operator * (\n            K<WriterT<W, M>, Func<A, B, C, D>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, D>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<W, M, A, B, C, D, E>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<WriterT<W, M>, Func<A, B, C, D, E>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<W, M, A, B, C, D, E, F>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<WriterT<W, M>, Func<A, B, C, D, E, F>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<W, M, A, B, C, D, E, F, G>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<W, M, A, B, C, D, E, F, G, H>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<W, M, A, B, C, D, E, F, G, H, I>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<W, M, A, B, C, D, E, F, G, H, I, J>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<W, M, A, B, C, D, E, F, G, H, I, J, K>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<WriterT<W, M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<WriterT<W, M>, A> ma,\n            K<WriterT<W, M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Operators/WriterT.Operators.Choice.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterTExtensions\n{\n    extension<W, M, A>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>, Choice<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static WriterT<W, M, A> operator |(K<WriterT<W, M>, A> lhs, K<WriterT<W, M>, A> rhs) =>\n            new (output => lhs.As().runWriter(output) | rhs.As().runWriter(output));\n\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static WriterT<W, M, A> operator |(K<WriterT<W, M>, A> lhs, Pure<A> rhs) =>\n            new (output => lhs.As().runWriter(output) | rhs.Map(x => (x, env: output)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Operators/WriterT.Operators.Fallible.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterTExtensions\n{\n    extension<W, E, M, A>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>, Fallible<E, M>\n        where W : Monoid<W>\n    {\n        public static WriterT<W, M, A> operator |(K<WriterT<W, M>, A> lhs, CatchM<E, M, A> rhs) =>\n            new(output => lhs.As().runWriter(output) | rhs.Map(a => (a, env: output)));\n\n        public static WriterT<W, M, A> operator |(K<WriterT<W, M>, A> lhs, Fail<E> rhs) =>\n            new(output => lhs.As().runWriter(output) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Operators/WriterT.Operators.Final.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class WriterTExtensions\n{\n    extension<W, X, M, A>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>, Final<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static WriterT<W, M, A> operator |(K<WriterT<W, M>, A> lhs, Finally<M, X> rhs) =>\n            new(output => lhs.As().runWriter(output) | rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Operators/WriterT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class WriterTExtensions\n{\n    extension<W, M, A, B>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, B> operator *(Func<A, B> f, K<WriterT<W, M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, B> operator *(K<WriterT<W, M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<W, M, A, B, C>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, C>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<W, M, A, B, C, D>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, D>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<W, M, A, B, C, D, E>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<W, M, A, B, C, D, E, F>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<W, M, A, B, C, D, E, F, G>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<W, M, A, B, C, D, E, F, G, H>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<W, M, A, B, C, D, E, F, G, H, I>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<W, M, A, B, C, D, E, F, G, H, I, J>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<W, M, A, B, C, D, E, F, G, H, I, J, K>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<WriterT<W, M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static WriterT<W, M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<WriterT<W, M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Operators/WriterT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterTExtensions\n{\n    extension<W, M, A, B>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static WriterT<W, M, B> operator >> (K<WriterT<W, M>, A> ma, Func<A, K<WriterT<W, M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static WriterT<W, M, B> operator >> (K<WriterT<W, M>, A> lhs, K<WriterT<W, M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<W, M, A>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static WriterT<W, M, A> operator >> (K<WriterT<W, M>, A> lhs, K<WriterT<W, M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Operators/WriterT.Operators.SemigroupK.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterTExtensions\n{\n    extension<W, M, A>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static WriterT<W, M, A> operator +(K<WriterT<W, M>, A> lhs, K<WriterT<W, M>, A> rhs) =>\n            new(output => lhs.As().runWriter(output) + rhs.As().runWriter(output));\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static WriterT<W, M, A> operator +(K<WriterT<W, M>, A> lhs, Pure<A> rhs) =>\n            new(s => lhs.As().runWriter(s) + M.Pure((rhs.Value, env: s)));\n    }\n    \n    extension<E, W, M, A>(K<WriterT<W, M>, A> self)\n        where M : Monad<M>, SemigroupK<M>, Fallible<E, M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static WriterT<W, M, A> operator +(K<WriterT<W, M>, A> lhs, Fail<E> rhs) =>\n            new(output => lhs.As().runWriter(output) + M.Fail<(A, W)>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Operators/WriterT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WriterTExtensions\n{\n    extension<W, M, A>(K<WriterT<W, M>, A> _)\n        where M : Monad<M>\n        where W : Monoid<W>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static WriterT<W, M, A> operator +(K<WriterT<W, M>, A> ma) =>\n            (WriterT<W, M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static WriterT<W, M, A> operator >> (K<WriterT<W, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/Trait/WriterT.TraitImpl.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `MonadStateT` trait implementation for `StateT` \n/// </summary>\n/// <typeparam name=\"S\">State environment type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\npublic partial class WriterT<W, M> : \n    MonadT<WriterT<W, M>, M>, \n    Writable<WriterT<W, M>, W>\n    where M : Monad<M>\n    where W : Monoid<W>\n{\n    static K<WriterT<W, M>, B> Monad<WriterT<W, M>>.Bind<A, B>(K<WriterT<W, M>, A> ma, Func<A, K<WriterT<W, M>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<WriterT<W, M>, B> Monad<WriterT<W, M>>.Recur<A, B>(A value, Func<A, K<WriterT<W, M>, Next<A, B>>> f) => \n        new WriterT<W, M, B>(\n            output =>\n            {\n                return M.Recur(f(value).As().runWriter(output), go);\n\n                K<M, Next<K<M, (Next<A, B>, W)>, (B, W)>> go(K<M, (Next<A, B> Next, W Output)> ma) =>\n                    ma >> (n => n.Next switch\n                                {\n                                    { IsDone: true, Done: var x } =>\n                                        M.Pure(Next.Done<K<M, (Next<A, B>, W)>, (B, W)>((x, n.Output))),\n\n                                    { IsLoop: true, Loop: var x } =>\n                                        M.Pure(Next.Loop<K<M, (Next<A, B>, W)>, (B, W)>(f(x).As().Run(n.Output))),\n\n                                    _ => throw new NotSupportedException()\n                                });\n            });\n\n    static K<WriterT<W, M>, B> Functor<WriterT<W, M>>.Map<A, B>(Func<A, B> f, K<WriterT<W, M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<WriterT<W, M>, A> Applicative<WriterT<W, M>>.Pure<A>(A value) => \n        WriterT<W, M, A>.Pure(value);\n\n    static K<WriterT<W, M>, B> Applicative<WriterT<W, M>>.Apply<A, B>(K<WriterT<W, M>, Func<A, B>> mf, K<WriterT<W, M>, A> ma) => \n        mf.As().Bind(x => ma.As().Map(x));\n\n    static K<WriterT<W, M>, B> Applicative<WriterT<W, M>>.Apply<A, B>(K<WriterT<W, M>, Func<A, B>> mf, Memo<WriterT<W, M>, A> ma) => \n        mf.As().Bind(x => ma.Value.As().Map(x));\n\n    static K<WriterT<W, M>, A> MonadT<WriterT<W, M>, M>.Lift<A>(K<M, A> ma) => \n        WriterT<W, M, A>.Lift(ma);\n    \n    static K<WriterT<W, M>, A> Maybe.MonadIO<WriterT<W, M>>.LiftIOMaybe<A>(IO<A> ma) =>\n        WriterT<W, M, A>.Lift(M.LiftIOMaybe(ma));\n\n    static K<WriterT<W, M>, Unit> Writable<WriterT<W, M>, W>.Tell(W item) =>\n        new WriterT<W, M, Unit>(w => M.Pure((unit, w + item)));\n\n    static K<WriterT<W, M>, (A Value, W Output)> Writable<WriterT<W, M>, W>.Listen<A>(K<WriterT<W, M>, A> ma) =>\n        ma.As().Listen;\n\n    static K<WriterT<W, M>, A> Writable<WriterT<W, M>, W>.Pass<A>(\n        K<WriterT<W, M>, (A Value, Func<W, W> Function)> action) =>\n        new WriterT<W, M, A>(\n            w => action.As()\n                       .Run()\n                       .Map(afw => (afw.Value.Value, w + afw.Value.Function(afw.Output))));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/WriterT.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n\npublic class WriterT<W>\n    where W : Monoid<W>\n{\n    public static WriterT<W, M, A> lift<M, A>(K<M, A> ma)\n        where M : Monad<M> => \n        WriterT<W, M, A>.Lift(ma);\n}\n\npublic partial class WriterT<W, M>\n{\n    public static WriterT<W, M, A> pure<A>(A value) => \n        WriterT<W, M, A>.Pure(value);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"effect\">Monad to lift</param>\n    /// <returns>`WriterT`</returns>\n    public static WriterT<W, M, A> liftIO<A>(IO<A> effect) =>\n        WriterT<W, M, A>.LiftIO(effect);\n}\n\npublic class WriterT\n{\n    public static WriterT<W, M, A> pure<W, M, A>(A value)  \n        where W : Monoid<W>\n        where M : Monad<M> => \n        WriterT<W, M, A>.Pure(value);\n\n    public static WriterT<W, M, A> lift<W, M, A>(K<M, A> ma)  \n        where W : Monoid<W>\n        where M : Monad<M> => \n        WriterT<W, M, A>.Lift(ma);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"effect\">Monad to lift</param>\n    /// <returns>`WriterT`</returns>\n    public static WriterT<W, M, A> liftIO<W, M, A>(IO<A> effect)\n        where W : Monoid<W>\n        where M : Monad<M> =>\n        WriterT<W, M, A>.LiftIO(effect);\n\n    /// <summary>\n    /// Tell is an action that produces the writer output\n    /// </summary>\n    /// <param name=\"item\">Item to tell</param>\n    /// <typeparam name=\"W\">Writer type</typeparam>\n    /// <returns>Structure with the told item</returns>\n    public static WriterT<W, M, Unit> tell<W, M>(W item)\n        where M : Monad<M>\n        where W : Monoid<W> =>\n        new (w => M.Pure((default(Unit), w + item)));\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static WriterT<W, M, A> write<W, M, A>((A, W) item)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        new (w => M.Pure((item.Item1, w + item.Item2)));\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static WriterT<W, M, A> write<W, M, A>(A value, W item)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        new (w => M.Pure((value, w + item)));\n\n    /// <summary>\n    /// `pass` is an action that executes the `action`, which returns a value and a\n    /// function; it then returns the value with the output having been applied to\n    /// the function.\n    /// </summary>\n    public static WriterT<W, M, A> pass<W, M, A>(WriterT<W, M, (A Value, Func<W, W> Function)> action)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        Writable.pass(action).As();\n\n    /// <summary>\n    /// `listen` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static WriterT<W, M, (A Value, W Output)> listen<W, M, A>(WriterT<W, M, A> ma)\n        where M : Monad<M>\n        where W : Monoid<W> =>\n        Writable.listen<W, WriterT<W, M>, A>(ma).As();\n\n    /// <summary>\n    /// `listens` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static WriterT<W, M, (A Value, B Output)> listens<W, M, A, B>(Func<W, B> f, WriterT<W, M, A> ma)\n        where M : Monad<M>\n        where W : Monoid<W> =>\n        Writable.listens(f, ma).As();\n\n    /// <summary>\n    /// `censor` executes the action `ma` and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public static WriterT<W, M, A> censor<W, M, A>(Func<W, W> f, WriterT<W, M, A> ma)\n        where M : Monad<M> \n        where W : Monoid<W> =>\n        Writable.censor(f, ma).As();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/State and Environment Monads/Writer/WriterT/WriterT.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `WriterT` monad transformer, which adds a modifiable state to a given monad. \n/// </summary>\n/// <typeparam name=\"S\">State type</typeparam>\n/// <typeparam name=\"M\">Given monad trait</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record WriterT<W, M, A>(Func<W, K<M, (A Value, W Output)>> runWriter) : K<WriterT<W, M>, A>\n    where M : Monad<M>\n    where W : Monoid<W>\n{\n    /// <summary>\n    /// Lift a pure value into the monad-transformer\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <returns>`WriterT`</returns>\n    public static WriterT<W, M, A> Pure(A value) =>\n        new (w => M.Pure((value, w)));\n\n    /// <summary>\n    /// Construct a writer computation from a (result, output) pair.\n    /// </summary>\n    /// <remarks>\n    /// The inverse of `Run()`\n    /// </remarks>\n    /// <param name=\"result\">Result / Output pair</param>\n    public static WriterT<W, M, A> Write((A Value, W Output) result) =>\n        new(w => M.Pure((result.Value, w.Combine(result.Output))));\n\n    /// <summary>\n    /// Construct a writer computation from a (result, output) pair.\n    /// </summary>\n    /// <remarks>\n    /// The inverse of `Run()`\n    /// </remarks>\n    /// <param name=\"result\">Result / Output pair</param>\n    public static WriterT<W, M, A> Write(A value, W output) =>\n        new(w => M.Pure((value, w.Combine(output))));\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public WriterT<W, M, (A Value, W Output)> Listen =>\n        Listens(x => x);\n\n    /// <summary>\n    /// `Listens` executes the action and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public WriterT<W, M, (A Value, B Output)> Listens<B>(Func<W, B> f) =>\n        new(w => Run().Map(aw => ((aw.Value, f(aw.Output)), w + aw.Output)));\n\n    /// <summary>\n    /// `Censor` executes the action and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public WriterT<W, M, A> Censor(Func<W, W> f) =>\n        new(w => Run().Map(aw => (aw.Value, w + f(aw.Output)))); \n    \n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`WriterT`</returns>\n    public static WriterT<W, M, A> Lift(Pure<A> monad) =>\n        Pure(monad.Value);\n\n    /// <summary>\n    /// Lifts a given monad into the transformer\n    /// </summary>\n    /// <param name=\"monad\">Monad to lift</param>\n    /// <returns>`WriterT`</returns>\n    public static WriterT<W, M, A> Lift(K<M, A> monad) =>\n        new(w => M.Map(value => (value, w), monad));\n\n    /// <summary>\n    /// Lifts a function into the transformer \n    /// </summary>\n    /// <param name=\"f\">Function to lift</param>\n    /// <returns>`WriterT`</returns>\n    public static WriterT<W, M, A> Lift(Func<A> f) =>\n        new(w => M.Pure((f(), w)));\n    \n    /// <summary>\n    /// Lifts a an IO monad into the monad \n    /// </summary>\n    /// <remarks>NOTE: If the IO monad isn't the innermost monad of the transformer\n    /// stack then this will throw an exception.</remarks>\n    /// <param name=\"ma\">IO monad to lift</param>\n    /// <returns>`WriterT`</returns>\n    public static WriterT<W, M, A> LiftIO(IO<A> ma) =>\n        Lift(M.LiftIOMaybe(ma));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Map\n    //\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M1\">Trait of the monad to map to</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M1, B> MapT<M1, B>(Func<K<M, (A Value, W Output)>, K<M1, (B Value, W Output)>> f)\n        where M1 : Monad<M1>, Choice<M1> =>\n        new (w => f(runWriter(w)));\n\n    /// <summary>\n    /// Maps the given monad\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>`StateT`</returns>\n    public WriterT<W, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new(state =>\n                runWriter(state)\n                   .Bind(vs => f(M.Pure(vs.Value)).Map(x => (x, vs.Output))));\n\n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, B> Map<B>(Func<A, B> f) =>\n        new(w => M.Map(x => (f(x.Value), x.Output), runWriter(w)));\n    \n    /// <summary>\n    /// Maps the bound value\n    /// </summary>\n    /// <param name=\"f\">Mapping transducer</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, B> Select<B>(Func<A, B> f) =>\n        new(w => M.Map(x => (f(x.Value), x.Output), runWriter(w)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Bind\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, B> Bind<B>(Func<A, K<WriterT<W, M>, B>> f) =>\n        Bind(x => f(x).As());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, B> Bind<B>(Func<A, WriterT<W, M, B>> f) =>\n        new(w => M.Bind(\n                      runWriter(w), \n                      mx => f(mx.Value).runWriter(mx.Output)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, Unit> Bind<B>(Func<A, Tell<W>> f) =>\n        Bind(x => f(x).ToWriterT<M>());\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, B> Bind<B>(Func<A, IO<B>> f) =>\n        Bind(x => WriterT<W, M, B>.LiftIO(f(x)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  SelectMany\n    //\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, C> SelectMany<B, C>(Func<A, K<WriterT<W, M>, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, C> SelectMany<B, C>(Func<A, WriterT<W, M, B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => WriterT<W, M, B>.Lift(bind(x)), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(x => project(x, bind(x).Value));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, C> SelectMany<C>(Func<A, Tell<W>> bind, Func<A, Unit, C> project) =>\n        SelectMany(x => bind(x).ToWriterT<M>(), project);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>`WriterT`</returns>\n    public WriterT<W, M, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Operators\n    //\n\n    /// <summary>\n    /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n    /// as the semicolon) in C#.\n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the second action</returns>\n    public static WriterT<W, M, A> operator >> (WriterT<W, M, A> lhs, WriterT<W, M, A> rhs) =>\n        lhs.Bind(_ => rhs);\n    \n    /// <summary>\n    /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n    /// as the semicolon) in C#.\n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the second action</returns>\n    public static WriterT<W, M, A> operator >> (WriterT<W, M, A> lhs, K<WriterT<W, M>, A> rhs) =>\n        lhs.Bind(_ => rhs);\n\n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static WriterT<W, M, A> operator >> (WriterT<W, M, A> lhs, WriterT<W, M, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static WriterT<W, M, A> operator >> (WriterT<W, M, A> lhs, K<WriterT<W, M>, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    public static implicit operator WriterT<W, M, A>(Pure<A> ma) =>\n        Pure(ma.Value);\n    \n    public static implicit operator WriterT<W, M, A>(IO<A> ma) =>\n        LiftIO(ma);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Run the monad\n    //\n\n    /// <summary>\n    /// Run the writer \n    /// </summary>\n    /// <returns>Bound monad</returns>\n    public K<M, (A Value, W Output)> Run() =>\n        runWriter(W.Empty);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Monads/Trampoline/Trampoline.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class Trampoline\n{\n    public static Trampoline<A> Pure<A>(A value) =>\n        new Trampoline<A>.PureStep(value);\n    \n    public static Trampoline<A> More<A>(Func<Trampoline<A>> value) =>\n        new Trampoline<A>.MoreStep(value);\n\n    public static Trampoline<B> Bind<A, B>(Trampoline<A> ma, Func<A, Trampoline<B>> f) =>\n        ma switch\n        {\n            Trampoline<A>.BindStep self => self.Fix(f),\n            _                       => new Trampoline<B>.BindStep<A>(ma, f)\n        };\n}\n\n/// <summary>\n/// \n/// </summary>\n/// <remarks>\n/// Based on: https://blog.higher-order.com/assets/trampolines.pdf\n/// </remarks>\n/// <typeparam name=\"A\"></typeparam>\npublic abstract record Trampoline<A>\n{\n    public A Run()\n    {\n        var f = () => this;\n        while (true)\n        {\n            switch (f().Resume())\n            {\n                case Either<Func<Trampoline<A>>, A>.Left (var nf):\n                    f = nf;\n                    break;\n\n                case Either<Func<Trampoline<A>>, A>.Right (var value):\n                    return value;\n            }\n        }\n    }\n    \n    public Trampoline<B> Bind<B>(Func<A, Trampoline<B>> f) =>\n        Trampoline.Bind(this, f);\n    \n    public Trampoline<B> Map<B>(Func<A, B> f) =>\n        Trampoline.Bind(this, x => Trampoline.Pure(f(x)));\n    \n    public Trampoline<B> Select<B>(Func<A, B> f) =>\n        Trampoline.Bind(this, x => Trampoline.Pure(f(x)));\n\n    public Trampoline<C> SelectMany<B, C>(Func<A, Trampoline<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    protected abstract Either<Func<Trampoline<A>>, A> Resume();\n\n    internal record PureStep(A Result) : Trampoline<A>\n    {\n        protected override Either<Func<Trampoline<A>>, A> Resume() =>\n            Result;\n    }\n\n    internal record MoreStep(Func<Trampoline<A>> Next) : Trampoline<A>\n    {\n        protected override Either<Func<Trampoline<A>>, A> Resume() =>\n            Next;\n    }\n\n    internal abstract record BindStep : Trampoline<A>\n    {\n        public abstract Trampoline<B> Fix<B>(Func<A, Trampoline<B>> f);\n    }\n\n    internal record BindStep<X>(Trampoline<X> Sub, Func<X, Trampoline<A>> Next) : BindStep\n    {\n        public override Trampoline<B> Fix<B>(Func<A, Trampoline<B>> f) =>\n            new Trampoline<B>.BindStep<X>(Sub, x => Trampoline.Bind(Next(x), f));\n\n        protected override Either<Func<Trampoline<A>>, A> Resume() =>\n            Sub switch\n            {\n                Trampoline<X>.PureStep (var x) =>\n                    Next(x).Resume(),\n\n                Trampoline<X>.MoreStep (var f) =>\n                    Left(() => Trampoline.Bind(f(), Next)),\n\n                Trampoline<X>.BindStep bind =>\n                    bind.Resume() switch\n                    {\n                        Either<Func<Trampoline<X>>, X>.Right (var x) => Left(() => Next(x)),\n                        Either<Func<Trampoline<X>>, X>.Left (var f)  => Left(() => Trampoline.Bind(f(), Next)),\n                        _                                            => throw new NotSupportedException()\n                    },\n\n                _ => throw new NotSupportedException()\n            };\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Number.cs",
    "content": "using System.Numerics;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// `Num〈A〉` trait for `INumber〈A〉` \n/// </summary>\n/// <typeparam name=\"A\"></typeparam>\npublic class Number<A> : Num<A>\n    where A : INumber<A>\n{\n    public static int GetHashCode(A x) =>\n        x.GetHashCode();\n\n    public static bool Equals(A x, A y) =>\n        x == y;\n\n    public static int Compare(A x, A y) =>\n        x.CompareTo(y);\n\n    public static A Add(A x, A y) =>\n        x + y;\n\n    public static A Subtract(A x, A y) =>\n        x - y;\n\n    public static A Multiply(A x, A y) =>\n        x * y;\n\n    public static A Negate(A x) =>\n        -x;\n\n    public static A Abs(A x) =>\n        x < A.Zero ? -x : x;\n\n    public static A Signum(A x) =>\n        x < A.Zero\n            ? -A.One\n            : x > A.Zero\n                ? A.One\n                : A.Zero;\n\n    public static A FromInteger(int x) =>\n        A.CreateChecked(x);\n\n    public static A FromDecimal(decimal x) => \n        A.CreateChecked(x);\n\n    public static A FromFloat(float x) => \n        A.CreateChecked(x);\n\n    public static A FromDouble(double x) => \n        A.CreateChecked(x);\n\n    public static A Divide(A x, A y) =>\n        x / y;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Obsolete and Deprecated/Change.cs",
    "content": "﻿namespace LanguageExt;\n\ninternal class Change\n{\n    public const string UseCollectionIntialiser =\n        \"Use collection intialiser instead.  So, instead of: (x, y, z), you should now call [x, y, z]\";\n\n    public const string UseCollectionIntialiserSeq =\n        \"Use collection intialiser instead.  So, instead of: Seq1(x), you should now call [x] - alternatively use Seq(x) as Seq1(x) has been deprecated.\";\n\n    public const string UseToArrayInstead =\n        \"Use ToArray() instead\";\n\n    public const string UseToListInstead =\n        \"Use ToList() instead\";\n\n    public const string UseToSeqInstead =\n        \"Use ToList() instead\";\n}\n"
  },
  {
    "path": "LanguageExt.Core/Obsolete and Deprecated/Fin.Prelude.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Fin constructor\n    /// Constructs a Fin in a success state\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"value\">Success value</param>\n    /// <returns>A new Fin instance</returns>\n    [Pure]\n    [Obsolete(\"FinSucc has been deprecated in favour of `Fin.Succ` or `Prelude.Pure`\")]\n    public static Fin<A> FinSucc<A>(A value) =>\n        new Fin<A>.Succ(value);\n\n    /// <summary>\n    /// Fin constructor\n    /// Constructs a Fin in a failure state\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"value\">Failure value</param>\n    /// <returns>A new Fin instance</returns>\n    [Pure]\n    [Obsolete(\"FinFail has been deprecated in favour of `Fin.Fail` or `Prelude.Fail`\")]\n    public static Fin<A> FinFail<A>(Error value) =>\n        new Fin<A>.Fail(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Opt.cs",
    "content": "using System.Runtime.CompilerServices;\n\nnamespace LanguageExt\n{\n    internal static class Opt\n    {\n        internal const MethodImplOptions Default = MethodImplOptions.AggressiveInlining;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Currying and Partial Application/Prelude.Curry.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Curry the function 'f' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, R>> curry<T1, T2, R>(Func<T1, T2, R> f) =>\n        a => b => f(a, b);\n\n    /// <summary>\n    /// Curry the function 'f' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)(c)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, Func<T3, R>>> curry<T1, T2, T3, R>(Func<T1, T2, T3, R> f) =>\n        a => b => c => f(a, b, c);\n\n    /// <summary>\n    /// Curry the function 'f' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)(c)(d)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, Func<T3, Func<T4, R>>>> curry<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> f) =>\n        a => b => c => d => f(a, b, c, d);\n\n    /// <summary>\n    /// Curry the function 'f' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)(c)(d)(e)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, R>>>>> curry<T1, T2, T3, T4, T5, R>(Func<T1, T2, T3, T4, T5, R> f) =>\n        a => b => c => d => e => f(a, b, c, d, e);\n\n    /// <summary>\n    /// Curry the function 'func' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)(c)(d)(e)(f)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, R>>>>>> curry<T1, T2, T3, T4, T5, T6, R>(Func<T1, T2, T3, T4, T5, T6, R> func) =>\n        a => b => c => d => e => f => func(a, b, c, d, e, f);\n\n\n    /// <summary>\n    /// Curry the function 'func' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)(c)(d)(e)(f)(g)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, Func<T7, R>>>>>>> curry<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> func) =>\n        a => b => c => d => e => f => g => func(a, b, c, d, e, f, g);\n\n\n    /// <summary>\n    /// Curry the function 'func' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)(c)(d)(e)(f)(g)(h)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, Func<T7, Func<T8, R>>>>>>>> curry<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> func) =>\n        a => b => c => d => e => f => g => h => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Curry the function 'func' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)(c)(d)(e)(f)(g)(h)(i)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, Func<T7, Func<T8, Func<T9, R>>>>>>>>> curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func) =>\n        a => b => c => d => e => f => g => h => i => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Curry the function 'func' provided.\n    /// You can then partially apply by calling: \n    /// \n    ///     var curried = curry(f);\n    ///     var r = curried(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)\n    /// \n    /// </summary>\n    [Pure]\n    public static Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, Func<T7, Func<T8, Func<T9, Func<T10, R>>>>>>>>>> curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func) =>\n        a => b => c => d => e => f => g => h => i => j => func(a, b, c, d, e, f, g, h, i, j);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Currying and Partial Application/Prelude.PartialApplication.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Left partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T1, R> lpar<T1, T2, R>(Func<T1, T2, R> func, T2 b) =>\n        a => func(a, b);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, R> par<T1, T2, R>(Func<T1, T2, R> func, T1 a) =>\n        b => func(a, b);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T3, R> par<T1, T2, T3, R>(Func<T1, T2, T3, R> func, T1 a, T2 b) =>\n        c => func(a, b, c);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, T3, R> par<T1, T2, T3, R>(Func<T1, T2, T3, R> func, T1 a) =>\n        (b, c) => func(a, b, c);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T4, R> par<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> func, T1 a, T2 b, T3 c) =>\n        d => func(a, b, c, d);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T3, T4, R> par<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> func, T1 a, T2 b) =>\n        (c, d) => func(a, b, c, d);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, T3, T4, R> par<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> func, T1 a) =>\n        (b, c, d) => func(a, b, c, d);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T5, R> par<T1, T2, T3, T4, T5, R>(Func<T1, T2, T3, T4, T5, R> func, T1 a, T2 b, T3 c, T4 d) =>\n        e => func(a, b, c, d, e);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T4, T5, R> par<T1, T2, T3, T4, T5, R>(Func<T1, T2, T3, T4, T5, R> func, T1 a, T2 b, T3 c) =>\n        (d, e) => func(a, b, c, d, e);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T3, T4, T5, R> par<T1, T2, T3, T4, T5, R>(Func<T1, T2, T3, T4, T5, R> func, T1 a, T2 b) =>\n        (c, d, e) => func(a, b, c, d, e);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, T3, T4, T5, R> par<T1, T2, T3, T4, T5, R>(Func<T1, T2, T3, T4, T5, R> func, T1 a) =>\n        (b, c, d, e) => func(a, b, c, d, e);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T6, R> par<T1, T2, T3, T4, T5, T6, R>(Func<T1, T2, T3, T4, T5, T6, R> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        f => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T5, T6, R> par<T1, T2, T3, T4, T5, T6, R>(Func<T1, T2, T3, T4, T5, T6, R> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f) => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T4, T5, T6, R> par<T1, T2, T3, T4, T5, T6, R>(Func<T1, T2, T3, T4, T5, T6, R> func, T1 a, T2 b, T3 c) =>\n        (d, e, f) => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T3, T4, T5, T6, R> par<T1, T2, T3, T4, T5, T6, R>(Func<T1, T2, T3, T4, T5, T6, R> func, T1 a, T2 b) =>\n        (c, d, e, f) => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, T3, T4, T5, T6, R> par<T1, T2, T3, T4, T5, T6, R>(Func<T1, T2, T3, T4, T5, T6, R> func, T1 a) =>\n        (b, c, d, e, f) => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T7, R> par<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) =>\n        g => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T6, T7, R> par<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        (f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T5, T6, T7, R> par<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T4, T5, T6, T7, R> par<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> func, T1 a, T2 b, T3 c) =>\n        (d, e, f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T3, T4, T5, T6, T7, R> par<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> func, T1 a, T2 b) =>\n        (c, d, e, f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, T3, T4, T5, T6, T7, R> par<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> func, T1 a) =>\n        (b, c, d, e, f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, T3, T4, T5, T6, T7, T8, R> par<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> func, T1 a) =>\n        (b, c, d, e, f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T3, T4, T5, T6, T7, T8, R> par<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> func, T1 a, T2 b) =>\n        (c, d, e, f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T4, T5, T6, T7, T8, R> par<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> func, T1 a, T2 b, T3 c) =>\n        (d, e, f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T5, T6, T7, T8, R> par<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T6, T7, T8, R> par<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        (f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T7, T8, R> par<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) =>\n        (g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T8, R> par<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g) =>\n        h => func(a, b, c, d, e, f, g, h);\n\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, T3, T4, T5, T6, T7, T8, T9, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func, T1 a) =>\n        (b, c, d, e, f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T3, T4, T5, T6, T7, T8, T9, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func, T1 a, T2 b) =>\n        (c, d, e, f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T4, T5, T6, T7, T8, T9, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func, T1 a, T2 b, T3 c) =>\n        (d, e, f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T5, T6, T7, T8, T9, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T6, T7, T8, T9, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        (f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T7, T8, T9, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) =>\n        (g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T8, T9, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g) =>\n        (h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T9, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g, T8 h) =>\n        i => func(a, b, c, d, e, f, g, h, i);\n\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T2, T3, T4, T5, T6, T7, T8, T9, T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a) =>\n        (b, c, d, e, f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T3, T4, T5, T6, T7, T8, T9, T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a, T2 b) =>\n        (c, d, e, f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T4, T5, T6, T7, T8, T9, T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a, T2 b, T3 c) =>\n        (d, e, f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T5, T6, T7, T8, T9, T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T6, T7, T8, T9, T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        (f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T7, T8, T9, T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) =>\n        (g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T8, T9, T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g) =>\n        (h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T9, T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g, T8 h) =>\n        (i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Func<T10, R> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g, T8 h, T9 i) =>\n        j => func(a, b, c, d, e, f, g, h, i, j);\n\n\n\n\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2> par<T1, T2>(Action<T1, T2> func, T1 a) =>\n        b => func(a, b);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T3> par<T1, T2, T3>(Action<T1, T2, T3> func, T1 a, T2 b) =>\n        c => func(a, b, c);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2, T3> par<T1, T2, T3>(Action<T1, T2, T3> func, T1 a) =>\n        (b, c) => func(a, b, c);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T4> par<T1, T2, T3, T4>(Action<T1, T2, T3, T4> func, T1 a, T2 b, T3 c) =>\n        d => func(a, b, c, d);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T3, T4> par<T1, T2, T3, T4>(Action<T1, T2, T3, T4> func, T1 a, T2 b) =>\n        (c, d) => func(a, b, c, d);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2, T3, T4> par<T1, T2, T3, T4>(Action<T1, T2, T3, T4> func, T1 a) =>\n        (b, c, d) => func(a, b, c, d);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T5> par<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> func, T1 a, T2 b, T3 c, T4 d) =>\n        e => func(a, b, c, d, e);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T4, T5> par<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> func, T1 a, T2 b, T3 c) =>\n        (d, e) => func(a, b, c, d, e);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T3, T4, T5> par<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> func, T1 a, T2 b) =>\n        (c, d, e) => func(a, b, c, d, e);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2, T3, T4, T5> par<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> func, T1 a) =>\n        (b, c, d, e) => func(a, b, c, d, e);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T6> par<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        f => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T5, T6> par<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f) => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T4, T5, T6> par<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> func, T1 a, T2 b, T3 c) =>\n        (d, e, f) => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T3, T4, T5, T6> par<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> func, T1 a, T2 b) =>\n        (c, d, e, f) => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2, T3, T4, T5, T6> par<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> func, T1 a) =>\n        (b, c, d, e, f) => func(a, b, c, d, e, f);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T7> par<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) =>\n        g => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T6, T7> par<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        (f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T5, T6, T7> par<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T4, T5, T6, T7> par<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> func, T1 a, T2 b, T3 c) =>\n        (d, e, f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T3, T4, T5, T6, T7> par<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> func, T1 a, T2 b) =>\n        (c, d, e, f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2, T3, T4, T5, T6, T7> par<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> func, T1 a) =>\n        (b, c, d, e, f, g) => func(a, b, c, d, e, f, g);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2, T3, T4, T5, T6, T7, T8> par<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> func, T1 a) =>\n        (b, c, d, e, f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T3, T4, T5, T6, T7, T8> par<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> func, T1 a, T2 b) =>\n        (c, d, e, f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T4, T5, T6, T7, T8> par<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> func, T1 a, T2 b, T3 c) =>\n        (d, e, f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T5, T6, T7, T8> par<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T6, T7, T8> par<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        (f, g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T7, T8> par<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) =>\n        (g, h) => func(a, b, c, d, e, f, g, h);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T8> par<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g) =>\n        h => func(a, b, c, d, e, f, g, h);\n\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2, T3, T4, T5, T6, T7, T8, T9> par<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> func, T1 a) =>\n        (b, c, d, e, f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T3, T4, T5, T6, T7, T8, T9> par<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> func, T1 a, T2 b) =>\n        (c, d, e, f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T4, T5, T6, T7, T8, T9> par<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> func, T1 a, T2 b, T3 c) =>\n        (d, e, f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T5, T6, T7, T8, T9> par<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T6, T7, T8, T9> par<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        (f, g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T7, T8, T9> par<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) =>\n        (g, h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T8, T9> par<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g) =>\n        (h, i) => func(a, b, c, d, e, f, g, h, i);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T9> par<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g, T8 h) =>\n        i => func(a, b, c, d, e, f, g, h, i);\n\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T2, T3, T4, T5, T6, T7, T8, T9, T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a) =>\n        (b, c, d, e, f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T3, T4, T5, T6, T7, T8, T9, T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a, T2 b) =>\n        (c, d, e, f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T4, T5, T6, T7, T8, T9, T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a, T2 b, T3 c) =>\n        (d, e, f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T5, T6, T7, T8, T9, T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a, T2 b, T3 c, T4 d) =>\n        (e, f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T6, T7, T8, T9, T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a, T2 b, T3 c, T4 d, T5 e) =>\n        (f, g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T7, T8, T9, T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) =>\n        (g, h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T8, T9, T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g) =>\n        (h, i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T9, T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g, T8 h) =>\n        (i, j) => func(a, b, c, d, e, f, g, h, i, j);\n\n    /// <summary>\n    /// Partially apply \n    /// </summary>\n    [Pure]\n    public static Action<T10> par<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> func, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g, T8 h, T9 i) =>\n        j => func(a, b, c, d, e, f, g, h, i, j);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Currying and Partial Application/Prelude.Uncurry.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, R> Uncurry<T1, T2, R>(this Func<T1, Func<T2, R>> function) =>\n        (arg1, arg2) => function(arg1)(arg2);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, R> Uncurry<T1, T2, T3, R>(this Func<T1, Func<T2, Func<T3, R>>> function) =>\n        (arg1, arg2, arg3) => function(arg1)(arg2)(arg3);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, R> Uncurry<T1, T2, T3, T4, R>(this Func<T1, Func<T2, Func<T3, Func<T4, R>>>> function) =>\n        (arg1, arg2, arg3, arg4) => function(arg1)(arg2)(arg3)(arg4);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, R> Uncurry<T1, T2, T3, T4, T5, R>(this Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, R>>>>> function) =>\n        (arg1, arg2, arg3, arg4, arg5) => function(arg1)(arg2)(arg3)(arg4)(arg5);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, R> Uncurry<T1, T2, T3, T4, T5, T6, R>(this Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, R>>>>>> function) =>\n        (arg1, arg2, arg3, arg4, arg5, arg6) => function(arg1)(arg2)(arg3)(arg4)(arg5)(arg6);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, R> Uncurry<T1, T2, T3, T4, T5, T6, T7, R>(this Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, Func<T7, R>>>>>>> function) =>\n        (arg1, arg2, arg3, arg4, arg5, arg6, arg7) => function(arg1)(arg2)(arg3)(arg4)(arg5)(arg6)(arg7);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, R> Uncurry<T1, T2, T3, T4, T5, T6, T7, T8, R>(this Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, Func<T7, Func<T8, R>>>>>>>> function) =>\n        (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => function(arg1)(arg2)(arg3)(arg4)(arg5)(arg6)(arg7)(arg8);\n\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, R> uncurry<T1, T2, R>(Func<T1, Func<T2, R>> function) =>\n        (arg1, arg2) => function(arg1)(arg2);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, R> uncurry<T1, T2, T3, R>(Func<T1, Func<T2, Func<T3, R>>> function) =>\n        (arg1, arg2, arg3) => function(arg1)(arg2)(arg3);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, R> uncurry<T1, T2, T3, T4, R>(Func<T1, Func<T2, Func<T3, Func<T4, R>>>> function) =>\n        (arg1, arg2, arg3, arg4) => function(arg1)(arg2)(arg3)(arg4);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, R> uncurry<T1, T2, T3, T4, T5, R>(Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, R>>>>> function) =>\n        (arg1, arg2, arg3, arg4, arg5) => function(arg1)(arg2)(arg3)(arg4)(arg5);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, R> uncurry<T1, T2, T3, T4, T5, T6, R>(Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, R>>>>>> function) =>\n        (arg1, arg2, arg3, arg4, arg5, arg6) => function(arg1)(arg2)(arg3)(arg4)(arg5)(arg6);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, R> uncurry<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, Func<T7, R>>>>>>> function) =>\n        (arg1, arg2, arg3, arg4, arg5, arg6, arg7) => function(arg1)(arg2)(arg3)(arg4)(arg5)(arg6)(arg7);\n\n    /// <summary>\n    /// Transforms a curried function into a function that takes multiple arguments\n    /// </summary>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, R> uncurry<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, Func<T2, Func<T3, Func<T4, Func<T5, Func<T6, Func<T7, Func<T8, R>>>>>>>> function) =>\n        (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => function(arg1)(arg2)(arg3)(arg4)(arg5)(arg6)(arg7)(arg8);\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Function argument flipping/Prelude.Flip.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Reverse the order of the arguments to a curried function\n    /// </summary>\n    [Pure]\n    public static Func<B, Func<A, R>> flip<A, B, R>(Func<A, Func<B, R>> f) =>\n        b => a => f(a)(b);\n\n    /// <summary>\n    /// Reverse the order of the arguments to a curried function\n    /// </summary>\n    [Pure]\n    public static Func<C, Func<B, Func<A, R>>> flip<A, B, C, R>(Func<A, Func<B, Func<C, R>>> f) =>\n        c => b => a => f(a)(b)(c);\n\n    /// <summary>\n    /// Reverse the order of the arguments to a function\n    /// </summary>\n    [Pure]\n    public static Func<B, A, R> flip<A, B, R>(Func<A, B, R> f) =>\n        (b, a) => f(a, b);\n\n    /// <summary>\n    /// Reverse the order of the arguments to a function\n    /// </summary>\n    [Pure]\n    public static Func<C, B, A, R> flip<A, B, C, R>(Func<A, B, C, R> f) =>\n        (c, b, a) => f(a, b, c);\n\n    /// <summary>\n    /// Reverse the order of the arguments to a curried function\n    /// </summary>\n    [Pure]\n    public static Func<B, Func<A, R>> Flip<A, B, R>(this Func<A, Func<B, R>> f) =>\n        b => a => f(a)(b);\n\n    /// <summary>\n    /// Reverse the order of the arguments to a curried function\n    /// </summary>\n    [Pure]\n    public static Func<C, Func<B, Func<A, R>>> Flip<A, B, C, R>(this Func<A, Func<B, Func<C, R>>> f) =>\n        c => b => a => f(a)(b)(c);\n\n    /// <summary>\n    /// Reverse the order of the arguments to a function\n    /// </summary>\n    [Pure]\n    public static Func<B, A, R> Flip<A, B, R>(this Func<A, B, R> f) =>\n        (b, a) => f(a, b);\n\n    /// <summary>\n    /// Reverse the order of the arguments to a function\n    /// </summary>\n    [Pure]\n    public static Func<C, B, A, R> Flip<A, B, C, R>(this Func<A, B, C, R> f) =>\n        (c, b, a) => f(a, b, c);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Hash code functions/Prelude.Hash.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Calculate a hash-code for an enumerable\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<A>(IEnumerable<A> xs) =>\n        FNV32.Hash<HashableDefault<A>, A>(xs);\n\n    /// <summary>\n    /// Calculate a hash-code for an enumerable by using the \n    /// Hashable class-instance to calculate each item's hash\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<HashA, A>(IEnumerable<A> xs) where HashA : Hashable<A> =>\n        FNV32.Hash<HashA, A>(xs);\n\n    //\n    //  The following overloads are to avoid boxing when using the \n    //  hash function, perhaps as a first-class function for a map\n    //\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<A>(Arr<A> xs) =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<K, V>(HashMap<K, V> xs) =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<EqK, K, V>(HashMap<EqK, K, V> xs) where EqK : Eq<K> =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<A>(HashSet<A> xs) =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<EqA, A>(HashSet<EqA, A> xs) where EqA : Eq<A> =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<A>(Lst<A> xs) =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<K, V>(Map<K, V> xs) =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<OrdK, K, V>(Map<OrdK, K, V> xs) where OrdK : Ord<K> =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<A>(Que<A> xs) =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<A>(Seq<A> xs) =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<A>(Set<A> xs) =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<OrdA, A>(Set<OrdA, A> xs) where OrdA : Ord<A> =>\n        xs.GetHashCode();\n\n    /// <summary>\n    /// Calculate a hash-code for the collection provided\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int hash<A>(Stck<A> xs) =>\n        xs.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Lambda function inference/Prelude.Func.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Linq.Expressions;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<R> fun<R>(Func<R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, R> fun<T1, R>(Func<T1, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, R> fun<T1, T2, R>(Func<T1, T2, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, R> fun<T1, T2, T3, R>(Func<T1, T2, T3, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, R> fun<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, R> fun<T1, T2, T3, T4, T5, R>(Func<T1, T2, T3, T4, T5, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, R> fun<T1, T2, T3, T4, T5, T6, R>(Func<T1, T2, T3, T4, T5, T6, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, R> fun<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> f) => f;\n\n    /// <summary>\n    /// Func type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈int,int,int〉 add = (int x, int y) => x + y;\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var add = fun((int x, int y) => x + y);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>The same func you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> fun<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> f) => f;\n\n    /// <summary>\n    /// Action type inference helper and converts it to a Func that returns a Unit instead of void\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string,Unit〉 putStr = (string x) => { Console.WriteLine(x); return unit; }\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = fun((string x) => Console.WriteLine(x) );\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Func that returns a Unit</returns>\n    [Pure]\n    public static Func<Unit> fun(Action f) => () => { f(); return unit; };\n\n    /// <summary>\n    /// Action type inference helper and converts it to a Func that returns a Unit instead of void\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string,Unit〉 putStr = (string x) => { Console.WriteLine(x); return unit; }\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = fun((string x) => Console.WriteLine(x) );\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Func that returns a Unit</returns>\n    [Pure]\n    public static Func<T1, Unit> fun<T1>(Action<T1> f) => (a1) => { f(a1); return unit; };\n\n    /// <summary>\n    /// Action type inference helper and converts it to a Func that returns a Unit instead of void\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string,Unit〉 putStr = (string x) => { Console.WriteLine(x); return unit; }\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = fun((string x) => Console.WriteLine(x) );\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Func that returns a Unit</returns>\n    [Pure]\n    public static Func<T1, T2, Unit> fun<T1, T2>(Action<T1, T2> f) => (a1, a2) => { f(a1, a2); return unit; };\n\n    /// <summary>\n    /// Action type inference helper and converts it to a Func that returns a Unit instead of void\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string,Unit〉 putStr = (string x) => { Console.WriteLine(x); return unit; }\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = fun((string x) => Console.WriteLine(x) );\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Func that returns a Unit</returns>\n    [Pure]\n    public static Func<T1, T2, T3, Unit> fun<T1, T2, T3>(Action<T1, T2, T3> f) => (a1, a2, a3) => { f(a1, a2, a3); return unit; };\n\n    /// <summary>\n    /// Action type inference helper and converts it to a Func that returns a Unit instead of void\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string,Unit〉 putStr = (string x) => { Console.WriteLine(x); return unit; }\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = fun((string x) => Console.WriteLine(x) );\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Func that returns a Unit</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, Unit> fun<T1, T2, T3, T4>(Action<T1, T2, T3, T4> f) => (a1, a2, a3, a4) => { f(a1, a2, a3, a4); return unit; };\n\n    /// <summary>\n    /// Action type inference helper and converts it to a Func that returns a Unit instead of void\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string,Unit〉 putStr = (string x) => { Console.WriteLine(x); return unit; }\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = fun((string x) => Console.WriteLine(x) );\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Func that returns a Unit</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, Unit> fun<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> f) => (a1, a2, a3, a4, a5) => { f(a1, a2, a3, a4, a5); return unit; };\n\n    /// <summary>\n    /// Action type inference helper and converts it to a Func that returns a Unit instead of void\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string,Unit〉 putStr = (string x) => { Console.WriteLine(x); return unit; }\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = fun((string x) => Console.WriteLine(x) );\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Func that returns a Unit</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, Unit> fun<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> f) => (a1, a2, a3, a4, a5, a6) => { f(a1, a2, a3, a4, a5, a6); return unit; };\n\n    /// <summary>\n    /// Action type inference helper and converts it to a Func that returns a Unit instead of void\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string,Unit〉 putStr = (string x) => { Console.WriteLine(x); return unit; }\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = fun((string x) => Console.WriteLine(x) );\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Func that returns a Unit</returns>\n    [Pure]\n    public static Func<T1, T2, T3, T4, T5, T6, T7, Unit> fun<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> f) => (a1, a2, a3, a4, a5, a6, a7) => { f(a1, a2, a3, a4, a5, a6, a7); return unit; };\n\n    /// <summary>\n    /// Action type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Action〈string〉 putStr = (string x) => Console.WriteLine(x);\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = act((string x) => Console.WriteLine(x));\n    /// \n    /// </summary>\n    /// <param name=\"f\">Action to infer</param>\n    /// <returns>The same Action you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Action act(Action f) => f;\n\n    /// <summary>\n    /// Action type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Action〈string〉 putStr = (string x) => Console.WriteLine(x);\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = act((string x) => Console.WriteLine(x));\n    /// \n    /// </summary>\n    /// <param name=\"f\">Action to infer</param>\n    /// <returns>The same Action you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Action<T1> act<T1>(Action<T1> f) => f;\n\n    /// <summary>\n    /// Action type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Action〈string〉 putStr = (string x) => Console.WriteLine(x);\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = act((string x) => Console.WriteLine(x));\n    /// \n    /// </summary>\n    /// <param name=\"f\">Action to infer</param>\n    /// <returns>The same Action you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Action<T1, T2> act<T1, T2>(Action<T1, T2> f) => f;\n\n    /// <summary>\n    /// Action type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Action〈string〉 putStr = (string x) => Console.WriteLine(x);\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = act((string x) => Console.WriteLine(x));\n    /// \n    /// </summary>\n    /// <param name=\"f\">Action to infer</param>\n    /// <returns>The same Action you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Action<T1, T2, T3> act<T1, T2, T3>(Action<T1, T2, T3> f) => f;\n\n    /// <summary>\n    /// Action type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Action〈string〉 putStr = (string x) => Console.WriteLine(x);\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = act((string x) => Console.WriteLine(x));\n    /// \n    /// </summary>\n    /// <param name=\"f\">Action to infer</param>\n    /// <returns>The same Action you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Action<T1, T2, T3, T4> act<T1, T2, T3, T4>(Action<T1, T2, T3, T4> f) => f;\n\n    /// <summary>\n    /// Action type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Action〈string〉 putStr = (string x) => Console.WriteLine(x);\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = act((string x) => Console.WriteLine(x));\n    /// \n    /// </summary>\n    /// <param name=\"f\">Action to infer</param>\n    /// <returns>The same Action you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Action<T1, T2, T3, T4, T5> act<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> f) => f;\n\n    /// <summary>\n    /// Action type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Action〈string〉 putStr = (string x) => Console.WriteLine(x);\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = act((string x) => Console.WriteLine(x));\n    /// \n    /// </summary>\n    /// <param name=\"f\">Action to infer</param>\n    /// <returns>The same Action you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Action<T1, T2, T3, T4, T5, T6> act<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> f) => f;\n\n    /// <summary>\n    /// Action type inference helper\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Action〈string〉 putStr = (string x) => Console.WriteLine(x);\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var putStr = act((string x) => Console.WriteLine(x));\n    /// \n    /// </summary>\n    /// <param name=\"f\">Action to infer</param>\n    /// <returns>The same Action you gave it, but allows the type system to work out what f is</returns>\n    [Pure]\n    public static Action<T1, T2, T3, T4, T5, T6, T7> act<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> f) => f;\n\n    /// <summary>\n    /// Func type inference helper; converts it to an Action by dropping the return value\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string, string〉 thereIs = ...\n    /// \n    ///     Action〈string,Unit〉 thereIsNoReturn = (string x) => { thereis(x); };\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var thereIsNoReturn = act(thereIs);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Action that is the same as the Func passed in, but with the return type dropped</returns>\n    [Pure]\n    public static Action act<R>(Func<R> f) => () => f();\n\n    /// <summary>\n    /// Func type inference helper; converts it to an Action by dropping the return value\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string, string〉 thereIs = ...\n    /// \n    ///     Action〈string,Unit〉 thereIsNoReturn = (string x) => { thereis(x); };\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var thereIsNoReturn = act(thereIs);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Action that is the same as the Func passed in, but with the return type dropped</returns>\n    [Pure]\n    public static Action<T1> act<T1, R>(Func<T1, R> f) => a1 => f(a1);\n\n    /// <summary>\n    /// Func type inference helper; converts it to an Action by dropping the return value\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string, string〉 thereIs = ...\n    /// \n    ///     Action〈string,Unit〉 thereIsNoReturn = (string x) => { thereis(x); };\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var thereIsNoReturn = act(thereIs);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Action that is the same as the Func passed in, but with the return type dropped</returns>\n    [Pure]\n    public static Action<T1, T2> act<T1, T2, R>(Func<T1, T2, R> f) => (a1, a2) => f(a1, a2);\n\n    /// <summary>\n    /// Func type inference helper; converts it to an Action by dropping the return value\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string, string〉 thereIs = ...\n    /// \n    ///     Action〈string,Unit〉 thereIsNoReturn = (string x) => { thereis(x); };\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var thereIsNoReturn = act(thereIs);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Action that is the same as the Func passed in, but with the return type dropped</returns>\n    [Pure]\n    public static Action<T1, T2, T3> act<T1, T2, T3, R>(Func<T1, T2, T3, R> f) => (a1, a2, a3) => f(a1, a2, a3);\n\n    /// <summary>\n    /// Func type inference helper; converts it to an Action by dropping the return value\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string, string〉 thereIs = ...\n    /// \n    ///     Action〈string,Unit〉 thereIsNoReturn = (string x) => { thereis(x); };\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var thereIsNoReturn = act(thereIs);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Action that is the same as the Func passed in, but with the return type dropped</returns>\n    [Pure]\n    public static Action<T1, T2, T3, T4> act<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> f) => (a1, a2, a3, a4) => f(a1, a2, a3, a4);\n\n    /// <summary>\n    /// Func type inference helper; converts it to an Action by dropping the return value\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string, string〉 thereIs = ...\n    /// \n    ///     Action〈string,Unit〉 thereIsNoReturn = (string x) => { thereis(x); };\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var thereIsNoReturn = act(thereIs);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Action that is the same as the Func passed in, but with the return type dropped</returns>\n    [Pure]\n    public static Action<T1, T2, T3, T4, T5> act<T1, T2, T3, T4, T5, R>(Func<T1, T2, T3, T4, T5, R> f) => (a1, a2, a3, a4, a5) => f(a1, a2, a3, a4, a5);\n\n    /// <summary>\n    /// Func type inference helper; converts it to an Action by dropping the return value\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string, string〉 thereIs = ...\n    /// \n    ///     Action〈string,Unit〉 thereIsNoReturn = (string x) => { thereis(x); };\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var thereIsNoReturn = act(thereIs);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Action that is the same as the Func passed in, but with the return type dropped</returns>\n    [Pure]\n    public static Action<T1, T2, T3, T4, T5, T6> act<T1, T2, T3, T4, T5, T6, R>(Func<T1, T2, T3, T4, T5, T6, R> f) => (a1, a2, a3, a4, a5, a6) => f(a1, a2, a3, a4, a5, a6);\n\n    /// <summary>\n    /// Func type inference helper; converts it to an Action by dropping the return value\n    /// \n    /// Try it with lambdas, instead of doing:\n    /// \n    ///     Func〈string, string〉 thereIs = ...\n    /// \n    ///     Action〈string,Unit〉 thereIsNoReturn = (string x) => { thereis(x); };\n    /// \n    /// You can use this function and do:\n    /// \n    ///     var thereIsNoReturn = act(thereIs);\n    /// \n    /// </summary>\n    /// <param name=\"f\">Function to infer</param>\n    /// <returns>Action that is the same as the Func passed in, but with the return type dropped</returns>\n    [Pure]\n    public static Action<T1, T2, T3, T4, T5, T6, T7> act<T1, T2, T3, T4, T5, T6, T7, R>(Func<T1, T2, T3, T4, T5, T6, T7, R> f) => (a1, a2, a3, a4, a5, a6, a7) => f(a1, a2, a3, a4, a5, a6, a7);\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Func<R>> expr<R>(Expression<Func<R>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Func<T1, R>> expr<T1, R>(Expression<Func<T1, R>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Func<T1, T2, R>> expr<T1, T2, R>(Expression<Func<T1, T2, R>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Func<T1, T2, T3, R>> expr<T1, T2, T3, R>(Expression<Func<T1, T2, T3, R>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Func<T1, T2, T3, T4, R>> expr<T1, T2, T3, T4, R>(Expression<Func<T1, T2, T3, T4, R>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Func<T1, T2, T3, T4, T5, R>> expr<T1, T2, T3, T4, T5, R>(Expression<Func<T1, T2, T3, T4, T5, R>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Func<T1, T2, T3, T4, T5, T6, R>> expr<T1, T2, T3, T4, T5, T6, R>(Expression<Func<T1, T2, T3, T4, T5, T6, R>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Func<T1, T2, T3, T4, T5, T6, T7, R>> expr<T1, T2, T3, T4, T5, T6, T7, R>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, R>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Action> expr(Expression<Action> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Action<T1>> expr<T1>(Expression<Action<T1>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Action<T1, T2>> expr<T1, T2>(Expression<Action<T1, T2>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Action<T1, T2, T3>> expr<T1, T2, T3>(Expression<Action<T1, T2, T3>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Action<T1, T2, T3, T4>> expr<T1, T2, T3, T4>(Expression<Action<T1, T2, T3, T4>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Action<T1, T2, T3, T4, T5>> expr<T1, T2, T3, T4, T5>(Expression<Action<T1, T2, T3, T4, T5>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Action<T1, T2, T3, T4, T5, T6>> expr<T1, T2, T3, T4, T5, T6>(Expression<Action<T1, T2, T3, T4, T5, T6>> f) => f;\n\n    /// <summary>\n    /// Expression inference\n    /// </summary>\n    /// <returns>Same expression passed in, just gives the type system a chance to infer</returns>\n    [Pure]\n    public static Expression<Action<T1, T2, T3, T4, T5, T6, T7>> expr<T1, T2, T3, T4, T5, T6, T7>(Expression<Action<T1, T2, T3, T4, T5, T6, T7>> f) => f;\n\n    /// <summary>\n    /// Function composition\n    /// </summary>\n    /// <returns>b(a(()))</returns>\n    [Pure]\n    public static Func<T2> compose<T1, T2>(Func<T1> a, Func<T1, T2> b) =>\n        () => b(a());\n        \n    /// <summary>\n    /// Function composition\n    /// </summary>\n    /// <returns>b(a(v))</returns>\n    [Pure]\n    public static Func<T1, T3> compose<T1, T2, T3>(Func<T1, T2> a, Func<T2, T3> b) =>\n        v => b(a(v));\n\n    /// <summary>\n    /// Function composition\n    /// </summary>\n    /// <returns>c(b(a(v)))</returns>\n    [Pure]\n    public static Func<T1, T4> compose<T1, T2, T3, T4>(Func<T1, T2> a, Func<T2, T3> b, Func<T3, T4> c) =>\n        v => c(b(a(v)));\n\n    /// <summary>\n    /// Function composition\n    /// </summary>\n    /// <returns>c(b(a(v)))</returns>\n    [Pure]\n    public static Func<T1, T5> compose<T1, T2, T3, T4, T5>(Func<T1, T2> a, Func<T2, T3> b, Func<T3, T4> c, Func<T4, T5> d) =>\n        v => d(c(b(a(v))));\n\n    /// <summary>\n    /// Function composition\n    /// </summary>\n    /// <returns>c(b(a(v)))</returns>\n    [Pure]\n    public static Func<T1, T6> compose<T1, T2, T3, T4, T5, T6>(Func<T1, T2> a, Func<T2, T3> b, Func<T3, T4> c, Func<T4, T5> d, Func<T5, T6> e) =>\n        v => e(d(c(b(a(v)))));\n\n    /// <summary>\n    /// Function composition\n    /// </summary>\n    /// <returns>c(b(a(v)))</returns>\n    [Pure]\n    public static Func<T1, T7> compose<T1, T2, T3, T4, T5, T6, T7>(Func<T1, T2> a, Func<T2, T3> b, Func<T3, T4> c, Func<T4, T5> d, Func<T5, T6> e, Func<T6, T7> f) =>\n        v => f(e(d(c(b(a(v))))));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Prelude.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Identity function\n    /// </summary>\n    [Pure]\n    public static A identity<A>(A x) => \n        x;\n\n    /// <summary>\n    /// Constant function\n    /// Always returns the first argument\n    /// </summary>\n    [Pure]\n    public static Func<B, A> constant<A, B>(A x) =>\n        _ => x;\n\n    /// <summary>\n    /// Constant function\n    /// Always returns the first argument\n    /// </summary>\n    [Pure]\n    public static A constant<A, B>(A x, B _) =>\n        x;\n\n    /// <summary>\n    /// Constant function\n    /// Always returns the first argument\n    /// </summary>\n    [Pure]\n    public static Func<A, A> constantA<A>(A x) =>\n        _ => x;\n\n    /// <summary>\n    /// Constant function\n    /// Always returns the first argument\n    /// </summary>\n    [Pure]\n    public static A constantA<A>(A x, A _) =>\n        x;\n\n    /// <summary>\n    /// Raises a lazy Exception with the message provided\n    /// </summary>\n    /// <param name=\"message\">Exception message</param>\n    /// <returns>Action that when executed throws</returns>\n    public static Action failwith(string message) =>\n        () => throw new Exception(message);\n\n    /// <summary>\n    /// Raises an Exception with the message provided\n    /// </summary>\n    /// <typeparam name=\"R\">The return type of the expression this function is being used in.\n    /// This allows exceptions to be thrown in ternary operators, or LINQ expressions for\n    /// example</typeparam>\n    /// <param name=\"message\">Exception message</param>\n    /// <returns>Throws an exception</returns>\n    public static R failwith<R>(string message) =>\n        throw new Exception(message);\n\n    /// <summary>\n    /// Raises an ApplicationException with the message provided\n    /// </summary>\n    /// <typeparam name=\"R\">The return type of the expression this function is being used in.\n    /// This allows exceptions to be thrown in ternary operators, or LINQ expressions for\n    /// example</typeparam>\n    /// <param name=\"message\">ApplicationException message</param>\n    /// <returns>Throws an ApplicationException</returns>\n    public static R raiseapp<R>(string message) =>\n        throw new ApplicationException(message);\n\n    /// <summary>\n    /// Raise an exception\n    /// </summary>\n    /// <typeparam name=\"R\">The return type of the expression this function is being used in.\n    /// This allows exceptions to be thrown in ternary operators, or LINQ expressions for\n    /// example</typeparam>\n    /// <param name=\"ex\">Exception to throw</param>\n    /// <returns>Throws an exception</returns>\n    public static R raise<R>(Exception ex) =>\n        ex.Rethrow<R>();\n\n    /// <summary>\n    /// Identifies an exception as being of type E\n    /// </summary>\n    /// <typeparam name=\"E\">Type to match</typeparam>\n    /// <param name=\"e\">Exception to test</param>\n    /// <returns>True if e is of type E</returns>\n    [Pure]\n    public static bool exceptionIs<E>(Exception e)\n    {\n        if (e is E) return true;\n        if (e.InnerException == null) return false;\n        return exceptionIs<E>(e.InnerException);\n    }\n\n    /// <summary>\n    /// Not function, for prettifying code and removing the need to \n    /// use the ! operator.\n    /// </summary>\n    /// <param name=\"f\">Predicate function to perform the not operation on</param>\n    /// <returns>!f</returns>\n    public static Func<A, bool> not<A>(Func<A, bool> f) => \n        x => !f(x);\n\n    /// <summary>\n    /// Not function, for prettifying code and removing the need to \n    /// use the ! operator.\n    /// </summary>\n    /// <param name=\"f\">Predicate function to perform the not operation on</param>\n    /// <returns>!f</returns>\n    public static Func<A, B, bool> not<A, B>(Func<A, B, bool> f) => \n        (x, y) => !f(x, y);\n\n    /// <summary>\n    /// Not function, for prettifying code and removing the need to \n    /// use the ! operator.\n    /// </summary>\n    /// <param name=\"f\">Predicate function to perform the not operation on</param>\n    /// <returns>!f</returns>\n    public static Func<A, B, C, bool> not<A, B, C>(Func<A, B, C, bool> f) => \n        (x, y, z) => !f(x, y, z);\n\n    /// <summary>\n    /// Not function, for prettifying code and removing the need to \n    /// use the ! operator.\n    /// </summary>\n    /// <param name=\"value\">Value to perform the not operation on</param>\n    /// <returns>!value</returns>\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool not(bool value) =>\n        !value;\n\n    /// <summary>\n    /// Returns true if the value is equal to this type's\n    /// default value.\n    /// </summary>\n    /// <example>\n    ///     isDefault(0)  // true\n    ///     isDefault(1)  // false\n    /// </example>\n    /// <returns>True if the value is equal to this type's\n    /// default value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    #nullable disable\n    public static bool isDefault<A>(A value) =>\n        Check<A>.IsDefault(value);\n    #nullable restore\n\n    /// <summary>\n    /// Returns true if the value is not equal to this type's\n    /// default value.\n    /// </summary>\n    /// <example>\n    ///     notDefault(0)  // false\n    ///     notDefault(1)  // true\n    /// </example>\n    /// <returns>True if the value is not equal to this type's\n    /// default value</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    #nullable disable\n    public static bool notDefault<A>(A value) =>\n        !Check<A>.IsDefault(value);\n    #nullable restore\n\n    /// <summary>\n    /// Returns true if the value is null, and does so without\n    /// boxing of any value-types.  Value-types will always\n    /// return false.\n    /// </summary>\n    /// <example>\n    ///     int x = 0;\n    ///     string y = null;\n    ///     \n    ///     isnull(x)  // false\n    ///     isnull(y)  // true\n    /// </example>\n    /// <returns>True if the value is null, and does so without\n    /// boxing of any value-types.  Value-types will always\n    /// return false.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    #nullable disable\n    public static bool isnull<A>(A value) =>\n        Check<A>.IsNull(value);\n    #nullable restore\n\n    /// <summary>\n    /// Returns true if the value is not null, and does so without\n    /// boxing of any value-types.  Value-types will always return \n    /// true.\n    /// </summary>\n    /// <example>\n    ///     int x = 0;\n    ///     string y = null;\n    ///     string z = \"Hello\";\n    ///     \n    ///     notnull(x)  // true\n    ///     notnull(y)  // false\n    ///     notnull(z)  // true\n    /// </example>\n    /// <returns>True if the value is null, and does so without\n    /// boxing of any value-types.  Value-types will always\n    /// return false.</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    #nullable disable\n    public static bool notnull<A>(A value) =>\n        !Check<A>.IsNull(value);\n    #nullable restore\n\n    /// <summary>\n    /// Convert a value to string\n    /// </summary>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static string toString<A>(A value) =>\n        value?.ToString() ?? \"\";\n\n    /// <summary>\n    /// Returns true if the string is not null, nor empty, nor a whitespace\n    /// </summary>\n    /// <param name=\"value\">String to test</param>\n    /// <returns>True if the string is null, empty, or whitespace</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool notEmpty(string? value) =>\n        !string.IsNullOrWhiteSpace(value);\n\n    /// <summary>\n    /// Returns true if the string is null, empty, or whitespace\n    /// </summary>\n    /// <param name=\"value\">String to test</param>\n    /// <returns>True if the string is null, empty, or whitespace</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool isEmpty([NotNullWhen(false)] string? value) =>\n        string.IsNullOrWhiteSpace(value);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static (A1, B) mapFirst<A, B, A1>(Func<A, A1> f, (A, B) pair) =>\n        (f(pair.Item1), pair.Item2);\n\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static (A, B1) mapSecond<A, B, B1>(Func<B, B1> f, (A, B) pair) =>\n        (pair.Item1, f(pair.Item2));\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/README.md",
    "content": "`Prelude` is a\n`static partial class`, this type is loaded with functions for constructing the key data types, as well\nas many of the things you'd expect in a functional programming language's prelude.  Note, the `Prelude` type\nextends into many other parts of the source-tree.  It's the same type, but spread all over the code-base.\nAnd so, you may see `Prelude` in other areas of the documentation: it's the same type.\n\nBecause it's so fundamental, you'll want to add this to the top of every code file:\n\n    using static LanguageExt.Prelude;\n\nSo what's in here?  Well, apart from the modules listed below, there's the data-type constructors, for example: \n\n    Option<int> mx = Some(100);\n\n    Seq<int> mx = Seq(1, 2, 3);\n\nAs well as the `camelCase` versions of the fluent-methods attached to each type:\n\n    var items = Seq(1, 2, 3);\n    \n    // Fluent version\n    var sum = items.Fold(0, (s, x) => s + x);\n    \n    // Prelude static function\n    var sum = fold(items, 0, (s, x) => s + x);\n\nThere is _mostly_ a 1-to-1 mapping between the fluent methods and the `Prelude` static functions ... mostly."
  },
  {
    "path": "LanguageExt.Core/Prelude/Random/Prelude.Random.cs",
    "content": "﻿using System;\nusing System.Buffers;\nusing System.Security.Cryptography;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    // There is no documentation that specifies whether the underlying RNG is thread-safe.\n    // It is assumed that the implementation is `RNGCryptoServiceProvider`, which under the\n    // hood calls `CryptGenRandom` from `advapi32` (i.e. a built-in Windows RNG).  There is\n    // no mention of thread-safety issues in any documentation, so we assume this must be \n    // thread-safe.\n    //\n    // Documentation of `CrypGenRandom`\n    //\n    //    https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom\n    //\n    // There is some discussion here:\n    //\n    //    https://stackoverflow.com/questions/46147805/is-cryptgenrandom-thread-safe\n    //\n    static readonly RandomNumberGenerator rnd = RandomNumberGenerator.Create();\n    static readonly int wordTop = BitConverter.IsLittleEndian ? 3 : 0;\n\n    /// <summary>\n    /// Thread-safe cryptographically strong random number generator\n    /// </summary>\n    /// <param name=\"max\">Maximum value to return + 1</param>\n    /// <returns>A non-negative random number, less than the value specified.</returns>\n    public static int random(int max)\n    {\n        var bytes = ArrayPool<byte>.Shared.Rent(4);\n        rnd.GetBytes(bytes);\n        bytes[wordTop] &= 0x7f;\n        var value = BitConverter.ToInt32(bytes, 0) % max;\n        ArrayPool<byte>.Shared.Return(bytes);\n        return value;\n    }\n\n    /// <summary>\n    /// Thread-safe cryptographically strong random base-64 string generator\n    /// </summary>\n    /// <param name=\"bytesCount\">number of bytes generated that are then \n    /// returned Base64 encoded</param>\n    /// <returns>Base64 encoded random string</returns>\n    public static string randomBase64(int bytesCount)\n    {\n        if (bytesCount < 1) throw new ArgumentException($\"The minimum value for {nameof(bytesCount)} is 1\");\n        var bytes = ArrayPool<byte>.Shared.Rent(bytesCount);\n        rnd.GetBytes(bytes);\n        var r = Convert.ToBase64String(bytes);\n        ArrayPool<byte>.Shared.Return(bytes);\n        return r;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Resources/Prelude.Resources.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Common;\nusing LanguageExt.DSL;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `bracketIO`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <param name=\"release\">Action to release the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static K<M, A> use<M, A>(K<M, A> acquire, Action<A> release)\n        where M : MonadUnliftIO<M> =>\n        acquire.MapIO(\n            acq => new IOUse<A, A>(\n                acq,\n                x => IO.lift(\n                    () =>\n                    {\n                        release(x);\n                        return unit;\n                    }),\n                IO.pure));\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `bracketIO`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <param name=\"release\">Action to release the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> use<A>(IO<A> acquire, Action<A> release) =>\n        new IOUse<A, A>(\n            acquire,\n            x => IO.lift(\n                () =>\n                {\n                    release(x);\n                    return unit;\n                }),\n            IO.pure);\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <param name=\"release\">Action to release the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> use<A>(Func<A> acquire, Action<A> release) =>\n        use(IO.lift(acquire), release).As();\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <param name=\"release\">Action to release the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> use<A>(Func<A> acquire, Func<A, IO<Unit>> release) =>\n        use(IO.lift(acquire), release).As();\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <param name=\"release\">Action to release the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static K<M, A> use<M, A>(K<M, A> acquire, Func<A, IO<Unit>> release)\n        where M : MonadUnliftIO<M> =>\n        acquire.MapIO(acq => new IOUse<A, A>(acq, release, IO.pure));\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <param name=\"release\">Action to release the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> use<A>(IO<A> acquire, Func<A, IO<Unit>> release) =>\n        new IOUse<A, A>(acquire, release, IO.pure);\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> use<A>(Func<EnvIO, A> acquire) \n        where A : IDisposable =>\n        use(IO.lift(acquire)).As();\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> use<A>(Func<A> acquire)\n        where A : IDisposable =>\n        new IOUseDisposable<A, A>(IO.lift(acquire), IO.pure);\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> useAsync<A>(Func<A> acquire)\n        where A : IAsyncDisposable =>\n        new IOUseAsyncDisposable<A, A>(IO.lift(acquire), IO.pure);\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static K<M, A> use<M, A>(K<M, A> acquire)\n        where M : MonadUnliftIO<M>\n        where A : IDisposable =>\n        acquire.MapIO(acq => new IOUseDisposable<A, A>(acq, IO.pure));\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static K<M, A> useMaybe<M, A>(K<M, A> acquire)\n        where M : MonadIO<M>\n        where A : IDisposable =>\n        acquire.MapIOMaybe(acq => new IOUseDisposable<A, A>(acq, IO.pure));\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> use<A>(IO<A> acquire)\n        where A : IDisposable =>\n        new IOUseDisposable<A, A>(acquire, IO.pure);\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static K<M, A> useAsync<M, A>(K<M, A> acquire)\n        where M : MonadUnliftIO<M>\n        where A : IAsyncDisposable =>\n        acquire.MapIO(acq => new IOUseAsyncDisposable<A, A>(acq, IO.pure));\n\n    /// <summary>\n    /// Acquire a resource and have it tracked by the IO environment.  The resource\n    /// can be released manually using `release` or from wrapping a section of IO\n    /// code with `@using`.\n    /// </summary>\n    /// <param name=\"acquire\">Computation that acquires the resource</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Acquired resource</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> useAsync<A>(IO<A> acquire)\n        where A : IAsyncDisposable =>\n        new IOUseAsyncDisposable<A, A>(acquire, IO.pure);\n\n    /// <summary>\n    /// Release the resource from the tracked IO environment\n    /// </summary>\n    /// <param name=\"value\">Resource to release</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Unit</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<Unit> release<A>(A value) =>\n        IO.lift(env => env.Resources.Release(value).Run(env));\n\n    /// <summary>\n    /// The IO monad tracks resources automatically; this creates a local resource environment\n    /// to run the `computation` in.  Once the computation is completed, any resources acquired\n    /// are automatically released.  Imagine this as the ultimate `using` statement.\n    /// </summary>\n    /// <param name=\"computation\">Computation to run in a local scope</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Result of computation</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static K<M, A> bracketIO<M, A>(K<M, A> computation)\n        where M : MonadUnliftIO<M> =>\n        computation.BracketIO();\n\n    /// <summary>\n    /// The IO monad tracks resources automatically; this creates a local resource environment\n    /// to run the `computation` in.  Once the computation is completed, any resources acquired\n    /// are automatically released.  Imagine this as the ultimate `using` statement.\n    /// </summary>\n    /// <param name=\"computation\">Computation to run in a local scope</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Result of computation</returns>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<A> bracketIO<M, A>(IO<A> computation)\n        where M : MonadUnliftIO<M> =>\n        computation.Bracket();\n    \n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <remarks>\n    /// Consider using `bracketIO(computation)` rather than `bracket(acq, use, fin)`, the semantics are more attractive\n    /// as there's no need to provide function handlers, the cleanup is automatic. \n    /// </remarks>\n    /// <param name=\"Acq\">Acquire resource</param>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Fin\">Function to invoke to release the resource</param>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static K<M, C> bracketIO<M, A, B, C>(K<M, A> Acq, Func<A, IO<C>> Use, Func<A, IO<B>> Fin)\n        where M : MonadUnliftIO<M> =>\n        Acq.BracketIO(Use, Fin);\n    \n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <remarks>\n    /// Consider using `bracketIO(computation)` rather than `bracket(acq, use, fin)`, the semantics are more attractive\n    /// as there's no need to provide function handlers, the cleanup is automatic. \n    /// </remarks>\n    /// <param name=\"Acq\">Acquire resource</param>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Fin\">Function to invoke to release the resource</param>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<C> bracketIO<M, A, B, C>(IO<A> Acq, Func<A, IO<C>> Use, Func<A, IO<B>> Fin)\n        where M : MonadUnliftIO<M> =>\n        Acq.Bracket(Use, Fin);\n    \n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <remarks>\n    /// Consider using `bracketIO(computation)` rather than `bracket(acq, use, fin)`, the semantics are more attractive\n    /// as there's no need to provide function handlers, the cleanup is automatic. \n    /// </remarks>\n    /// <param name=\"Acq\">Acquire resource</param>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Catch\">Function called when an `Error` is raised within the `Acq` computation</param>\n    /// <param name=\"Finally\">Function to invoke to release the resource</param>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static K<M, C> bracketIO<M, A, B, C>(K<M, A> Acq, Func<A, IO<C>> Use, Func<Error, IO<C>> Catch, Func<A, IO<B>> Fin)\n        where M : MonadUnliftIO<M> =>\n        Acq.BracketIO(Use, Catch, Fin);\n    \n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <remarks>\n    /// Consider using `bracketIO(computation)` rather than `bracket(acq, use, fin)`, the semantics are more attractive\n    /// as there's no need to provide function handlers, the cleanup is automatic. \n    /// </remarks>\n    /// <param name=\"Acq\">Acquire resource</param>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Catch\">Function called when an `Error` is raised within the `Acq` computation</param>\n    /// <param name=\"Finally\">Function to invoke to release the resource</param>\n    [Pure]\n    [MethodImpl(Opt.Default)]\n    public static IO<C> bracketIO<M, A, B, C>(IO<A> Acq, Func<A, IO<C>> Use, Func<Error, IO<C>> Catch, Func<A, IO<B>> Fin)\n        where M : MonadIO<M> =>\n        Acq.Bracket(Use, Catch, Fin);\n    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Timer/Prelude.Timer.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Execute an action after a specified delay\n    /// </summary>\n    /// <param name=\"f\">Action to execute</param>\n    /// <param name=\"delayFor\">Time span to delay for</param>\n    public static Unit delay(Action f, TimeSpan delayFor)\n    {\n        if (delayFor.TotalMilliseconds < 1)\n        {\n            f();\n        }\n        else\n        {\n            Task.Delay(delayFor).ContinueWith(_ => f());\n        }\n        return unit;\n    }\n\n    /// <summary>\n    /// Execute a function at a specific time\n    /// </summary>\n    /// <remarks>\n    /// This will fail to be accurate across a Daylight Saving Time boundary\n    /// </remarks>\n    /// <param name=\"f\">Action to execute</param>\n    /// <param name=\"delayUntil\">DateTime to wake up at.</param>\n    public static Unit delay(Action f, DateTime delayUntil) =>\n        delay(f, delayUntil.ToUniversalTime() - DateTime.UtcNow);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prelude/Value parsing/Prelude.Parse.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Diagnostics.Contracts;\nusing System.Net;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    [Pure]\n    public static Option<A> convert<A>(object? value)\n    {\n        if (value == null)\n        {\n            return None;\n        }\n\n        try\n        {\n            var nvalue = (A)Convert.ChangeType(value, typeof(A));\n            return nvalue;\n        }\n        catch\n        {\n            return None;\n        }\n    }\n\n    [Pure]\n    public static K<M, A> convert<M, A>(object? value)\n        where M : Alternative<M>\n    {\n        if (value == null)\n        {\n            return M.Empty<A>();\n        }\n\n        try\n        {\n            var nvalue = (A)Convert.ChangeType(value, typeof(A));\n            return M.Pure(nvalue);\n        }\n        catch\n        {\n            return M.Empty<A>();\n        }\n    }\n\n    [Pure]\n    public static Option<long> parseLong(string? value) =>\n        Parse<long>(long.TryParse, value);\n\n    [Pure]\n    public static K<M, long> parseLong<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, long>(long.TryParse, value);\n\n    [Pure]\n    public static Option<int> parseInt(string? value) =>\n        Parse<int>(int.TryParse, value);\n\n    [Pure]\n    public static K<M, int> parseInt<M>(string? value)\n        where M : Alternative<M> =>\n        Parse<M, int>(int.TryParse, value);\n\n    [Pure]\n    public static Option<int> parseInt(string? value, int fromBase)\n    {\n        try\n        {\n            return Convert.ToInt32(value, fromBase);\n        }\n        catch\n        {\n            return None;\n        }\n    }\n\n    [Pure]\n    public static K<M, int> parseInt<M>(string? value, int fromBase)\n        where M : Alternative<M>\n    {\n        try\n        {\n            return M.Pure(Convert.ToInt32(value, fromBase));\n        }\n        catch\n        {\n            return M.Empty<int>();\n        }\n    }\n\n    [Pure]\n    public static Option<short> parseShort(string? value) =>\n        Parse<short>(short.TryParse, value);\n\n    [Pure]\n    public static K<M, short> parseShort<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, short>(short.TryParse, value);\n\n    [Pure]\n    public static Option<char> parseChar(string? value) =>\n        Parse<char>(char.TryParse, value);\n\n    [Pure]\n    public static K<M, char> parseChar<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, char>(char.TryParse, value);\n\n    [Pure]\n    public static Option<sbyte> parseSByte(string? value) =>\n        Parse<sbyte>(sbyte.TryParse, value);\n\n    [Pure]\n    public static K<M, sbyte> parseSByte<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, sbyte>(sbyte.TryParse, value);\n\n    [Pure]\n    public static Option<byte> parseByte(string? value) =>\n        Parse<byte>(byte.TryParse, value);\n\n    [Pure]\n    public static K<M, byte> parseByte<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, byte>(byte.TryParse, value);\n\n    [Pure]\n    public static Option<ulong> parseULong(string? value) =>\n        Parse<ulong>(ulong.TryParse, value);\n\n    [Pure]\n    public static K<M, ulong> parseULong<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, ulong>(ulong.TryParse, value);\n\n    [Pure]\n    public static Option<uint> parseUInt(string? value) =>\n        Parse<uint>(uint.TryParse, value);\n\n    [Pure]\n    public static K<M, uint> parseUInt<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, uint>(uint.TryParse, value);\n\n    [Pure]\n    public static Option<ushort> parseUShort(string? value) =>\n        Parse<ushort>(ushort.TryParse, value);\n\n    [Pure]\n    public static K<M, ushort> parseUShort<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, ushort>(ushort.TryParse, value);\n\n    [Pure]\n    public static Option<float> parseFloat(string? value) =>\n        Parse<float>(float.TryParse, value);\n\n    [Pure]\n    public static K<M, float> parseFloat<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, float>(float.TryParse, value);\n\n    [Pure]\n    public static Option<double> parseDouble(string? value) =>\n        Parse<double>(double.TryParse, value);\n\n    [Pure]\n    public static K<M, double> parseDouble<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, double>(double.TryParse, value);\n\n    [Pure]\n    public static Option<decimal> parseDecimal(string? value) =>\n        Parse<decimal>(decimal.TryParse, value);\n\n    [Pure]\n    public static K<M, decimal> parseDecimal<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, decimal>(decimal.TryParse, value);\n\n    [Pure]\n    public static Option<bool> parseBool(string? value) =>\n        Parse<bool>(bool.TryParse, value);\n\n    [Pure]\n    public static K<M, bool> parseBool<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, bool>(bool.TryParse, value);\n\n    [Pure]\n    public static Option<Guid> parseGuid(string? value) =>\n        Parse<Guid>(Guid.TryParse, value);\n\n    [Pure]\n    public static K<M, Guid> parseGuid<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, Guid>(Guid.TryParse, value);\n\n    [Pure]\n    public static Option<DateTime> parseDateTime(string? value) =>\n        Parse<DateTime>(DateTime.TryParse, value);\n\n    [Pure]\n    public static K<M, DateTime> parseDateTime<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, DateTime>(DateTime.TryParse, value);\n\n    [Pure]\n    public static Option<DateTimeOffset> parseDateTimeOffset(string? value) =>\n        Parse<DateTimeOffset>(DateTimeOffset.TryParse, value);\n\n    [Pure]\n    public static K<M, DateTimeOffset> parseDateTimeOffset<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, DateTimeOffset>(DateTimeOffset.TryParse, value);\n        \n    [Pure]\n    public static Option<TimeSpan> parseTimeSpan(string? value) =>\n        Parse<TimeSpan>(TimeSpan.TryParse, value);\n        \n    [Pure]\n    public static K<M, TimeSpan> parseTimeSpan<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, TimeSpan>(TimeSpan.TryParse, value);\n\n    [Pure]\n    public static Option<TEnum> parseEnum<TEnum>(string? value)\n        where TEnum : struct =>\n        Parse<TEnum>(Enum.TryParse, value);\n\n    [Pure]\n    public static K<M, TEnum> parseEnum<M, TEnum>(string? value)\n        where TEnum : struct \n        where M : Alternative<M> =>\n        Parse<M, TEnum>(Enum.TryParse, value);\n\n    [Pure]\n    public static Option<TEnum> parseEnumIgnoreCase<TEnum>(string? value)\n        where TEnum : struct =>\n        ParseIgnoreCase<TEnum>(Enum.TryParse, value);\n\n    [Pure]\n    public static K<M, TEnum> parseEnumIgnoreCase<M, TEnum>(string? value)\n        where TEnum : struct \n        where M : Alternative<M> =>\n        ParseIgnoreCase<M, TEnum>(Enum.TryParse, value);\n\n    [Pure]\n    public static Option<IPAddress> parseIPAddress(string? value) =>\n        Parse<IPAddress>(IPAddress.TryParse, value);\n\n    [Pure]\n    public static K<M, IPAddress> parseIPAddress<M>(string? value) \n        where M : Alternative<M> =>\n        Parse<M, IPAddress>(IPAddress.TryParse, value);\n\n    delegate bool TryParse<T>(string value, [NotNullWhen(true)] out T? result);\n\n    delegate bool TryParseIgnoreCase<T>(string value, bool ignoreCase, [NotNullWhen(true)] out T? result);\n\n    static Option<A> Parse<A>(TryParse<A> tryParse, string? value) =>\n        value is not null && tryParse(value, out var result)\n            ? Some(result)\n            : None;\n\n    static K<M, A> Parse<M, A>(TryParse<A> tryParse, string? value) \n        where M : Alternative<M> =>\n        value is not null && tryParse(value, out var result)\n            ? M.Pure(result)\n            : M.Empty<A>();\n    \n    static Option<A> ParseIgnoreCase<A>(TryParseIgnoreCase<A> tryParse, string? value) =>\n        value is not null && tryParse(value, true, out var result)\n            ? Some(result)\n            : None;\n    \n    static K<M, A> ParseIgnoreCase<M, A>(TryParseIgnoreCase<A> tryParse, string? value) \n        where M : Alternative<M> =>\n        value is not null && tryParse(value, true, out var result)\n            ? M.Pure(result)\n            : M.Empty<A>();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/Doc.cs",
    "content": "using System;\nusing System.Text;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pretty\n{\n    /// <summary>\n    /// Document building functions\n    /// </summary>\n    /// <remarks>\n    /// No annotation (unit only), use `DocAnn` for annotated documents\n    /// </remarks>\n    public static class Doc\n    {\n        public static readonly Doc<Unit> Fail =\n            DocAnn.Fail<Unit>();\n        \n        public static readonly Doc<Unit> Empty =\n            DocAnn.Empty<Unit>();\n        \n        public static Doc<Unit> Char(char c) =>\n            DocAnn.Char<Unit>(c);\n\n        public static Doc<Unit> Text(string text) =>\n            DocAnn.Text<Unit>(text);\n\n        public static Doc<Unit> FlatAlt(Doc<Unit> da, Doc<Unit> db) =>\n            DocAnn.FlatAlt(da, db);\n \n        public static Doc<Unit> Union(Doc<Unit> da, Doc<Unit> db) =>\n            DocAnn.Union(da, db);\n        \n        public static Doc<Unit> Cat(Doc<Unit> da, Doc<Unit> db) =>\n            DocAnn.Cat(da, db);\n\n        public static Doc<Unit> Nest(int indent, Doc<Unit> doc) =>\n            DocAnn.Nest(indent, doc);\n\n        public static Doc<Unit> Column(Func<int, Doc<Unit>> f) =>\n            DocAnn.Column(f);\n\n        public static Doc<Unit> PageWidth(Func<PageWidth, Doc<Unit>> f) =>\n            DocAnn.PageWidth(f);\n\n        public static Doc<Unit> Nesting(Func<int, Doc<Unit>> f) =>\n            DocAnn.Nesting(f);\n        \n        /// <summary>\n        /// A hardline is always laid out as a line break, even when 'grouped or\n        /// when there is plenty of space. Note that it might still be simply discarded\n        /// if it is part of a 'FlatAlt' inside a 'Group'.\n        /// </summary>\n        public static readonly Doc<Unit> HardLine =\n            DocLine<Unit>.Default;\n\n        /// <summary>\n        /// LineOrSpace is a line-break, but behaves like Char(' ') if the line break\n        /// is undone by Group\n        /// </summary>\n        public static readonly Doc<Unit> LineOrSpace =\n            DocAnn.LineOrSpace<Unit>();\n\n        /// <summary>\n        /// LineOrEmpty is a line-break, but behaves like Empty if the line break\n        /// is undone by Group\n        /// </summary>\n        public static readonly Doc<Unit> LineOrEmpty =\n            DocAnn.LineOrEmpty<Unit>();\n\n        /// <summary>\n        /// softline behaves like space if the resulting output fits the page,\n        /// otherwise like line\n        /// </summary>\n        public static readonly Doc<Unit> SoftLineOrSpace =\n            DocAnn.SoftLineOrSpace<Unit>();\n\n        /// <summary>\n        /// softline behaves like Empty if the resulting output fits the page,\n        /// otherwise like line\n        /// </summary>\n        public static readonly Doc<Unit> SoftLineOrEmpty =\n            DocAnn.SoftLineOrEmpty<Unit>();\n\n        /// <summary>\n        /// Group tries laying out doc into a single line by removing the\n        /// contained line breaks; if this does not fit the page, or when a 'hardline'\n        /// within doc prevents it from being flattened, doc is laid out without any\n        /// changes.\n        /// \n        /// The 'group' function is key to layouts that adapt to available space nicely.\n        /// </summary>\n        public static Doc<Unit> Group(Doc<Unit> doc) =>\n            DocAnn.Group(doc);\n\n        /// <summary>\n        /// Align lays out the document with the nesting level set to the\n        /// current column. It is used for example to implement 'hang'.\n        ///\n        /// As an example, we will put a document right above another one, regardless of\n        /// the current nesting level. Without alignment, the second line is put simply\n        /// below everything we've had so far,\n        ///\n        ///     Text(\"lorem\") + VertSep([\"ipsum\", \"dolor\"])\n        ///\n        /// lorem ipsum\n        /// dolor\n        ///\n        /// If we add an Align to the mix, the VertSep contents all start in the\n        /// same column,\n        ///\n        /// >>> Text(\"lorem\") + Align (VertSep([\"ipsum\", \"dolor\"]))\n        /// lorem ipsum\n        ///       dolor        \n        /// </summary>\n        public static Doc<Unit> Align(Doc<Unit> doc) =>\n            DocAnn.Align(doc);\n\n        /// <summary>     \n        /// Hang lays out the document with a nesting level set to the\n        /// /current column/ plus offset. Negative values are allowed, and decrease the\n        /// nesting level accordingly.\n        ///\n        /// >>> var doc = Reflow(\"Indenting these words with hang\")\n        /// >>> PutDocW(24, (\"prefix\" + Hang(4, doc)))\n        /// prefix Indenting these\n        ///            words with\n        ///            hang\n        ///\n        /// This differs from Nest, which is based on the /current nesting level/ plus\n        /// offset. When you're not sure, try the more efficient 'nest' first. In our\n        /// example, this would yield\n        ///\n        /// >>> var doc = Reflow(\"Indenting these words with nest\")\n        /// >>> PutDocW(24, \"prefix\" + Nest(4, doc))\n        /// prefix Indenting these\n        ///     words with nest\n        /// </summary>\n        public static Doc<Unit> Hang(int offset, Doc<Unit> doc) =>\n            DocAnn.Hang(offset, doc);\n\n        /// <summary>\n        /// Indents document `indent` columns, starting from the\n        /// current cursor position.\n        ///\n        /// >>> var doc = Reflow(\"The indent function indents these words!\")\n        /// >>> PutDocW(24, (\"prefix\" + Indent(4, doc))\n        /// prefix    The indent\n        ///           function\n        ///           indents these\n        ///           words!\n        ///\n        /// </summary>\n        public static Doc<Unit> Indent(int indent, Doc<Unit> doc) =>\n            DocAnn.Indent(indent, doc);\n\n        /// <summary>\n        /// Delimit and intersperse the documents with a separator\n        /// </summary>\n        public static Doc<Unit> EncloseSep(Doc<Unit> leftDelim, Doc<Unit> rightDelim, Doc<Unit> sep, Seq<Doc<Unit>> docs) =>\n            DocAnn.BetweenSep(leftDelim, rightDelim, sep, docs);\n\n        /// <summary>\n        /// Delimit and intersperse the documents with a separator\n        /// </summary>\n        public static Doc<Unit> EncloseSep(Doc<Unit> leftDelim, Doc<Unit> rightDelim, Doc<Unit> sep, params Doc<Unit>[] docs) =>\n            DocAnn.BetweenSep(leftDelim, rightDelim, sep, docs);\n\n        /// <summary>\n        /// Haskell-inspired array/list formatting\n        /// </summary>\n        public static Doc<Unit> List(Seq<Doc<Unit>> docs) =>\n            DocAnn.List(docs);\n\n        /// <summary>\n        /// Haskell-inspired tuple formatting\n        /// </summary>\n        public static Doc<Unit> Tuple(Seq<Doc<Unit>> docs) =>\n            DocAnn.Tuple(docs);\n\n        /// <summary>\n        /// Haskell-inspired array/list formatting\n        /// </summary>\n        public static Doc<Unit> List(params Doc<Unit>[] docs) =>\n            DocAnn.List(docs);\n\n        /// <summary>\n        /// Haskell-inspired tuple formatting\n        /// </summary>\n        public static Doc<Unit> Tuple(params Doc<Unit>[] docs) =>\n            DocAnn.Tuple(docs);\n        \n        /// <summary>\n        /// Insert a number of spaces. Negative values count as 0.\n        /// </summary>\n        public static Doc<Unit> Spaces(int n) =>\n            DocAnn.Spaces<Unit>(n);\n        \n        /// <summary>\n        /// HorizSep concatenates all documents horizontally with `+`\n        /// i.e. it puts a space between all entries.\n        ///\n        /// HorizSep does not introduce line breaks on its own, even when the page is too\n        /// narrow:\n        ///\n        /// For automatic line breaks, consider using 'fillSep' instead.\n        /// </summary>\n        public static Doc<Unit> HorizSep(Seq<Doc<Unit>> docs) =>\n            DocAnn.HorizSep(docs);\n\n        /// <summary>\n        /// VertSep concatenates all documents above each other. If a\n        /// Group undoes the line breaks inserted by VertSep, the documents are\n        /// separated with a 'space' instead.\n        ///\n        /// Grouping a VertSep separates the documents with a 'space' if it fits the\n        /// page (and does nothing otherwise). See the Sep convenience function for\n        /// this use case.\n        ///\n        /// The Align function can be used to align the documents under their first\n        /// element:\n        ///\n        /// Since Grouping a VertSep is rather common, Sep is a built-in for doing\n        /// that.        \n        /// </summary>\n        public static Doc<Unit> VertSep(Seq<Doc<Unit>> docs) =>\n            DocAnn.VertSep(docs);\n\n        /// <summary>\n        /// Intersperse the documents with a separator\n        /// </summary>\n        public static Doc<Unit> Sep(Doc<Unit> sep, Seq<Doc<Unit>> docs) =>\n            DocAnn.Sep(sep, docs);\n \n        /// <summary>\n        /// Sep tries laying out the documents separated with 'space's,\n        /// and if this does not fit the page, separates them with newlines. This is what\n        /// differentiates it from VerSep, which always lays out its contents beneath\n        /// each other.\n        /// </summary>\n        public static Doc<Unit> Sep(Seq<Doc<Unit>> docs) =>\n            DocAnn.Sep(docs);\n\n        /// <summary>\n        /// FillSep concatenates the documents horizontally with `+` (inserting a space)\n        /// as long as it fits the page, then inserts a Line and continues doing that\n        /// for all documents in (Line means that if Grouped, the documents\n        /// are separated with a Space instead of newlines.  Use 'FillCat' if you do not\n        /// want a 'space'.)       \n        /// </summary>\n        public static Doc<Unit> FillSep(Seq<Doc<Unit>> docs) =>\n            DocAnn.FillSep(docs);\n\n        /// <summary>\n        /// Hard line separator\n        /// </summary>\n        public static Doc<Unit> HardSep(Seq<Doc<Unit>> docs) =>\n            DocAnn.HardSep(docs);\n\n        /// <summary>\n        /// HorizCat concatenates all documents horizontally with |\n        /// (i.e. without any spacing).\n        /// \n        /// It is provided only for consistency, since it is identical to 'Cat'.\n        /// </summary>\n        public static Doc<Unit> HorizCat(Seq<Doc<Unit>> docs) =>\n            DocAnn.HorizSep(docs);\n\n        /// <summary>\n        /// VertCat vertically concatenates the documents. If it is\n        /// Grouped, the line breaks are removed.\n        ///\n        /// In other words VertCat is like VertSep, with newlines removed instead of\n        /// replaced by spaces.\n        /// </summary>\n        public static Doc<Unit> VertCat(Seq<Doc<Unit>> docs) =>\n            DocAnn.VertSep(docs);\n        \n        /// <summary>\n        /// Width lays out the document 'doc', and makes the column width\n        /// of it available to a function.\n        /// </summary>\n        public static Doc<Unit> Width(Doc<Unit> doc, Func<int, Doc<Unit>> f) =>\n            DocAnn.Width(doc, f);\n\n        /// <summary>\n        /// Fill lays out the document. It then appends spaces until\n        /// the width is equal to `width`. If the width is already larger, nothing is\n        /// appended.\n        /// </summary>\n        public static Doc<Unit> Fill(int width, Doc<Unit> doc) =>\n            DocAnn.Fill(width, doc);\n\n        /// <summary>\n        /// Enclose\n        /// </summary>\n        public static Doc<Unit> Between(Doc<Unit> left, Doc<Unit> right, Doc<Unit> middle) =>\n            DocAnn.Between(left, middle, right);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/DocAnn.cs",
    "content": "using System;\nusing System.Text;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pretty;\n\n/// <summary>\n/// Document building functions\n/// </summary>\n/// <remarks>\n/// Carries annotation, for unit only annotations, use `Doc`\n/// </remarks>\npublic static class DocAnn\n{\n    public static Doc<A> Annotate<A>(A annotation, Doc<A> doc) =>\n        new DocAnnotate<A>(annotation, doc);\n        \n    public static Doc<A> Fail<A>() =>\n        DocFail<A>.Default;\n\n    public static Doc<A> Empty<A>() =>\n        DocEmpty<A>.Default;\n        \n    public static Doc<A> Char<A>(char c) =>\n        c == '\\n'\n            ? LineOrSpace<A>()\n            : new DocChar<A>(c);\n\n    public static Doc<A> Text<A>(string text) =>\n        string.IsNullOrEmpty(text)\n            ? DocEmpty<A>.Default\n            : text.Length == 1\n                ? Char<A>(text[0])\n                : text.Contains(\"\\n\")\n                    ? text.Split('\\n')\n                          .AsIterable() \n                          .Map(Text<A>)\n                          .Intersperse(DocLine<A>.Default)\n                          .Reduce(Cat)\n                    : new DocText<A>(text);\n\n    public static Doc<A> FlatAlt<A>(Doc<A> da, Doc<A> db) =>\n        new DocFlatAlt<A>(da, db);\n \n    public static Doc<A> Union<A>(Doc<A> da, Doc<A> db) =>\n        new DocFlatAlt<A>(da, db);\n\n    public static Doc<A> Cat<A>(Doc<A> da, Doc<A> db) =>\n        (da, db) switch\n        {\n            (DocEmpty<A>, DocEmpty<A>) => da,\n            (DocEmpty<A>, _)           => db,\n            (_, DocEmpty<A>)           => da,\n            _                          => new DocCat<A>(da, db)\n        };\n\n    public static Doc<A> Nest<A>(int indent, Doc<A> doc) =>\n        indent == 0\n            ? doc\n            : new DocNest<A>(indent, doc);\n\n    public static Doc<A> Column<A>(Func<int, Doc<A>> f) =>\n        new DocColumn<A>(f);\n\n    public static Doc<A> PageWidth<A>(Func<PageWidth, Doc<A>> f) =>\n        new DocPageWidth<A>(f);\n\n    public static Doc<A> Nesting<A>(Func<int, Doc<A>> f) =>\n        new DocNesting<A>(f);\n        \n    /// <summary>\n    /// A hardline is always laid out as a line break, even when 'grouped or\n    /// when there is plenty of space. Note that it might still be simply discarded\n    /// if it is part of a 'FlatAlt' inside a 'Group'.\n    /// </summary>\n    public static Doc<A> HardLine<A>() =>\n        DocLine<A>.Default;\n\n    /// <summary>\n    /// LineOrSpace is a line-break, but behaves like space if the line break\n    /// is undone by Group\n    /// </summary>\n    public static Doc<A> LineOrSpace<A>() =>\n        FlatAlt(DocLine<A>.Default, Char<A>(' '));\n\n    /// <summary>\n    /// LineOrEmpty is a line-break, but behaves like Empty if the line break\n    /// is undone by Group\n    /// </summary>\n    public static Doc<A> LineOrEmpty<A>() =>\n        FlatAlt(DocLine<A>.Default, Empty<A>());\n\n    /// <summary>\n    /// softline behaves like space if the resulting output fits the page,\n    /// otherwise like line\n    /// </summary>\n    public static Doc<A> SoftLineOrSpace<A>() =>\n        Union(Char<A>(' '), DocLine<A>.Default);\n\n    /// <summary>\n    /// softline behaves like Empty if the resulting output fits the page,\n    /// otherwise like line\n    /// </summary>\n    public static Doc<A> SoftLineOrEmpty<A>() =>\n        Union(Empty<A>(), DocLine<A>.Default);\n\n    /// <summary>\n    /// Group tries laying out doc into a single line by removing the\n    /// contained line breaks; if this does not fit the page, or when a 'hardline'\n    /// within doc prevents it from being flattened, doc is laid out without any\n    /// changes.\n    /// \n    /// The 'group' function is key to layouts that adapt to available space nicely.\n    /// </summary>\n    public static Doc<A> Group<A>(Doc<A> doc) =>\n        doc switch\n        {\n            DocUnion<A> _ => doc,\n            DocFlatAlt<A> (var a, var b) => b.ChangesUponFlattening() switch\n                                            {\n                                                Flattened<Doc<A>> (var b1) => Union(b1, a),\n                                                AlreadyFlat<Doc<A>>        => Union(b, a),\n                                                _                          => a\n                                            },\n            _ => doc.ChangesUponFlattening() switch\n                 {\n                     Flattened<Doc<A>> (var x1) => Union(x1, doc),\n                     _                          => doc\n                 },\n        };\n\n    /// <summary>\n    /// Align lays out the document with the nesting level set to the\n    /// current column. It is used for example to implement 'hang'.\n    ///\n    /// As an example, we will put a document right above another one, regardless of\n    /// the current nesting level. Without alignment, the second line is put simply\n    /// below everything we've had so far,\n    ///\n    ///     Text(\"lorem\") + VertSep([\"ipsum\", \"dolor\"])\n    ///\n    /// lorem ipsum\n    /// dolor\n    ///\n    /// If we add an 'Align' to the mix, the VertSep's contents all start in the\n    /// same column,\n    ///\n    /// >>> Text(\"lorem\") + Align (VertSep([\"ipsum\", \"dolor\"]))\n    /// lorem ipsum\n    ///       dolor        \n    /// </summary>\n    public static Doc<A> Align<A>(Doc<A> doc) =>\n        Column(k => Nesting(i => Nest(k - i, doc)));\n\n    /// <summary>     \n    /// Hang lays out the document with a nesting level set to the\n    /// /current column/ plus offset. Negative values are allowed, and decrease the\n    /// nesting level accordingly.\n    ///\n    /// >>> var doc = Reflow(\"Indenting these words with hang\")\n    /// >>> PutDocW(24, (\"prefix\" + Hang(4, doc)))\n    /// prefix Indenting these\n    ///            words with\n    ///            hang\n    ///\n    /// This differs from Nest, which is based on the /current nesting level/ plus\n    /// offset. When you're not sure, try the more efficient 'nest' first. In our\n    /// example, this would yield\n    ///\n    /// >>> var doc = Reflow(\"Indenting these words with nest\")\n    /// >>> PutDocW(24, \"prefix\" + Nest(4, doc))\n    /// prefix Indenting these\n    ///     words with nest\n    /// </summary>\n    public static Doc<A> Hang<A>(int offset, Doc<A> doc) =>\n        Align(Nest(offset, doc));\n\n    /// <summary>\n    /// Indents document `indent` columns, starting from the\n    /// current cursor position.\n    ///\n    /// >>> var doc = Reflow(\"The indent function indents these words!\")\n    /// >>> PutDocW(24, (\"prefix\" + Indent(4, doc))\n    /// prefix    The indent\n    ///           function\n    ///           indents these\n    ///           words!\n    ///\n    /// </summary>\n    public static Doc<A> Indent<A>(int indent, Doc<A> doc) =>\n        Hang(indent, Spaces<A>(indent) | doc);\n\n    /// <summary>\n    /// Intersperse the documents with a separator\n    /// </summary>\n    public static Doc<A> Sep<A>(Doc<A> sep, Seq<Doc<A>> docs)\n    {\n        if (docs.IsEmpty) return Empty<A>();\n        var d = docs.Head.Value!;\n        foreach (var doc in docs.Tail)\n        {\n            d = d | sep | doc;\n        }\n        return d;\n    }\n\n    /// <summary>\n    /// Delimit and intersperse the documents with a separator\n    /// </summary>\n    public static Doc<A> BetweenSep<A>(Doc<A> leftDelim, Doc<A> rightDelim, Doc<A> sep, Seq<Doc<A>> docs) =>\n        leftDelim | Sep(sep, docs) | rightDelim;\n\n    /// <summary>\n    /// Delimit and intersperse the documents with a separator\n    /// </summary>\n    public static Doc<A> BetweenSep<A>(Doc<A> leftDelim, Doc<A> rightDelim, Doc<A> sep, params Doc<A>[] docs) =>\n        BetweenSep(leftDelim, rightDelim, sep, toSeq(docs));\n\n    /// <summary>\n    /// Haskell-inspired array/list formatting\n    /// </summary>\n    public static Doc<A> List<A>(Seq<Doc<A>> docs) =>\n        Group(BetweenSep(\n                  FlatAlt<A>(\"[ \", \"[\"),\n                  FlatAlt<A>(\" ]\", \"]\"),\n                  \", \",\n                  docs));\n\n    /// <summary>\n    /// Haskell-inspired tuple formatting\n    /// </summary>\n    public static Doc<A> Tuple<A>(Seq<Doc<A>> docs) =>\n        Group(BetweenSep(\n                  FlatAlt<A>(\"( \", \"(\"),\n                  FlatAlt<A>(\" )\", \")\"),\n                  \", \",\n                  docs));\n        \n\n    /// <summary>\n    /// Haskell-inspired array/list formatting\n    /// </summary>\n    public static Doc<A> List<A>(params Doc<A>[] docs) =>\n        Group(BetweenSep(\n                  FlatAlt<A>(\"[ \", \"[\"),\n                  FlatAlt<A>(\" ]\", \"]\"),\n                  \", \",\n                  docs));\n\n    /// <summary>\n    /// Haskell-inspired tuple formatting\n    /// </summary>\n    public static Doc<A> Tuple<A>(params Doc<A>[] docs) =>\n        Group(BetweenSep(\n                  FlatAlt<A>(\"( \", \"(\"),\n                  FlatAlt<A>(\" )\", \")\"),\n                  \", \",\n                  docs));        \n\n    /// <summary>\n    /// Insert a number of spaces. Negative values count as 0.\n    /// </summary>\n    public static Doc<A> Spaces<A>(int n)\n    {\n        return (n < 0 ? 0 : n) switch\n               {\n                   0 => Empty<A>(),\n                   1 => Char<A>(' '),\n                   2 => Text<A>(\"  \"),\n                   3 => Text<A>(\"   \"),\n                   4 => Text<A>(\"    \"),\n                   5 => Text<A>(\"     \"),\n                   6 => Text<A>(\"      \"),\n                   7 => Text<A>(\"       \"),\n                   8 => Text<A>(\"        \"),\n                   _ => Text<A>(FastSpace(n - 8))\n               };\n            \n        string FastSpace(int x)\n        {\n            var sb = new StringBuilder();\n            sb.Append(\"        \");\n            for (var i = 0; i < x; i++)\n            {\n                sb.Append(' ');\n            }\n            return sb.ToString();\n        }\n    }\n\n    /// <summary>\n    /// HorizSep concatenates all documents horizontally with `+`\n    /// i.e. it puts a space between all entries.\n    ///\n    /// HorizSep does not introduce line breaks on its own, even when the page is too\n    /// narrow:\n    ///\n    /// For automatic line breaks, consider using 'fillSep' instead.\n    /// </summary>\n    public static Doc<A> HorizSep<A>(Seq<Doc<A>> docs) =>\n        docs.IsEmpty\n            ? DocEmpty<A>.Default\n            : docs.Tail.Fold(docs.Head.Value!, (s, d) => s + d);\n\n    /// <summary>\n    /// VertSep concatenates all documents above each other. If a\n    /// Group undoes the line breaks inserted by VertSep, the documents are\n    /// separated with a 'space' instead.\n    ///\n    /// Grouping a VertSep separates the documents with a 'space' if it fits the\n    /// page (and does nothing otherwise). See the Sep convenience function for\n    /// this use case.\n    ///\n    /// The Align function can be used to align the documents under their first\n    /// element:\n    ///\n    /// Since Grouping a VertSep is rather common, Sep is a built-in for doing\n    /// that.        \n    /// </summary>\n    public static Doc<A> VertSep<A>(Seq<Doc<A>> docs) =>\n        docs.IsEmpty\n            ? DocEmpty<A>.Default\n            : docs.Tail.Fold(docs.Head.Value!, (s, d) => s | LineOrSpace<A>() | d);\n\n    /// <summary>\n    /// Sep tries laying out the documents separated with 'space's,\n    /// and if this does not fit the page, separates them with newlines. This is what\n    /// differentiates it from VerSep, which always lays out its contents beneath\n    /// each other.\n    /// </summary>\n    public static Doc<A> Sep<A>(Seq<Doc<A>> docs) =>\n        Group(VertSep(docs));\n\n    /// <summary>\n    /// FillSep concatenates the documents horizontally with `+` (inserting a space)\n    /// as long as it fits the page, then inserts a Line and continues doing that\n    /// for all documents in (Line means that if Grouped, the documents\n    /// are separated with a Space instead of newlines.  Use 'FillCat' if you do not\n    /// want a 'space'.)       \n    /// </summary>\n    public static Doc<A> FillSep<A>(Seq<Doc<A>> docs) =>\n        docs.IsEmpty\n            ? DocEmpty<A>.Default\n            : docs.Tail.Fold(docs.Head.Value!, (s, d) => s | SoftLineOrSpace<A>() | d);\n\n    /// <summary>\n    /// Hard line separator\n    /// </summary>\n    public static Doc<A> HardSep<A>(Seq<Doc<A>> docs) =>\n        docs.IsEmpty\n            ? DocEmpty<A>.Default\n            : docs.Tail.Fold(docs.Head.Value!, (s, d) => (s, d) switch\n                                                         {\n                                                             (DocLine<A>, DocLine<A>) => s,\n                                                             (DocLine<A>, _)          => d,\n                                                             (_, DocLine<A>)          => s,\n                                                             _                        => s | HardLine<A>() | d\n                                                         });\n         \n    /// <summary>\n    /// HorizCat concatenates all documents horizontally with |\n    /// (i.e. without any spacing).\n    /// \n    /// It is provided only for consistency, since it is identical to 'Cat'.\n    /// </summary>\n    public static Doc<A> HorizCat<A>(Seq<Doc<A>> docs) =>\n        docs.IsEmpty\n            ? DocEmpty<A>.Default\n            : docs.Tail.Fold(docs.Head.Value!, (s, d) => s | d);\n\n    /// <summary>\n    /// VertCat vertically concatenates the documents. If it is\n    /// Grouped, the line breaks are removed.\n    ///\n    /// In other words VertCat is like VertSep, with newlines removed instead of\n    /// replaced by spaces.\n    /// </summary>\n    public static Doc<A> VertCat<A>(Seq<Doc<A>> docs) =>\n        docs.IsEmpty\n            ? DocEmpty<A>.Default\n            : docs.Tail.Fold(docs.Head.Value!, (s, d) => s | LineOrEmpty<A>() | d);\n\n    /// <summary>\n    /// Width lays out the document 'doc', and makes the column width\n    /// of it available to a function.\n    /// </summary>\n    public static Doc<A> Width<A>(Doc<A> doc, Func<int, Doc<A>> f) =>\n        Column<A>(colStart =>\n                      doc | Column<A>(colEnd =>\n                                          f(colEnd - colStart)));\n\n    /// <summary>\n    /// Fill lays out the document. It then appends spaces until\n    /// the width is equal to `width`. If the width is already larger, nothing is\n    /// appended.\n    /// </summary>\n    public static Doc<A> Fill<A>(int width, Doc<A> doc) =>\n        Width(doc, w => Spaces<A>(width - w));\n\n    /// <summary>\n    /// Enclose\n    /// </summary>\n    public static Doc<A> Between<A>(Doc<A> left, Doc<A> middle, Doc<A> right) =>\n        left | middle | right;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/DocStream.cs",
    "content": "using System;\nusing System.Text;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pretty\n{\n    public abstract record DocStream<A>\n    {\n        public DocStream<B> Select<B>(Func<A, B> f) => ReAnnotate(f);\n        public DocStream<B> Map<B>(Func<A, B> f) => ReAnnotate(f);\n        public abstract DocStream<B> ReAnnotate<B>(Func<A, B> f);\n\n        public string Show()\n        {\n            var doc = this;\n            var sb  = new StringBuilder();\n            while (true)\n            {\n                switch (doc)\n                {\n                    case SFail<A>:\n                        sb.Append(\"[FAIL]\");\n                        return sb.ToString();//throw new Exception(\"Doc Fail\");\n                    \n                    case SEmpty<A>:\n                        return sb.ToString();\n                    \n                    case SChar<A> (var c, var next):\n                        sb.Append(c);\n                        doc = next;\n                        break;\n                    \n                    case SText<A> (var t, var next):\n                        sb.Append(t);\n                        doc = next;\n                        break;\n                    \n                    case SLine<A>(var i, var next):\n                        sb.AppendLine();\n                        sb.Append(FastSpace.Show(i));\n                        doc = next;\n                        break;\n                    \n                    case SAnnPush<A>(var _, var next):\n                        doc = next;\n                        break;\n                    \n                    case SAnnPop<A>(var next):\n                        doc = next;\n                        break;\n                }\n            }\n        }\n    }\n\n    public record SFail<A> : DocStream<A>\n    {\n        public static readonly DocStream<A> Default = new SFail<A>();\n\n        public override DocStream<B> ReAnnotate<B>(Func<A, B> f) =>\n            SFail<B>.Default;\n    }\n\n    public record SEmpty<A> : DocStream<A>\n    {\n        public static readonly DocStream<A> Default = new SEmpty<A>();\n\n        public override DocStream<B> ReAnnotate<B>(Func<A, B> f) =>\n            SEmpty<B>.Default;\n    }\n\n    public record SChar<A>(char Value, DocStream<A> Next) : DocStream<A>\n    {\n        public override DocStream<B> ReAnnotate<B>(Func<A, B> f) =>\n            new SChar<B>(Value, Next.ReAnnotate(f));\n    }\n\n    public record SText<A>(string Value, DocStream<A> Next) : DocStream<A>\n    {\n        public override DocStream<B> ReAnnotate<B>(Func<A, B> f) =>\n            new SText<B>(Value, Next.ReAnnotate(f));\n    }\n    \n    public record SLine<A>(int Indent, DocStream<A> Next) : DocStream<A>\n    {\n        public override DocStream<B> ReAnnotate<B>(Func<A, B> f) =>\n            new SLine<B>(Indent, Next.ReAnnotate(f));\n    }\n        \n    public record SAnnPush<A>(A Ann, DocStream<A> Next) : DocStream<A>\n    {\n        public override DocStream<B> ReAnnotate<B>(Func<A, B> f) =>\n            new SAnnPush<B>(f(Ann), Next.ReAnnotate(f));\n    }\n\n    public record SAnnPop<A>(DocStream<A> Next) : DocStream<A>\n    {\n        public override DocStream<B> ReAnnotate<B>(Func<A, B> f) =>\n            new SAnnPop<B>(Next.ReAnnotate(f));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/Doc_A.cs",
    "content": "using System;\nusing System.Text;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pretty\n{\n    /// <summary>\n    /// Base document record\n    /// </summary>\n    /// <remarks>\n    /// Construct documents using the Doc and DocAnn static types\n    /// </remarks>\n    public abstract record Doc<A>\n    {\n        public virtual Doc<A> Append(Doc<A> d) =>\n            DocAnn.Cat<A>(this, d);\n\n        public readonly Doc<A> Empty =\n            DocEmpty<A>.Default;\n\n        public static Doc<A> operator +(Doc<A> x, Doc<A> y) =>\n            x | DocAnn.Char<A>(' ') | y;\n\n        public static Doc<A> operator +(string x, Doc<A> y) =>\n            x | DocAnn.Char<A>(' ') | y;\n\n        public static Doc<A> operator +(Doc<A> x, string y) =>\n            x | DocAnn.Char<A>(' ') | y;\n\n        public static Doc<A> operator |(Doc<A> x, Doc<A> y) =>\n            x.Append(y);\n\n        public static Doc<A> operator |(string x, Doc<A> y) =>\n            DocAnn.Text<A>(x).Append(y);\n\n        public static Doc<A> operator |(Doc<A> x, string y) =>\n            x.Append(DocAnn.Text<A>(y));\n\n        public Doc<B> Select<B>(Func<A, B> f) =>\n            ReAnnotate(f);\n\n        public Doc<B> Map<B>(Func<A, B> f) =>\n            ReAnnotate(f);\n\n        public abstract Doc<B> ReAnnotate<B>(Func<A, B> f);\n        public abstract FlattenResult<Doc<A>> ChangesUponFlattening();\n        public abstract Doc<A> Flatten();\n\n        public static implicit operator Doc<A>(string x) =>\n            DocAnn.Text<A>(x);\n\n        public string Show() =>\n            Layout.smart(LayoutOptions.Default, this).Show();\n    }\n\n    public record DocFail<A> : Doc<A>\n    {\n        public readonly static Doc<A> Default = new DocFail<A>();\n\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocFail<B>.Default;\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            NeverFlat<Doc<A>>.Default;\n\n        public override Doc<A> Flatten() =>\n            this;\n    }\n        \n    public record DocEmpty<A> : Doc<A>\n    {\n        public readonly static Doc<A> Default = new DocEmpty<A>();\n\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocEmpty<B>.Default;\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            AlreadyFlat<Doc<A>>.Default;\n\n        public override Doc<A> Flatten() =>\n            this;\n\n        public override Doc<A> Append(Doc<A> d) =>\n            d switch\n            {\n                DocText<A>(var ts) => d,\n                DocChar<A>(var c)  => d,\n                DocEmpty<A>        => this,\n                _                  => base.Append(d)\n            };\n    }\n\n    /// <summary>\n    /// Invariant: not '\\n'\n    /// </summary>\n    /// <typeparam name=\"A\"></typeparam>\n    public record DocChar<A>(char Value) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.Char<B>(Value);\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            AlreadyFlat<Doc<A>>.Default;\n\n        public override Doc<A> Flatten() =>\n            this;\n    }\n\n    /// <summary>\n    /// At least two characters long, does not contain '\\n'. For\n    /// empty documents, there is `DocEmpty`; for singleton documents, there is\n    /// `DocChar`; newlines should be replaced by e.g. `DocLine`.\n    /// </summary>\n    /// <typeparam name=\"A\"></typeparam>\n    public record DocText<A>(string Text) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.Text<B>(Text);\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            AlreadyFlat<Doc<A>>.Default;\n\n        public override Doc<A> Flatten() =>\n            this;\n\n        public int Length =>\n            Text.Length;\n    }\n\n    /// <summary>\n    /// Hard line break\n    /// </summary>\n    public record DocLine<A> : Doc<A>\n    {\n        public readonly static Doc<A> Default = new DocLine<A>();\n\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocLine<B>.Default;\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            NeverFlat<Doc<A>>.Default;\n\n        public override Doc<A> Flatten() =>\n            DocFail<A>.Default;\n    }\n\n    /// <summary>\n    /// Lay out the first 'Doc', but when flattened (via 'group'), prefer\n    /// the second.\n    /// \n    /// The layout algorithms work under the assumption that the first\n    /// alternative is less wide than the flattened second alternative.\n    /// </summary>\n    public record DocFlatAlt<A>(Doc<A> Primary, Doc<A> Alt) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.FlatAlt<B>(Primary.ReAnnotate(f), Alt.ReAnnotate(f));\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            new Flattened<Doc<A>>(Alt.Flatten());\n\n        public override Doc<A> Flatten() =>\n            Alt.Flatten();\n    }\n\n    /// <summary>\n    /// The first lines of first document should be longer than the\n    /// first lines of the second one, so the layout algorithm can pick the one\n    /// that fits best. Used to implement layout alternatives for 'group'.\n    /// </summary>\n    public record DocUnion<A>(Doc<A> DocA, Doc<A> DocB) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.Union<B>(DocA.ReAnnotate(f), DocB.ReAnnotate(f));\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            new Flattened<Doc<A>>(DocA.Flatten());\n\n        public override Doc<A> Flatten() =>\n            DocA.Flatten();\n    }\n\n    /// <summary>\n    /// Concat two documents\n    /// </summary>\n    public record DocCat<A>(Doc<A> DocA, Doc<A> DocB) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.Cat(DocA.ReAnnotate(f), DocB.ReAnnotate(f));\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            (DocA.ChangesUponFlattening(), DocB.ChangesUponFlattening()) switch\n            {\n                (NeverFlat<Doc<A>>, _)                                   => NeverFlat<Doc<A>>.Default,\n                (_, NeverFlat<Doc<A>>)                                   => NeverFlat<Doc<A>>.Default,\n                (Flattened<Doc<A>> (var x1), Flattened<Doc<A>> (var y1)) => new Flattened<Doc<A>>(DocAnn.Cat<A>(x1, y1)),\n                (Flattened<Doc<A>> (var x1), AlreadyFlat<Doc<A>>)        => new Flattened<Doc<A>>(DocAnn.Cat<A>(x1, DocB)),\n                (AlreadyFlat<Doc<A>>, Flattened<Doc<A>> (var y1))        => new Flattened<Doc<A>>(DocAnn.Cat<A>(DocA, y1)),\n                _                                                        => AlreadyFlat<Doc<A>>.Default\n            };\n\n        public override Doc<A> Flatten() =>\n            DocAnn.Cat(DocA.Flatten(), DocB.Flatten());\n    }\n    \n    /// <summary>\n    /// Document indented by a number of columns\n    /// </summary>\n    public record DocNest<A>(int Indent, Doc<A> Doc) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.Nest<B>(Indent, Doc.ReAnnotate(f));\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            Doc.ChangesUponFlattening().Map(d => DocAnn.Nest<A>(Indent, d) as Doc<A>);\n\n        public override Doc<A> Flatten() =>\n            DocAnn.Nest<A>(Indent, Doc.Flatten());\n\n        public override string ToString() =>\n            $\"(nest {Indent} {Doc})\";\n    }\n    \n    /// <summary>\n    /// React on the current cursor position,\n    /// </summary>\n    public record DocColumn<A>(Func<int, Doc<A>> React) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.Column<B>(a => React(a).ReAnnotate(f));\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            new Flattened<Doc<A>>(DocAnn.Column<A>(x => React(x).Flatten()));\n\n        public override Doc<A> Flatten() =>\n            DocAnn.Column<A>(x => React(x).Flatten());\n    }\n    \n    /// <summary>\n    /// React on the document's page width\n    /// </summary>\n    public record DocPageWidth<A>(Func<PageWidth, Doc<A>> React) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.PageWidth<B>(a => React(a).ReAnnotate(f));\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            new Flattened<Doc<A>>(DocAnn.PageWidth<A>(x => React(x).Flatten()));\n\n        public override Doc<A> Flatten() =>\n            DocAnn.PageWidth<A>(x => React(x).Flatten());\n    }\n    \n    /// <summary>\n    /// React on the current nesting level\n    /// </summary>\n    public record DocNesting<A>(Func<int, Doc<A>> React) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.Nesting<B>(a => React(a).ReAnnotate(f));\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            new Flattened<Doc<A>>(DocAnn.Nesting<A>(x => React(x).Flatten()));\n\n        public override Doc<A> Flatten() =>\n            DocAnn.Nesting<A>(x => React(x).Flatten());\n    }\n    \n    /// <summary>\n    /// dd an annotation to the enclosed 'Doc'. Can be used for example to add\n    /// styling directives or alt texts that can then be used by the renderer.\n    /// </summary>\n    public record DocAnnotate<A>(A Annotation, Doc<A> Doc) : Doc<A>\n    {\n        public override Doc<B> ReAnnotate<B>(Func<A, B> f) =>\n            DocAnn.Annotate<B>(f(Annotation), Doc.ReAnnotate(f));\n\n        public override FlattenResult<Doc<A>> ChangesUponFlattening() =>\n            Doc.ChangesUponFlattening().Map(d => DocAnn.Annotate<A>(Annotation, Doc) as Doc<A>);\n\n        public override Doc<A> Flatten() =>\n            DocAnn.Annotate<A>(Annotation, Doc.Flatten());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/FastSpace.cs",
    "content": "using System.Text;\n\nnamespace LanguageExt.Pretty\n{\n    internal class FastSpace\n    {\n        public static string Show(int n) =>\n            (n < 0 ? 0 : n) switch\n            {\n                0 => \"\",\n                1 => \" \",\n                2 => \"  \",\n                3 => \"   \",\n                4 => \"    \",\n                5 => \"     \",\n                6 => \"      \",\n                7 => \"       \",\n                8 => \"        \",\n                _ => FastSpaceInternal(n - 8)\n            };\n\n        static string FastSpaceInternal(int x)\n        {\n            var sb = new StringBuilder();\n            sb.Append(\"        \");\n            for (var i = 0; i < x; i++)\n            {\n                sb.Append(' ');\n            }\n            return sb.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/FittingPredicate.cs",
    "content": "using System;\n\nnamespace LanguageExt.Pretty\n{\n    /// <summary>\n    /// FittingPredicate  \n    /// </summary>\n    /// <remarks>\n    ///\n    ///     FP: PageWidth, Nesting Level, Width for fist line (None is unbounded(\n    /// \n    /// </remarks>\n    public record FittingPredicate<A>(Func<PageWidth, int, Option<int>, DocStream<A>, bool> FP);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/FlattenResult.cs",
    "content": "using System;\n\nnamespace LanguageExt.Pretty\n{\n    public abstract record FlattenResult<A>\n    {\n        public abstract FlattenResult<B> Map<B>(Func<A, B> f);\n        public FlattenResult<B> Select<B>(Func<A, B> f) => Map(f);\n    }\n\n    public record Flattened<A>(A Value) : FlattenResult<A>\n    {\n        public override FlattenResult<B> Map<B>(Func<A, B> f) =>\n            new Flattened<B>(f(Value));\n    }\n\n    public record AlreadyFlat<A> : FlattenResult<A>\n    {\n        public static readonly FlattenResult<A> Default = new AlreadyFlat<A>();\n        \n        public override FlattenResult<B> Map<B>(Func<A, B> f) =>\n            AlreadyFlat<B>.Default;\n    }\n        \n    public record NeverFlat<A> : FlattenResult<A>\n    {\n        public static readonly FlattenResult<A> Default = new NeverFlat<A>();\n        \n        public override FlattenResult<B> Map<B>(Func<A, B> f) =>\n            NeverFlat<B>.Default;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/Layout.cs",
    "content": "#nullable enable\nusing System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pretty\n{\n    public static class Layout\n    {\n        public static DocStream<A> pretty<A>(LayoutOptions options, Doc<A> doc)\n        {\n            return layout(new FittingPredicate<A>(static (p, m, w, d) => go(w, d)), options, doc);\n\n            static bool go(Option<int> mx, DocStream<A> doc)\n            {\n                while (true)\n                {\n                    switch ((mx.Case, doc))\n                    {\n                        case (null, _):\n                            return true;\n\n                        case (int w, _) when w < 0:\n                            return false;\n\n                        case (_, SFail<A>):\n                            return false;\n\n                        case (_, SEmpty<A>):\n                            return false;\n\n                        case (int w, SChar<A> (_, var x)):\n                            mx = Some(w - 1);\n                            doc = x;\n                            break;\n                        \n                        case (int w, SText<A> (var t, var x)):\n                            mx  = Some(w - t.Length);\n                            doc = x;\n                            break;\n                            \n                        case (_, SLine<A>):\n                            return true;\n                            \n                        case (int w, SAnnPush<A> (_, var x)):\n                            mx = Some(w);\n                            doc = x;\n                            break;\n                        \n                        case (int w, SAnnPop<A> (var x)):\n                            mx  = Some(w);\n                            doc = x;\n                            break;\n                        \n                        default: throw new NotSupportedException();\n                    }\n                }\n            }\n        }\n        \n        public static DocStream<A> smart<A>(LayoutOptions options, Doc<A> doc)\n        {\n            return layout(new FittingPredicate<A>(go), options, doc);\n\n            static bool go(PageWidth pageWidth, int minNest, Option<int> mx, DocStream<A> doc)\n            {\n                while (true)\n                {\n                    switch ((pageWidth, minNest, mx.Case, doc))\n                    {\n                        case (_, _, null, _):\n                            return false;\n\n                        case (_, _, int w, _) when w < 0:\n                            return false;\n\n                        case (_, _, _, SFail<A>):\n                            return false;\n\n                        case (_, _, _, SEmpty<A>):\n                            return true;\n\n                        case (var pw, var m, int w, SChar<A> (_, var x)):\n                            mx  = Some(w - 1);\n                            doc = x;\n                            break;\n                        \n                        case (var pw, var m, int w, SText<A> (var t, var x)):\n                            mx  = Some(w - t.Length);\n                            doc = x;\n                            break;\n                            \n                        case (AvailablePerLine (var cpl, _), var m, _, SLine<A>(var i, var x)) when m < i :\n                            mx  = Some(cpl - i);\n                            doc = x;\n                            break;\n                            \n                        case (_, _, _, SLine<A>):\n                            return true;\n                            \n                        case (var pw, var m, int w, SAnnPush<A> (_, var x)):\n                            mx  = Some(w);\n                            doc = x;\n                            break;\n                        \n                        case (var pw, var m, int w, SAnnPop<A> (var x)):\n                            mx  = Some(w);\n                            doc = x;\n                            break;\n                        \n                        default: throw new NotSupportedException();\n                    }\n                }\n            }\n        }\n        \n        public static DocStream<A> layout<A>(\n            FittingPredicate<A> fittingPredicate,\n            LayoutOptions options,\n            Doc<A> doc)\n        {\n            return best(0, 0, new Cons<A>(0, doc, Nil<A>.Default));\n\n            DocStream<A> best(int nest, int col, LayoutPipeline<A> pipeline) =>\n                (nest, col, pipeline) switch\n                {\n                    (_, _, Nil<A>)                        => SEmpty<A>.Default,\n                    (var nl, var cc, UndoAnn<A> (var ds)) => new SAnnPop<A>(best(nl, cc, ds)),\n                    (var nl, var cc, Cons<A> (var i, var d, var ds)) =>\n                        d switch\n                        {\n                            DocFail<A>                     => SFail<A>.Default,\n                            DocEmpty<A>                    => best(nl, cc, ds),\n                            DocChar<A> (var c)             => new SChar<A>(c, best(nl, cc + 1, ds)),\n                            DocText<A> (var t)             => new SText<A>(t, best(nl, cc + t.Length, ds)),\n                            DocLine<A>                     => new SLine<A>(i, best(i, i, ds)),\n                            DocFlatAlt<A>(var x, _)        => best(nl, cc, new Cons<A>(i, x, ds)),\n                            DocCat<A>(var x, var y)        => best(nl, cc, new Cons<A>(i, x, new Cons<A>(i, y, ds))),\n                            DocNest<A>(var j, var x)       => best(nl, cc, new Cons<A>(i + j, x, ds)),\n                            DocUnion<A>(var x, var y)      => selectNicer(fittingPredicate, nl, cc, best(nl, cc, new Cons<A>(i, x, ds)), best(nl, cc, new Cons<A>(i, y, ds))),\n                            DocColumn<A>(var f)            => best(nl, cc, new Cons<A>(i, f(cc), ds)),\n                            DocPageWidth<A>(var f)         => best(nl, cc, new Cons<A>(i, f(options.PageWidth), ds)),\n                            DocNesting<A>(var f)           => best(nl, cc, new Cons<A>(i, f(i), ds)),\n                            DocAnnotate<A>(var ann, var x) => new SAnnPush<A>(ann, best(nl, cc, new Cons<A>(i, x, new UndoAnn<A>(ds)))),\n                            _                              => throw new NotSupportedException()\n                        },\n                    _ => throw new NotSupportedException()\n                };\n\n            DocStream<A> selectNicer(FittingPredicate<A> fits, int lineIndent, int currentColumn, DocStream<A> x, DocStream<A> y)\n            {\n                var minNestingLevel = Math.Min(lineIndent, currentColumn);\n                var ribbonWidth = options.PageWidth switch\n                                  {\n                                      AvailablePerLine (var lineLength, var ribbonFraction) =>\n                                          Some(Math.Max(0, Math.Min(lineLength, (int) (((double) lineLength) * ribbonFraction)))),\n                                      Unbounded => None,\n                                      _         => throw new NotSupportedException()\n                                  };\n                var availableWidth = from columnsLeftInLine in options.PageWidth switch\n                                                               {\n                                                                   AvailablePerLine(var cpl, var ribbonFrac) => Some(cpl - currentColumn),\n                                                                   Unbounded                                 => None, _ => throw new NotSupportedException()\n                                                               }\n                                     from columnsLeftInRibbon in from li in Some(lineIndent)\n                                                                 from rw in ribbonWidth\n                                                                 from cc in Some(currentColumn)\n                                                                 select li + rw - cc\n                                     select Math.Min(columnsLeftInLine, columnsLeftInRibbon);\n\n                return fits.FP(options.PageWidth, minNestingLevel, availableWidth, x)\n                           ? x\n                           : y;\n            }\n        }\n    }\n}\n#nullable disable\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/LayoutOptions.cs",
    "content": "using System;\nusing System.Text;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pretty\n{\n    public record LayoutOptions(PageWidth PageWidth)\n    {\n        public static readonly LayoutOptions Default = new LayoutOptions(PageWidth.Default);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/LayoutPipeline.cs",
    "content": "namespace LanguageExt.Pretty\n{\n    /// <summary>\n    /// List of nesting level/document pairs yet to be laid out.\n    /// </summary>\n    public abstract record LayoutPipeline<A>;\n\n    public record Nil<A> : LayoutPipeline<A>\n    {\n        public static readonly LayoutPipeline<A> Default = new Nil<A>();\n    }\n\n    public record Cons<A>(int Value, Doc<A> Doc, LayoutPipeline<A> Pipeline): LayoutPipeline<A>;\n    public record UndoAnn<A>(LayoutPipeline<A> Pipeline): LayoutPipeline<A>;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Pretty/PageWidth.cs",
    "content": "using System;\nusing System.Text;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pretty\n{\n    public abstract record PageWidth\n    {\n        public static readonly PageWidth Default = new AvailablePerLine();\n    }\n\n    /// <summary>\n    ///  - The 'Int' is the number of characters, including whitespace, that\n    ///    fit in a line. A typical value is 80.\n    ///\n    ///  - The 'Double' is the ribbon with, i.e. the fraction of the total\n    ///    page width that can be printed on. This allows limiting the length\n    ///    of printable text per line. Values must be between 0 and 1, and\n    ///    0.4 to 1 is typical.\n    /// </summary>\n    public record AvailablePerLine(int LineLength = 120, double RibbonFraction = 0.4) : PageWidth;\n    public record Unbounded() : PageWidth;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prism/Prelude_Prism.cs",
    "content": "﻿namespace LanguageExt\n{\n    public static partial class Prelude\n    {\n        /// <summary>\n        /// Convert a lens to a prism\n        /// </summary>\n        public static Prism<A, B> prism<A, B>(Lens<A, B> la) =>\n            Prism<A, B>.New(la);\n\n        /// <summary>\n        /// Convert a lens to a prism\n        /// </summary>\n        public static Prism<A, B> prism<A, B>(Lens<A, Option<B>> la) => \n            Prism<A, B>.New(la);\n\n        /// <summary>\n        /// Sequentially composes two prisms\n        /// </summary>\n        public static Prism<A, C> prism<A, B, C>(Prism<A, B> pa, Prism<B, C> pb) => \n            Prism<A, C>.New(\n                Get: a => pa.Get(a).Bind(pb.Get),\n                Set: v => pa.Update(pb.SetF(v)));\n\n        /// <summary>\n        /// Sequentially composes three prisms\n        /// </summary>\n        public static Prism<A, D> prism<A, B, C, D>(Prism<A, B> pa, Prism<B, C> pb, Prism<C, D> pc) =>\n            Prism<A, D>.New(\n                Get: a => pa.Get(a).Bind(pb.Get).Bind(pc.Get),\n                Set: v => pa.Update(pb.Update(pc.SetF(v))));\n\n        /// <summary>\n        /// Sequentially composes four prisms\n        /// </summary>\n        public static Prism<A, E> prism<A, B, C, D, E>(Prism<A, B> pa, Prism<B, C> pb, Prism<C, D> pc, Prism<D, E> pd) =>\n            Prism<A, E>.New(\n                Get: a => pa.Get(a).Bind(pb.Get).Bind(pc.Get).Bind(pd.Get),\n                Set: v => pa.Update(pb.Update(pc.Update(pd.SetF(v)))));\n\n        /// <summary>\n        /// Sequentially composes five prisms\n        /// </summary>\n        public static Prism<A, F> prism<A, B, C, D, E, F>(Prism<A, B> pa, Prism<B, C> pb, Prism<C, D> pc, Prism<D, E> pd, Prism<E, F> pe) =>\n            Prism<A, F>.New(\n                Get: a => pa.Get(a).Bind(pb.Get).Bind(pc.Get).Bind(pd.Get).Bind(pe.Get),\n                Set: v => pa.Update(pb.Update(pc.Update(pd.Update(pe.SetF(v))))));\n\n        /// <summary>\n        /// Sequentially composes six prisms\n        /// </summary>\n        public static Prism<A, G> prism<A, B, C, D, E, F, G>(Prism<A, B> pa, Prism<B, C> pb, Prism<C, D> pc, Prism<D, E> pd, Prism<E, F> pe, Prism<F, G> pf) =>\n            Prism<A, G>.New(\n                Get: a => pa.Get(a).Bind(pb.Get).Bind(pc.Get).Bind(pd.Get).Bind(pe.Get).Bind(pf.Get),\n                Set: v => pa.Update(pb.Update(pc.Update(pd.Update(pe.Update(pf.SetF(v)))))));\n\n        /// <summary>\n        /// Sequentially composes seven prisms\n        /// </summary>\n        public static Prism<A, H> prism<A, B, C, D, E, F, G, H>(Prism<A, B> pa, Prism<B, C> pb, Prism<C, D> pc, Prism<D, E> pd, Prism<E, F> pe, Prism<F, G> pf, Prism<G, H> pg) =>\n            Prism<A, H>.New(\n                Get: a => pa.Get(a).Bind(pb.Get).Bind(pc.Get).Bind(pd.Get).Bind(pe.Get).Bind(pf.Get).Bind(pg.Get),\n                Set: v => pa.Update(pb.Update(pc.Update(pd.Update(pe.Update(pf.Update(pg.SetF(v))))))));\n\n        /// <summary>\n        /// Sequentially composes eight prisms\n        /// </summary>\n        public static Prism<A, I> prism<A, B, C, D, E, F, G, H, I>(Prism<A, B> pa, Prism<B, C> pb, Prism<C, D> pc, Prism<D, E> pd, Prism<E, F> pe, Prism<F, G> pf, Prism<G, H> pg, Prism<H, I> ph) =>\n            Prism<A, I>.New(\n                Get: a => pa.Get(a).Bind(pb.Get).Bind(pc.Get).Bind(pd.Get).Bind(pe.Get).Bind(pf.Get).Bind(pg.Get).Bind(ph.Get),\n                Set: v => pa.Update(pb.Update(pc.Update(pd.Update(pe.Update(pf.Update(pg.Update(ph.SetF(v)))))))));\n\n        /// <summary>\n        /// Sequentially composes nine prisms\n        /// </summary>\n        public static Prism<A, J> prism<A, B, C, D, E, F, G, H, I, J>(Prism<A, B> pa, Prism<B, C> pb, Prism<C, D> pc, Prism<D, E> pd, Prism<E, F> pe, Prism<F, G> pf, Prism<G, H> pg, Prism<H, I> ph, Prism<I, J> pi) =>\n            Prism<A, J>.New(\n                Get: a => pa.Get(a).Bind(pb.Get).Bind(pc.Get).Bind(pd.Get).Bind(pe.Get).Bind(pf.Get).Bind(pg.Get).Bind(ph.Get).Bind(pi.Get),\n                Set: v => pa.Update(pb.Update(pc.Update(pd.Update(pe.Update(pf.Update(pg.Update(ph.Update(pi.SetF(v))))))))));\n\n        /// <summary>\n        /// Sequentially composes ten prisms\n        /// </summary>\n        public static Prism<A, K> prism<A, B, C, D, E, F, G, H, I, J, K>(Prism<A, B> pa, Prism<B, C> pb, Prism<C, D> pc, Prism<D, E> pd, Prism<E, F> pe, Prism<F, G> pf, Prism<G, H> pg, Prism<H, I> ph, Prism<I, J> pi, Prism<J, K> pj) =>\n            Prism<A, K>.New(\n                Get: a => pa.Get(a).Bind(pb.Get).Bind(pc.Get).Bind(pd.Get).Bind(pe.Get).Bind(pf.Get).Bind(pg.Get).Bind(ph.Get).Bind(pi.Get).Bind(pj.Get),\n                Set: v => pa.Update(pb.Update(pc.Update(pd.Update(pe.Update(pf.Update(pg.Update(ph.Update(pi.Update(pj.SetF(v)))))))))));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prism/Prism.cs",
    "content": "﻿namespace LanguageExt\n{\n    public static class Prism\n    {\n        /// <summary>\n        /// Identity lens\n        /// </summary>\n        public static Prism<A, A> identity<A>() =>\n            Prism<A, A>.New(\n                Get: a => a,\n                Set: a => _ => a);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prism/PrismAB.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Primitive prism type for creating transformations through Options\n    /// </summary>\n    public readonly struct Prism<A, B>\n    {\n        public readonly Func<A, Option<B>> Get;\n        public readonly Func<B, Func<A, A>> SetF;\n\n        private Prism(Func<A, Option<B>> get, Func<B, Func<A, A>> set)\n        {\n            Get = get;\n            SetF = set;\n        }\n\n        public A Set(B value, A cont)\n            => SetF(value)(cont);\n\n        public static Prism<A, B> New(Func<A, Option<B>> Get,\n                                      Func<B, Func<A, A>> Set)\n            => new Prism<A, B>(Get, Set);\n\n        public static Prism<A, B> New(Lens<A, B> lens) =>\n            Prism<A, B>.New(\n                Get: a => lens.Get(a),\n                Set: v => lens.SetF(v)\n            );\n\n        public static Prism<A, B> New(Lens<A, Option<B>> lens) =>\n            Prism<A, B>.New(\n                Get: a => lens.Get(a),\n                Set: v => lens.SetF(v)\n            );\n\n        public Func<A, A> Update(Func<B, B> f)\n        {\n            var self = this;\n            return a => self.Get(a)\n                            .Map(v => self.Set(f(v), a))\n                            .IfNone(a);\n        }\n\n        public A Update(Func<B, B> f, A value)\n        {\n            var self = this;\n            return Get(value).Map(v => self.Set(f(v), value))\n                             .IfNone(value);\n        }\n\n        /// <summary>\n        /// Implicit conversion operator from Lens〈A, B〉 to Prism〈A, B〉\n        /// </summary>\n        /// <param name=\"value\">Value</param>\n        [Pure]\n        public static implicit operator Prism<A, B>(Lens<A, B> value) => \n            New(value);\n\n        /// <summary>\n        /// Implicit conversion operator from Option〈A〉 to Result〈A〉\n        /// </summary>\n        /// <param name=\"value\">Value</param>\n        [Pure]\n        public static implicit operator Prism<A, B>(Lens<A, Option<B>> value) => \n            New(value);\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Prism/README.md",
    "content": "Prisms are lenses that allow you to look inside a structure to access its value and \nthen subsequently update that value.  But because we don't want to do mutation, the \nupdaters create new versions of the underlying structure.\n\nThe difference between lenses and prisms is that a prism returns an optional value for\nits getter.  \n"
  },
  {
    "path": "LanguageExt.Core/README.md",
    "content": "If you're new to this library, you may need a few pointers of where to look for features:\n\n  * [`Prelude`](Prelude) is a \n    `static partial class`, this type is loaded with functions for constructing the key data types, as well \n    as many of the things you'd expect in a functional programming language's prelude.  Note, the `Prelude` type\n    extends into many other parts of the source-tree.  It's the same type, but spread all over the code-base.\n    And so, you may see `Prelude` in other areas of the documentation: it's the same type.\n    \n    Because it's so fundamental, you'll want to add this to the top of every code file (or in your global usings):\n\n        using static LanguageExt.Prelude;\n  \n    This makes all functions in the `Prelude` available as though they were local.\n  * [`Traits`](Traits) are the powerhouse of this library and allow for true higher-kinded abstract behviours to be leveraged throughout.  The topic of traits is huge, so if you're looking for an introduction, take a look at [Paul Louth's Higher Kinds series on his blog](https://paullouth.com/higher-kinds-in-c-with-language-ext/).\n  * [`Monads`](Monads) contains the common monads like `Option<A>` and `Either<L, R>`, as well as state-managing monads like `Reader`, `Writer`, and `State`.  It also is home to many monad-transformers (types with a `T` suffix, like `OptionT`).  Transformers allow 'stacking' of monadic effects into 'super monads'.\n  * [`Immutable Collections`](Immutable%20Collections) contains the high-performance functional collection types this library is famous for.\n  * [`Effects`](Effects) is where the pure IO functionality of language-ext resides.  It is also where you'll find \n    the `StreamT` for 'effectful' streaming.  To understand more about how to deal with side-effects, \n    [check the wiki](https://github.com/louthy/language-ext/wiki/How-to-deal-with-side-effects).\n  * [`Concurrency`](Concurrency) is where you'll find lots of help in atomically managing shared data without locks. \n  \n  \n"
  },
  {
    "path": "LanguageExt.Core/README.nuget.md",
    "content": "# LanguageExt.Core\n\n`LanguageExt.Core` is the primary library in the [language-ext functional programming framework](https://github.com/louthy/language-ext).\n\nThe framework uses and abuses the features of C# to provide a pure functional-programming \n'Base Class Library' that, if you squint, can look like extensions to the language itself. \nThe desire here is to make programming in C# much more robust by helping the engineer's \ninertia flow in the direction of declarative and pure functional code rather than imperative. \n\nUsing these techniques for large code-bases can bring tangible benefits to long-term maintenance \nby removing hidden complexity and by easing the engineer's cognitive load.\n\n## Features\n\n### [Functional effects and IO](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/index.html)\n\n| Location | Feature      | Description                                                                                                                                                                                              |\n|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `IO<A>`      | [A synchronous and asynchronous side-effect: an IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/IO/index.html)                                                                  |\n| `Core`   | `Eff<A>`     | [A synchronous and asynchronous side-effect with error handling](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20no%20runtime/index.html)                                       |\n| `Core`   | `Eff<RT, A>` | [Same as `Eff<A>` but with an injectable runtime for dependency-injection: a unit testable IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20with%20runtime/index.html) |\n| `Core`   | Pipes        | [A clean and powerful stream processing system that lets you build and connect reusable streaming components](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Pipes/index.html)           |\n| `Core`   | StreamT      | [less powerful (than Pipes), but easier to use streaming effects transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/StreamT/index.html)                                         |\n\n### [Atomic concurrency and collections](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/index.html)\n\n| Location | Feature                            | Description                                                                                                                                            |\n|----------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Atom<A>`                          | [A lock-free atomically mutable reference for working with shared state](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/Atom)      |\n| `Core`   | `Ref<A>`                           | [An atomic reference to be used in the transactional memory system](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/STM)            |\n| `Core`   | `AtomHashMap<K, V>`                | [An immutable `HashMap` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomHashMap) |\n| `Core`   | `AtomSeq<A>`                       | [An immutable `Seq` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomSeq)         |\n| `Core`   | `VectorClock<A>`                   | [Understand distributed causality](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VectorClock)                                     |\n| `Core`   | `VersionVector<A>`                 | [A vector clock with some versioned data](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionVector)                            |\n| `Core`   | `VersionHashMap <ConflictV, K, V>` | [Distrubuted atomic versioning of keys in a hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionHashMap)               |\n\n### [Immutable collections](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/index.html)\n\n| Location | Feature              | Description                                                                                                                                                                                                             |\n|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Arr<A>`             | [Immutable array](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Arr/index.html)                                                                                                        |\n| `Core`   | `Seq<A>`             | [Lazy immutable list, evaluate at-most-once](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Seq/index.html) - very, very fast!                                                          |\n| `Core`   | `Iterable<A>`        | [Wrapper around `IEnumerable` with support for traits](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Iterable/index.html) - enables the higher-kinded traits to work with enumerables. |\n| `Core`   | `Lst<A>`             | [Immutable list](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/List/index.html) - use `Seq` over `Lst` unless you need `InsertAt`                                                      |\n| `Core`   | `Map<K, V>`          | [Immutable map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                                                          |\n| `Core`   | `Map<OrdK, K, V>`    | [Immutable map with Ord constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                               |\n| `Core`   | `HashMap<K, V>`      | [Immutable hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                                                 |\n| `Core`   | `HashMap<EqK, K, V>` | [Immutable hash-map with Eq constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                       |\n| `Core`   | `Set<A>`             | [Immutable set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                                                          |\n| `Core`   | `Set<OrdA, A>`       | [Immutable set with Ord constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                               |\n| `Core`   | `HashSet<A>`         | [Immutable hash-set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                                                 |\n| `Core`   | `HashSet<EqA, A>`    | [Immutable hash-set with Eq constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                       |\n| `Core`   | `Que<A>`             | [Immutable queue](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Queue/index.html)                                                                                                      |\n| `Core`   | `Stck<A>`            | [Immutable stack](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Stack/index.html)                                                                                                      |\n\n### [Optional and alternative value monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/index.html)\n\n| Location | Feature                         | Description                                                                                                                                                                                              |\n|----------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Option<A>`                     | [Option monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Option/index.html)                                                                                     |\n| `Core`   | `OptionT<M, A>`                 | [Option monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/OptionT/index.html)                                                                        |\n| `Core`   | `Either<L,R>`                   | [Right/Left choice monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Either/index.html)                                                                          |\n| `Core`   | `EitherT<L, M, R>`              | [Right/Left choice monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/EitherT/index.html)                                                             |\n| `Core`   | `Fin<A>`                        | [`Error` handling monad, like `Either<Error, A>`](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Fin/index.html)                                                     |\n| `Core`   | `FinT<M, A>`                    | [`Error` handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/FinT/index.html)                                                                 |\n| `Core`   | `Try<A>`                        | [Exception handling monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Try/index.html)                                                                            |\n| `Core`   | `TryT<M, A>`                    | [Exception handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/TryT/index.html)                                                               |\n| `Core`   | `Validation<FAIL ,SUCCESS>`     | [Validation applicative and monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Validation/index.html) for collecting multiple errors before aborting an operation |\n| `Core`   | `ValidationT<FAIL, M, SUCCESS>` | [Validation applicative and monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/ValidationT/index.html)                                                |\n\n### [State managing monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/index.html)\n\n| Location | Feature            | Description                                                                                                                                                                             |\n|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Reader<E, A>`     | [Reader monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/Reader/index.html)                                               |\n| `Core`   | `ReaderT<E, M, A>` | [Reader monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/ReaderT/index.html)                                  |\n| `Core`   | `Writer<W, A>`     | [Writer monad that logs to a `W` constrained to be a Monoid](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/Writer/index.html) |\n| `Core`   | `WriterT<W, M, A>` | [Writer monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/WriterT/index.html)                                  |\n| `Core`   | `State<S, A>`      | [State monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/State/index.html)                                                  |\n| `Core`   | `StateT<S, M, A>`  | [State monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/StateT/index.html)                                     |\n\n### [Parser combinators](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)\n\n| Location | Feature        | Description                                                                                                                    |\n|----------|----------------|--------------------------------------------------------------------------------------------------------------------------------|\n| `Parsec` | `Parser<A>`    | [String parser monad and full parser combinators library](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html) |\n| `Parsec` | `Parser<I, O>` | [Parser monad that can work with any input stream type](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)   |\n\n### [Pretty](https://louthy.github.io/language-ext/LanguageExt.Core/Pretty/index.html)\n\n| Location | Feature  | Description                                      |\n|----------|----------|--------------------------------------------------|\n| `Core`   | `Doc<A>` | Produce nicely formatted text with smart layouts |\n\n### [Differencing](https://louthy.github.io/language-ext/LanguageExt.Core/DataTypes/Patch/index.html)\n\n| Location | Feature         | Description                                                                                                                                                                                                                          |\n|----------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Patch<EqA, A>` | Uses patch-theory to efficiently calculate the difference (`Patch.diff(list1, list2)`) between two collections of `A` and build a patch which can be applied (`Patch.apply(patch, list)`) to one to make the other (think git diff). |\n\n### [Traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/index.html)\n\nThe traits are major feature of `v5`+ language-ext that makes generic programming with higher-kinds a reality.  Check out Paul's [series on Higher Kinds](https://paullouth.com/higher-kinds-in-c-with-language-ext/) to get a deeper insight.\n\n| Location | Feature                                | Description                                                                                                                                                            |\n|----------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `MonoidK<F>`                       | [A monoid on applicative functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Alternative/index.html)                                               |\n| `Core`   | `Applicative<F>`                       | [Applicative functor](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Applicative/index.html)                                                            |\n| `Core`   | `Eq<A>`                                | [Ad-hoc equality trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Eq/index.html)                                                                   |\n| `Core`   | `Fallible<F>`                          | [Trait that describes types that can fail](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Fallible/index.html)                                          |\n| `Core`   | `Foldable<T>`                          | [Aggregation over a structure](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Foldable/index.html)                                                      |\n| `Core`   | `Functor<F>`                           | [Functor `Map`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Functor/index.html)                                                                      |\n| `Core`   | `Has<M, TRAIT>`                        | [Used in runtimes to enable DI-like capabilities](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Has/index.html)                                        |\n| `Core`   | `Hashable<A>`                          | [Ad-hoc has-a-hash-code trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Hashable/index.html)                                                      |\n| `Core`   | `Local<M, E>`                          | [Creates a local environment to run a computation ](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Local/index.html)                                    |\n| `Core`   | `Monad<M>`                             | [Monad trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/Monad/index.html)                                                                   |\n| `Core`   | `MonadT<M, N>`                         | [Monad transformer trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/MonadT/index.html)                                                      |\n| `Core`   | `Monoid<A>`                            | [A monoid is a type with an identity `Empty` and an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monoid/index.html) |\n| `Core`   | `MonoidK<M>`                           | [Equivalent of monoids for working on higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/MonoidK/index.html)                           |\n| `Core`   | `Mutates<M, OUTER_STATE, INNER_STATE>` | [Used in runtimes to enable stateful operations](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Mutates/index.html)                                     |\n| `Core`   | `Ord<A>`                               | [Ad-hoc ordering / comparisons](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Ord/index.html)                                                          |\n| `Core`   | `Range<SELF, NumOrdA, A>`              | [Abstraction of a range of values](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Range/index.html)                                                     |\n| `Core`   | `Readable<M, Env>`                     | [Generalised Reader monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Readable/index.html)                                              |\n| `Core`   | `SemigroupK<F>`                   | [A semigroup on functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                                                    |\n| `Core`   | `Semigroup<A>`                         | [Provides an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Semigroup/index.html)                                     |\n| `Core`   | `SemigroupK<M>`                        | [Equivalent of semigroups for working with higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                   |\n| `Core`   | `Stateful<M, S>`                       | [Generalised State monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Stateful/index.html)                                               |\n| `Core`   | `Traversable<T>`                       | [Traversable structures support element-wise sequencing of Applicative effects](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Traversable/index.html)  |\n| `Core`   | `Writable<M, W>`                       | [Generalised Writer monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Writable/index.html)                                              |\n\n### [Value traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Domain/index.html)\n\nThese work a little like `NewType` but they impart semantic meaning and some common operators for the underlying value.\n\n| Location | Feature                              | Description                                                                                                                                                                                                                                       |\n|----------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `DomainType<SELF, REPR>`             | Provides a mapping from `SELF` to an underlying representation: `REPR`                                                                                                                                                                            |\n| `Core`   | `Identifier <SELF>`                  | Identifiers (like IDs in databases: `PersonId` for example), they are equivalent to `DomaintType` with equality.                                                                                                                                  |\n| `Core`   | `VectorSpace<SELF, SCALAR>`          | Scalable values; can add and subtract self, but can only multiply and divide by a scalar. Can also negate.                                                                                                                                        |\n| `Core`   | `Amount <SELF, SCALAR>`              | Quantities, such as the amount of money in USD on a bank account or a file size in bytes. Derives `VectorSpace`, `IdentifierLike`, `DomainType`, and is orderable (comparable).                                                                   |\n| `Core`   | `LocusLike <SELF, SCALAR, DISTANCE>` | Works with space-like structures. Spaces have absolute and relative distances. Has an origin/zero point and derives `DomainType`, `IdentifierLike`, `AmountLike` and `VectorSpace`.  `DISTANCE` must also be an `AmountLike<SELF, REPR, SCALAR>`. |\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Alternative/Alternative.Extensions.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A monoid on applicative functors\n/// </summary>\n/// <typeparam name=\"F\">Applicative functor</typeparam>\npublic static class AlternativeExtensions\n{\n    /// <summary>\n    /// Given a set of applicative functors, return the first one to succeed.\n    /// </summary>\n    /// <remarks>\n    /// If none succeed, the last applicative functor will be returned.\n    /// </remarks>\n    public static K<F, A> OneOf<F, A>(this Seq<K<F, A>> ms)\n        where F : Alternative<F> =>\n        Alternative.choice(ms);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Alternative/Alternative.Laws.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functions that test that Alternative laws hold for the `F` Alternative provided.\n/// </summary>\n/// <para>\n///     choose(pure(a), pure(b)) = pure(a)\n///     choose(empty(), pure(b)) = pure(b)\n///     choose(pure(a), empty()) = pure(a)\n/// </para>\n/// <remarks>\n/// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n/// can be proven to be true.  If your Alternative structure doesn't have `Equals` then you\n/// must provide the optional `equals` parameter so that the equality of outcomes can be tested.\n/// </remarks>\n/// <typeparam name=\"F\">Alternative type</typeparam>\npublic static class AlternativeLaw<F>\n    where F : Alternative<F>, Applicative<F>\n{\n    /// <summary>\n    /// Assert that the Alternative laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Unit assert(Func<K<F, int>, K<F, int>, bool>? equals = null) =>\n        validate(equals)\n           .IfFail(errors => errors.Throw());\n\n    /// <summary>\n    /// Validate that the Alternative laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> validate(Func<K<F, int>, K<F, int>, bool>? equals = null)\n    {\n        equals ??= (fa, fb) => fa.Equals(fb);\n        return ApplicativeLaw<F>.validate(equals) >>\n               leftCatchLaw(equals)               >>\n               leftZeroLaw(equals)                >>\n               rightZeroLaw(equals);\n    }\n\n    /// <summary>\n    /// Left-zero law\n    /// </summary>\n    /// <remarks>\n    ///    choose(empty, pure(x)) = pure(x)\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> leftZeroLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var fa = F.Empty<int>();\n        var fb = F.Pure(100);\n        var fr = choose(fa, fb);\n\n        return equals(fr, fb) \n                   ? unit\n                   : Error.New($\"Alternative left-zero law does not hold for {typeof(F).Name}\");\n    }\n\n    /// <summary>\n    /// Right-zero law\n    /// </summary>\n    /// <remarks>\n    ///    choose(pure(x), empty) = pure(x)\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> rightZeroLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var fa = F.Pure(100);\n        var fb = F.Empty<int>();\n        var fr = choose(fa, fb);\n\n        return equals(fr, fa) \n                   ? unit\n                   : Error.New($\"Alternative right-zero law does not hold for {typeof(F).Name}\");\n    }    \n\n    /// <summary>\n    /// Left catch law\n    /// </summary>\n    /// <remarks>\n    ///    choose(pure(x), pure(y)) = pure(x)\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> leftCatchLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var fa = F.Pure(100);\n        var fb = F.Pure(200);\n        var fr = choose(fa, fb);\n\n        return equals(fr, fa) \n                   ? unit\n                   : Error.New($\"Choice left-catch law does not hold for {typeof(F).Name}\");\n    }    \n    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Alternative/Alternative.Module.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic static class Alternative\n{\n    /// <summary>\n    /// Empty / none state for the `F` structure \n    /// </summary>\n    /// <typeparam name=\"F\">Alternative trait implementation</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Empty</returns>\n    public static K<F, A> empty<F, A>()\n        where F : Alternative<F> =>\n        F.Empty<A>();\n\n    /// <summary>\n    /// Given a set of applicative functors, return the first one to succeed.\n    /// </summary>\n    /// <remarks>\n    /// If none succeed, the last applicative functor will be returned.\n    /// </remarks>\n    [Pure]\n    public static K<F, A> choice<F, A>(Seq<K<F, A>> ms)\n        where F : Alternative<F> =>\n        F.Choice(ms);\n\n    /// <summary>\n    /// Given a set of applicative functors, return the first one to succeed.\n    /// </summary>\n    /// <remarks>\n    /// If none succeed, the last applicative functor will be returned.\n    /// </remarks>\n    [Pure]\n    public static K<F, A> choice<F, A>(params ReadOnlySpan<K<F, A>> ms)\n        where F : Alternative<F> =>\n        F.Choice(ms);\n\n    /// <summary>\n    /// One or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    ///\n    /// Will always succeed if at least one item has been yielded.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: It is important that the `F` applicative-type overrides `Apply` (the one with `Func` laziness) in its\n    /// trait-implementations otherwise this will likely result in a stack-overflow. \n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>One or more values</returns>\n    [Pure]\n    public static K<F, Seq<A>> some<F, A>(K<F, A> fa)\n        where F : Alternative<F> =>\n        F.Some(fa);\n    \n    /// <summary>\n    /// Zero or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    /// Will always succeed.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: It is important that the `F` applicative-type overrides `ApplyLazy` in its trait-implementations\n    /// otherwise this will likely result in a stack-overflow. \n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>Zero or more values</returns>\n    [Pure]\n    public static K<F, Seq<A>> many<F, A>(K<F, A> fa)\n        where F : Alternative<F> =>\n        F.Many(fa);\n    \n    /// <summary>\n    /// `endBy(p, sep)` parses zero-or-more occurrences of `p`, separated and ended by\n    /// `sep`. Returns a list of values returned by `p`.\n    /// </summary>\n    /// <param name=\"p\">Value parser</param>\n    /// <param name=\"sep\">Separator parser</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, Seq<A>> endBy<F, A, SEP>(K<F, A> p, K<F, SEP> sep) \n        where F : Alternative<F> =>\n        F.EndBy(p, sep);\n    \n    /// <summary>\n    /// `endBy1(p, sep)` parses one-or-more occurrences of `p`, separated and ended by\n    /// `sep`. Returns a list of values returned by `p`.\n    /// </summary>\n    /// <param name=\"p\">Value parser</param>\n    /// <param name=\"sep\">Separator parser</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, Seq<A>> endBy1<F, A, SEP>(K<F, A> p, K<F, SEP> sep) \n        where F : Alternative<F> =>\n        F.EndBy1(p, sep);\n    \n    /// <summary>\n    /// Combine two alternatives\n    /// </summary>\n    /// <param name=\"ma\">Left alternative</param>\n    /// <param name=\"mb\">Right alternative</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Alternative structure with an `Either` lifted into it</returns>\n    [Pure]\n    public static K<F, Either<A, B>> either<F, A, B>(K<F, A> ma, K<F, B> mb) \n        where F : Alternative<F> =>\n        F.Either(ma, mb);\n    \n    /// <summary>\n    /// `manyUntil(fa, end)` applies `fa` _zero_ or more times until `fend` succeeds.\n    /// Returns the list of values returned by`fa`. `fend` result is consumed and\n    /// lost. Use `manyUntil2` if you wish to keep it.\n    /// </summary>\n    /// <param name=\"fa\">Structure to consume</param>\n    /// <param name=\"fend\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, Seq<A>> manyUntil<F, A, END>(K<F, A> fa, K<F, END> fend)\n        where F : Alternative<F> =>\n        F.ManyUntil(fa, fend);\n        \n    /// <summary>\n    /// `manyUntil2(fa, end)` applies `fa` _zero_ or more times until `fend` succeeds.\n    /// Returns the list of values returned by`fa` plus the `fend` result.\n    ///\n    /// Use `manyUntil` if you don't wish to keep the `end` result.\n    /// </summary>\n    /// <param name=\"fa\">Structure to consume</param>\n    /// <param name=\"fend\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, (Seq<A> Items, END End)> manyUntil2<F, A, END>(K<F, A> fa, K<F, END> fend)\n        where F : Alternative<F> =>\n        F.ManyUntil2(fa, fend);\n    \n    /// <summary>\n    /// `someUntil(fa, end)` applies `fa` _one_ or more times until `fend` succeeds.\n    /// Returns the list of values returned by`fa`. `fend` result is consumed and\n    /// lost. Use `someUntil2` if you wish to keep it.\n    /// </summary>\n    /// <param name=\"fa\">Structure to consume</param>\n    /// <param name=\"fend\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, Seq<A>> someUntil<F, A, END>(K<F, A> fa, K<F, END> fend) \n        where F : Alternative<F> =>\n        F.SomeUntil(fa, fend);\n\n    /// <summary>\n    /// `someUntil2(fa, end)` applies `fa` _one_ or more times until `fend` succeeds.\n    /// Returns the list of values returned by`fa` plus the `fend` result.\n    ///\n    /// Use `someUntil` if you don't wish to keep the `end` result.\n    /// </summary>\n    /// <param name=\"fa\">Structure to consume</param>\n    /// <param name=\"fend\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, (Seq<A> Items, END End)> someUntil2<F, A, END>(K<F, A> fa, K<F, END> fend)\n        where F : Alternative<F> =>\n        F.SomeUntil2(fa, fend);\n    \n    /// <summary>\n    /// `option(x, fa)` tries to apply `fa`. If `fa` fails without 'consuming' anything, it\n    /// returns `value`, otherwise the value returned by `fa`.\n    /// </summary>\n    /// <remarks>\n    /// The word 'consuming' is used here because this feature started life as a parser combinator, but it\n    /// can be applied to any `Alternative` structure.  Critically, most combinators only have a single flavour\n    /// of failure.  So, `option` just results in a default value being returned if `fa` fails.\n    /// </remarks>\n    /// <param name=\"value\">Default value to use if `fa` fails without 'consuming' anything</param>\n    /// <param name=\"fa\"></param>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, A> option<F, A>(A value, K<F, A> fa) \n        where F : Alternative<F> =>\n        F.Option(value, fa);\n    \n    /// <summary>\n    /// `sepBy(fa, sep) processes _zero_ or more occurrences of `fa`, separated by `sep`. \n    /// </summary>\n    /// <param name=\"fa\">Structure to yield return values</param>\n    /// <param name=\"sep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>List of values returned by `fa`</returns>\n    [Pure]\n    public static K<F, Seq<A>> sepBy<F, A, SEP>(K<F, A> fa, K<F, SEP> sep) \n        where F : Alternative<F> =>\n        F.SepBy(fa, sep);\n    \n    /// <summary>\n    /// `sepBy(fa, sep) processes _one_ or more occurrences of `fa`, separated by `sep`. \n    /// </summary>\n    /// <param name=\"fa\">Structure to yield return values</param>\n    /// <param name=\"sep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>List of values returned by `fa`</returns>\n    [Pure]\n    public static K<F, Seq<A>> sepBy1<F, A, SEP>(K<F, A> fa, K<F, SEP> sep) \n        where F : Alternative<F> =>\n        F.SepBy1(fa, sep);\n\n    /// <summary>\n    /// `sepEndBy(fa, sep) processes _zero_ or more occurrences of `fa`, separated\n    /// and optionally ended by `sep`. Returns a list of values returned by `fa`.\n    /// </summary>\n    /// <param name=\"fa\">Structure to yield return values</param>\n    /// <param name=\"sep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>List of values returned by `fa`</returns>\n    [Pure]\n    public static K<F, Seq<A>> sepByEnd<F, A, SEP>(K<F, A> fa, K<F, SEP> sep) \n        where F : Alternative<F> =>\n        F.SepByEnd(fa, sep);\n\n    /// <summary>\n    /// `sepEndBy1(fa, sep) processes _one_ or more occurrences of `fa`, separated\n    /// and optionally ended by `sep`. Returns a list of values returned by `fa`.\n    /// </summary>\n    /// <param name=\"fa\">Structure to yield return values</param>\n    /// <param name=\"sep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>List of values returned by `fa`</returns>\n    [Pure]\n    public static K<F, Seq<A>> sepByEnd1<F, A, SEP>(K<F, A> fa, K<F, SEP> sep) \n        where F : Alternative<F> =>\n        F.SepByEnd1(fa, sep);\n    \n    /// <summary>\n    /// Process `fa` _zero_ or more times and drop all yielded values.\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly until failure.\n    /// Will always succeed.\n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public static K<F, Unit> skipMany<F, A>(K<F, A> fa)\n        where F : Alternative<F> =>\n        F.SkipMany(fa);\n    \n    /// <summary>\n    /// Process `fa` _one_ or more times and drop all yielded values.\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly until failure. At least one item must be yielded for overall success.\n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public static K<F, Unit> skipSome<F, A>(K<F, A> fa) \n        where F : Alternative<F> =>\n        F.SkipSome(fa);\n\n    /// <summary>\n    /// `skip(n, fa)` processes `n` occurrences of `fa`, skipping its result.\n    /// If `n` is not positive, the process equates to `Pure(unit)`.\n    /// </summary>\n    /// <param name=\"n\">Number of occurrences of `fa` to skip</param>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, Unit> skip<F, A>(int n, K<F, A> fa) \n        where F : Alternative<F> =>\n        F.Skip(n, fa);\n\n    /// <summary>\n    /// `skipManyUntil(fa, fend)` applies the process `fa` _zero_ or more times\n    /// skipping results until process `fend` succeeds. The resulting value from\n    /// `fend` is then returned.\n    /// </summary>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, END> skipManyUntil<F, A, END>(K<F, A> fa, K<F, END> fend)\n        where F : Alternative<F> =>\n        F.SkipManyUntil(fa, fend);\n\n    /// <summary>\n    /// `skipManyUntil(fa, fend)` applies the process `fa` _one_ or more times\n    /// skipping results until process `fend` succeeds. The resulting value from\n    /// `fend` is then returned.\n    /// </summary>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, END> skipSomeUntil<F, A, END>(K<F, A> fa, K<F, END> fend) \n        where F : Alternative<F> =>\n        F.SkipSomeUntil(fa, fend);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Alternative/Alternative.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Given a set of applicative functors, return the first one to succeed.\n    /// </summary>\n    /// <remarks>\n    /// If none succeed, the last applicative functor will be returned.\n    /// </remarks>\n    [Pure]\n    public static K<F, A> oneOf<F, A>(params K<F, A>[] ms)\n        where F : Alternative<F> =>\n        Alternative.choice(ms);\n\n    /// <summary>\n    /// Given a set of applicative functors, return the first one to succeed.\n    /// </summary>\n    /// <remarks>\n    /// If none succeed, the last applicative functor will be returned.\n    /// </remarks>\n    [Pure]\n    public static K<F, A> oneOf<F, A>(Seq<K<F, A>> ms)\n        where F : Alternative<F> =>\n        Alternative.choice(ms);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Alternative/Alternative.Trait.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic interface Alternative<F> : Choice<F>, Applicative<F>\n    where F : Alternative<F>\n{\n    /// <summary>\n    /// Identity\n    /// </summary>\n    [Pure]\n    public static abstract K<F, A> Empty<A>(); \n    \n    /// <summary>\n    /// Given a set of applicative functors, return the first one to succeed.\n    /// </summary>\n    /// <remarks>\n    /// If none succeed, the last applicative functor will be returned.\n    /// </remarks>\n    [Pure]\n    public static virtual K<F, A> Choice<A>(in Seq<K<F, A>> ms)\n    {\n        if(ms.IsEmpty) return F.Empty<A>();\n        var r = ms[0];\n        foreach (var m in ms.Tail)\n        {\n            r |= m;\n        }\n        return r;\n    }\n\n    /// <summary>\n    /// Given a set of applicative functors, return the first one to succeed.\n    /// </summary>\n    /// <remarks>\n    /// If none succeed, the last applicative functor will be returned.\n    /// </remarks>\n    [Pure]\n    public static virtual K<F, A> Choice<A>(in ReadOnlySpan<K<F, A>> ms)\n    {\n        if(ms.Length == 0) return F.Empty<A>();\n        var r = ms[0];\n        foreach (var m in ms)\n        {\n            r |= m;\n        }\n        return r;\n    }\n        \n    /// <summary>\n    /// One or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    ///\n    /// Will always succeed if at least one item has been yielded.\n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>One or more values</returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> Some<A>(K<F, A> fa)\n    {\n        return some();\n        \n        K<F, Seq<A>> many() =>\n            F.Choose(some(), F.Pure(Seq<A>()));\n\n        K<F, Seq<A>> some() =>\n            Cached<A>.cons * fa * memoK(many);\n    }\n    \n    /// <summary>\n    /// Zero or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    /// Will always succeed.\n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>Zero or more values</returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> Many<A>(K<F, A> fa)\n    {\n        return many();\n        \n        K<F, Seq<A>> many() =>\n            some() | F.Pure(Seq<A>());\n\n        K<F, Seq<A>> some() =>\n            Cached<A>.cons * fa * memoK(many);\n    }\n    \n    /// <summary>\n    /// `endBy(p, sep)` parses zero-or-more occurrences of `p`, separated and ended by\n    /// `sep`. Returns a list of values returned by `p`.\n    /// </summary>\n    /// <param name=\"p\">Value parser</param>\n    /// <param name=\"sep\">Separator parser</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> EndBy<A, SEP>(K<F, A> p, K<F, SEP> sep) =>\n        F.Many(p.BackAction(sep));\n    \n    /// <summary>\n    /// `endBy1(p, sep)` parses one-or-more occurrences of `p`, separated and ended by\n    /// `sep`. Returns a list of values returned by `p`.\n    /// </summary>\n    /// <param name=\"p\">Value parser</param>\n    /// <param name=\"sep\">Separator parser</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> EndBy1<A, SEP>(K<F, A> p, K<F, SEP> sep) =>\n        F.Some(p.BackAction(sep));\n\n    /// <summary>\n    /// Combine two alternatives\n    /// </summary>\n    /// <param name=\"fa\">Left alternative</param>\n    /// <param name=\"fb\">Right alternative</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Alternative structure with an `Either` lifted into it</returns>\n    [Pure]\n    public static virtual K<F, Either<A, B>> Either<A, B>(K<F, A> fa, K<F, B> fb) =>\n        (Left<A, B>) * fa | (Right<A, B>) * fb; \n    \n    /// <summary>\n    /// `manyUntil(fa, end)` applies `fa` _zero_ or more times until `fend` succeeds.\n    /// Returns the list of values returned by`fa`. `fend` result is consumed and\n    /// lost. Use `manyUntil2` if you wish to keep it.\n    /// </summary>\n    /// <param name=\"fa\">Structure to consume</param>\n    /// <param name=\"fend\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> ManyUntil<A, END>(K<F, A> fa, K<F, END> fend)\n    {\n        var empty = Prelude.Pure(Seq<A>.Empty);\n        return go();\n\n        K<F, Seq<A>> go() =>\n            empty * fend | Applicative.lift(Seq.cons, fa, memoK(go));\n    }\n        \n    /// <summary>\n    /// `manyUntil2(fa, end)` applies `fa` _zero_ or more times until `fend` succeeds.\n    /// Returns the list of values returned by`fa` plus the `fend` result.\n    ///\n    /// Use `manyUntil` if you don't wish to keep the `end` result.\n    /// </summary>\n    /// <param name=\"fa\">Structure to consume</param>\n    /// <param name=\"fend\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, (Seq<A> Items, END End)> ManyUntil2<A, END>(K<F, A> fa, K<F, END> fend)\n    {\n        var empty = (END e) => (Seq<A>.Empty, e);\n        return go();\n\n        K<F, (Seq<A> Items, END End)> go() =>\n            empty * fend | Applicative.lift((x, p) => (x.Cons(p.Items), p.End), fa, memoK(go));\n    }\n    \n    /// <summary>\n    /// `someUntil(fa, end)` applies `fa` _one_ or more times until `fend` succeeds.\n    /// Returns the list of values returned by`fa`. `fend` result is consumed and\n    /// lost. Use `someUntil2` if you wish to keep it.\n    /// </summary>\n    /// <param name=\"fa\">Structure to consume</param>\n    /// <param name=\"fend\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> SomeUntil<A, END>(K<F, A> fa, K<F, END> fend) =>\n        Applicative.lift(Seq.cons, fa, F.ManyUntil(fa, fend));\n        \n    /// <summary>\n    /// `someUntil2(fa, end)` applies `fa` _one_ or more times until `fend` succeeds.\n    /// Returns the list of values returned by`fa` plus the `fend` result.\n    ///\n    /// Use `someUntil` if you don't wish to keep the `end` result.\n    /// </summary>\n    /// <param name=\"fa\">Structure to consume</param>\n    /// <param name=\"fend\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, (Seq<A> Items, END End)> SomeUntil2<A, END>(K<F, A> fa, K<F, END> fend) =>\n        Applicative.lift((x, p) => (x.Cons(p.Items), p.End), fa, F.ManyUntil2(fa, fend));\n    \n    /// <summary>\n    /// `option(x, fa)` tries to apply `fa`. If `fa` fails without 'consuming' anything, it\n    /// returns `value`, otherwise the value returned by `fa`.\n    /// </summary>\n    /// <remarks>\n    /// The word 'consuming' is used here because this feature started life as a parser combinator, but it\n    /// can be applied to any `Alternative` structure.  Critically, most combinators only have a single flavour\n    /// of failure.  So, `option` just results in a default value being returned if `fa` fails.\n    /// </remarks>\n    /// <param name=\"value\">Default value to use if `fa` fails without 'consuming' anything</param>\n    /// <param name=\"p\"></param>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, A> Option<A>(A value, K<F, A> fa) => \n        fa | F.Pure(value);\n    \n    /// <summary>\n    /// `sepBy(fa, sep) processes _zero_ or more occurrences of `fa`, separated by `sep`. \n    /// </summary>\n    /// <param name=\"fa\">Structure to yield return values</param>\n    /// <param name=\"fsep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>List of values returned by `fa`</returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> SepBy<A, SEP>(K<F, A> fa, K<F, SEP> sep) =>\n        F.SepBy1(fa, sep) | F.Pure(Seq<A>.Empty);\n    \n    /// <summary>\n    /// `sepBy(fa, sep) processes _one_ or more occurrences of `fa`, separated by `sep`. \n    /// </summary>\n    /// <param name=\"fa\">Structure to yield return values</param>\n    /// <param name=\"fsep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>List of values returned by `fa`</returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> SepBy1<A, SEP>(K<F, A> fa, K<F, SEP> sep) =>\n        Applicative.lift(Seq.cons, fa, F.Many(sep >>> fa));\n\n    /// <summary>\n    /// `sepEndBy(fa, sep) processes _zero_ or more occurrences of `fa`, separated\n    /// and optionally ended by `sep`. Returns a list of values returned by `fa`.\n    /// </summary>\n    /// <param name=\"fa\">Structure to yield return values</param>\n    /// <param name=\"fsep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>List of values returned by `fa`</returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> SepByEnd<A, SEP>(K<F, A> fa, K<F, SEP> sep) =>\n        F.SepByEnd1(fa, sep) | F.Pure(Seq<A>.Empty);\n\n    /// <summary>\n    /// `sepEndBy1(fa, sep) processes _one_ or more occurrences of `fa`, separated\n    /// and optionally ended by `sep`. Returns a list of values returned by `fa`.\n    /// </summary>\n    /// <param name=\"fa\">Structure to yield return values</param>\n    /// <param name=\"fsep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>List of values returned by `fa`</returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> SepByEnd1<A, SEP>(K<F, A> fa, K<F, SEP> sep) =>\n        Applicative.lift(Seq.cons, fa, sep >>> F.SepByEnd(fa, sep) | F.Pure(Seq<A>.Empty));\n    \n    /// <summary>\n    /// Process `fa` _zero_ or more times and drop all yielded values.\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly until failure.\n    /// Will always succeed.\n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public static virtual K<F, Unit> SkipMany<A>(K<F, A> fa)\n    {\n        return go();\n        K<F, Unit> go() =>\n            fa >> memoK(go) | F.Pure(unit);\n    }\n    \n    /// <summary>\n    /// Process `fa` _one_ or more times and drop all yielded values.\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly until failure. At least one item must be yielded for overall success.\n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public static virtual K<F, Unit> SkipSome<A>(K<F, A> fa) =>\n        fa >>> F.SkipMany(fa);\n\n    /// <summary>\n    /// `skip(n, fa)` processes `n` occurrences of `fa`, skipping its result.\n    /// If `n` is not positive, the process equates to `Pure(unit)`.\n    /// </summary>\n    /// <param name=\"n\">Number of occurrences of `fa` to skip</param>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, Unit> Skip<A>(int n, K<F, A> fa) =>\n        n switch\n        {\n            <= 0 => F.Pure(unit),\n            _    => Applicative.lift((_, _) => unit, fa, F.Replicate(n - 1, fa))\n        };\n\n    /// <summary>\n    /// `skipManyUntil(fa, fend)` applies the process `fa` _zero_ or more times\n    /// skipping results until process `fend` succeeds. The resulting value from\n    /// `fend` is then returned.\n    /// </summary>\n    /// <param name=\"n\">Number of occurrences of `fa` to skip</param>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, END> SkipManyUntil<A, END>(K<F, A> fa, K<F, END> fend)\n    {\n        return go();\n        K<F, END> go() =>\n            fend | fa >> memoK(go); \n    }\n\n    /// <summary>\n    /// `skipManyUntil(fa, fend)` applies the process `fa` _one_ or more times\n    /// skipping results until process `fend` succeeds. The resulting value from\n    /// `fend` is then returned.\n    /// </summary>\n    /// <param name=\"n\">Number of occurrences of `fa` to skip</param>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static virtual K<F, END> SkipSomeUntil<A, END>(K<F, A> fa, K<F, END> fend) =>\n        fa >>> F.SkipManyUntil(fa, fend);\n        \n    static class Cached<A>\n    {\n        public static readonly Func<A, Func<Seq<A>, Seq<A>>> cons =\n            static x => xs => x.Cons(xs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Alternative/README.md",
    "content": "`Alternative<F>` allows for propagation of 'failure' and 'choice' (in some appropriate sense, depending on the type),\nas well as provision of a unit/identity value (`Empty`).\n\n`Alternative` is a `Choice` and `MonoidK`, which means it has a `Choose` method, a `Combine` method (which defaults to\ncalling the `Choose` method), and an `Empty` method.  That creates a semantic meaning for `Choose`, which is about \nchoice propagation rather than the broader meaning of `SemigroupK.Combine`.  It also allows for `Choose` and `Combine` \nto have separate implementations depending on the type.\n\nThe way to think about `Choose` and the inherited `SemigroupK.Combine` methods is:\n* `Choose` is the failure/choice propagation operator: `|`\n* `Combine` is the concatenation/combination/addition operator: `+`\n\nAny type that supports the `Alternative` trait should also implement the `|` operator, to enable easy choice/failure \npropagation.  If there is a different implementation of `Combine` (rather than accepting the default), then the type \nshould also implement the `+` operator.\n\n`AlternativeLaw` can help you test your implementation:\n\n    choose(Pure(a), Pure(b)) = Pure(a)\n    choose(Empty  , Pure(b)) = Pure(b)\n    choose(Pure(a), Empty  ) = Pure(a)\n    choose(Empty  , Empty  ) = Empty\n\nIt also tests the `Applicative` and `Functor` laws."
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Act.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\npublic static class Act<A, B>\n{\n    public static readonly Func<A, Func<B, B>> fun =\n        _ => y => y;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Applicative.Laws.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functions that test that Applicative-functor laws hold for the `F` applicative-functor provided.\n/// </summary>\n/// <para>\n///  * Homomorphism\n///  * Identity\n///  * Interchange\n///  * Applicative-Functor\n///  * Composition\n/// </para>\n/// <remarks>\n/// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n/// can be proven to be true.  If your applicative-functor doesn't have `Equals` then you must provide\n/// the optional `equals` parameter so that the equality of outcomes can be tested.\n/// </remarks>\n/// <typeparam name=\"F\">Applicative functor type</typeparam>\npublic static class ApplicativeLaw<F>\n    where F : Applicative<F>\n{\n    /// <summary>\n    /// Assert that the applicative-functor laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your applicative-functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Unit assert(Func<K<F, int>, K<F, int>, bool>? equals = null) =>\n        validate(equals)\n           .IfFail(errors => errors.Throw());\n\n    /// <summary>\n    /// Validate that the applicative-functor laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your applicative-functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> validate(Func<K<F, int>, K<F, int>, bool>? equals = null)\n    {\n        equals ??= (fa, fb) => fa.Equals(fb);\n        var fa = F.Pure(1);\n        return FunctorLaw<F>.validate(fa, equals) >>\n               homomorphismLaw(equals)            >>\n               interchangeLaw(equals)             >>\n               compositionLaw(equals)             >>\n               functorLaw(equals)                 >>\n               identityLaw(equals);\n    }\n\n    /// <summary>\n    /// Validate the homomorphism law\n    /// </summary>\n    /// <remarks>\n    /// Homomorphism\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your applicative-functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> homomorphismLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var f  = (int x) => x * 2;\n        var a  = 100;\n        \n        var ff = F.Pure(f);\n        var fa = F.Pure(a);\n\n        var lhs = ff.Apply(fa);\n        var rhs = F.Pure(f(a));\n        \n        return equals(lhs, rhs) \n                   ? unit\n                   : Error.New($\"Applicative homomorphism law does not hold for {typeof(F).Name}\");\n    }\n    \n    /// <summary>\n    /// Validate the interchange law\n    /// </summary>\n    /// <remarks>\n    /// Interchange\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your applicative-functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> interchangeLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var ap = (int x) => (Func<int, int> f) => f(x);\n        \n        var f = (int x) => x * 2;\n        var a = 100;\n        \n        var ff = F.Pure(f);\n        var fa = F.Pure(a);\n\n        var lhs = ff.Apply(fa);\n        var rhs = F.Pure(ap(a)).Apply(ff);\n        \n        return equals(lhs, rhs) \n                   ? unit\n                   : Error.New($\"Applicative interchange law does not hold for {typeof(F).Name}\");\n    }\n\n    /// <summary>\n    /// Validate the identity law\n    /// </summary>\n    /// <remarks>\n    /// Identity\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your applicative-functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> identityLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var lhs = F.Pure(100);\n        var rhs = F.Pure<Func<int, int>>(identity).Apply(lhs);\n        \n        return equals(lhs, rhs) \n                   ? unit\n                   : Error.New($\"Applicative identity law does not hold for {typeof(F).Name}\");\n    }\n\n    /// <summary>\n    /// Validate the composition law\n    /// </summary>\n    /// <remarks>\n    /// Composition\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> compositionLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        // (b -> c) -> (a -> b) -> a -> c\n        Func<Func<int, int>, Func<Func<int, int>, Func<int, int>>> compose = \n            g => f => a => g(f(a));\n\n        var xs = F.Pure(10);\n        var us = F.Pure((int x) => x + 1);\n        var vs = F.Pure((int x) => x * 2);\n\n        var lhs = compose.Map(us).Apply(vs).Apply(xs); \n        var rhs = us.Apply(vs.Apply(xs));\n        \n        return equals(lhs, rhs)\n                   ? unit\n                   : Error.New($\"Applicative composition law does not hold for {typeof(F).Name}\");\n    }\n\n    /// <summary>\n    /// Validate the functor law\n    /// </summary>\n    /// <remarks>\n    /// Applicative-Functor\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> functorLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var g = (int x) => x * 1;\n        var x = F.Pure(10);\n\n        var lhs = g.Map(x);\n        var rhs = F.Pure(g).Apply(x);\n        \n        return equals(lhs, rhs)\n                   ? unit\n                   : Error.New($\"Applicative functor law does not hold for {typeof(F).Name}\");\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Applicative.Trait.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Applicative functor \n/// </summary>\n/// <typeparam name=\"F\">Functor trait type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic interface Applicative<F> : Functor<F>\n    where F : Applicative<F>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Abstract members\n    //\n    \n    /// <summary>\n    /// Lift a pure value into the applicative structure\n    /// </summary>\n    /// <param name=\"value\">Value to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed applicative structure</returns>\n    [Pure]\n    public static abstract K<F, A> Pure<A>(A value);\n    \n    /// <summary>\n    /// Apply the function to the argument.\n    /// </summary>\n    /// <remarks>\n    /// This is like `delegate.Invoke` for lifted functions and lifted arguments.\n    /// </remarks>\n    /// <param name=\"mf\">Lifted function</param>\n    /// <param name=\"ma\">Lifted argument</param>\n    /// <typeparam name=\"A\">Argument type</typeparam>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <returns>Applicative structure that represents the result of invoking the lifted function with\n    /// the lifted argument</returns>\n    [Pure]\n    public static abstract K<F, B> Apply<A, B>(K<F, Func<A, B>> mf, K<F, A> ma);\n    \n    /// <summary>\n    /// Apply the function to the argument.\n    /// This is like `delegate.Invoke` for lifted functions and lifted arguments.\n    /// </summary>\n    /// <remarks>\n    /// Uses memoisation for lazy and then cached evaluation of the argument.\n    /// </remarks>\n    /// <param name=\"mf\">Lifted function</param>\n    /// <param name=\"ma\">Lifted argument</param>\n    /// <typeparam name=\"A\">Argument type</typeparam>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <returns>Applicative structure that represents the result of invoking the lifted function with\n    /// the lifted argument</returns>\n    [Pure]\n    public static abstract K<F, B> Apply<A, B>(K<F, Func<A, B>> mf, Memo<F, A> ma);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Default implementations\n    //\n\n    /// <summary>\n    /// Apply the function to the argument.\n    /// This is like `delegate.Invoke` for lifted functions and lifted arguments.\n    /// </summary>\n    /// <remarks>\n    /// Uses memoisation for lazy and then cached evaluation of the argument.\n    /// </remarks>\n    /// <param name=\"mf\">Lifted function</param>\n    /// <param name=\"ma\">Lifted argument</param>\n    /// <typeparam name=\"A\">Argument type</typeparam>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <returns>Applicative structure that represents the result of invoking the lifted function with\n    /// the lifted argument</returns>\n    [Pure]\n    public static virtual K<F, B> Apply<A, B>(Memo<F, Func<A, B>> mf, Memo<F, A> ma) =>\n        mf.Value.Apply(ma);\n\n    /// <summary>\n    /// Apply the function to the argument.\n    /// This is like `delegate.Invoke` for lifted functions and lifted arguments.\n    /// </summary>\n    /// <remarks>\n    /// Uses memoisation for lazy and then cached evaluation of the argument.\n    /// </remarks>\n    /// <param name=\"mf\">Lifted function</param>\n    /// <param name=\"ma\">Lifted argument</param>\n    /// <typeparam name=\"A\">Argument type</typeparam>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <returns>Applicative structure that represents the result of invoking the lifted function with\n    /// the lifted argument</returns>\n    [Pure]\n    public static virtual K<F, B> Apply<A, B>(Memo<F, Func<A, B>> mf, K<F, A> ma) =>\n        mf.Value.Apply(ma);\n\n    /// <summary>\n    /// Applicative action.  Computes the first applicative action and then computes the second.\n    /// </summary>\n    /// <param name=\"ma\">First applicative structure</param>\n    /// <param name=\"mb\">Second applicative structure</param>\n    /// <typeparam name=\"A\">First applicative structure bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative structure bound value type</typeparam>\n    /// <returns>The result of the second applicative action (if there wasn't a failure beforehand)</returns>\n    [Pure]\n    public static virtual K<F, B> Action<A, B>(K<F, A> ma, K<F, B> mb) =>\n        Applicative.lift<F, A, B, B>(_ => y => y, ma, mb);\n\n    /// <summary>\n    /// Applicative action.  Computes the first applicative action and then computes the second.\n    /// </summary>\n    /// <param name=\"ma\">First applicative structure</param>\n    /// <param name=\"mb\">Second applicative structure</param>\n    /// <typeparam name=\"A\">First applicative structure bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative structure bound value type</typeparam>\n    /// <returns>The result of the second applicative action (if there wasn't a failure beforehand)</returns>\n    [Pure]\n    public static virtual K<F, A> BackAction<A, B>(K<F, A> ma, K<F, B> mb) =>\n        Applicative.lift<F, A, B, A>(x => _ => x, ma, mb);\n\n    /// <summary>\n    /// Applicative action.  Computes the first applicative action and then computes the second.\n    /// </summary>\n    /// <param name=\"ma\">First applicative structure</param>\n    /// <param name=\"mb\">Second applicative structure</param>\n    /// <typeparam name=\"A\">First applicative structure bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative structure bound value type</typeparam>\n    /// <returns>The result of the second applicative action (if there wasn't a failure beforehand)</returns>\n    [Pure]\n    public static virtual K<F, B> Action<A, B>(K<F, A> ma, Memo<F, B> mb) =>\n        Applicative.lift<F, A, B, B>(_ => y => y, memoK(ma), mb);\n\n    /// <summary>\n    /// Applicative action.  Computes the first applicative action and then computes the second.\n    /// </summary>\n    /// <param name=\"ma\">First applicative structure</param>\n    /// <param name=\"mb\">Second applicative structure</param>\n    /// <typeparam name=\"A\">First applicative structure bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative structure bound value type</typeparam>\n    /// <returns>The result of the second applicative action (if there wasn't a failure beforehand)</returns>\n    [Pure]\n    public static virtual K<F, A> BackAction<A, B>(K<F, A> ma, Memo<F, B> mb) =>\n        Applicative.lift<F, A, B, A>(x => _ => x, memoK(ma), mb);\n\n    /// <summary>\n    /// Applicative action.  Computes the first applicative action and then computes the second.\n    /// </summary>\n    /// <param name=\"ma\">First applicative structure</param>\n    /// <param name=\"mb\">Second applicative structure</param>\n    /// <typeparam name=\"A\">First applicative structure bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative structure bound value type</typeparam>\n    /// <returns>The result of the second applicative action (if there wasn't a failure beforehand)</returns>\n    [Pure]\n    public static virtual K<F, B> Action<A, B>(Memo<F, A> ma, Memo<F, B> mb) =>\n        Applicative.lift<F, A, B, B>(_ => y => y, ma, mb);\n\n    /// <summary>\n    /// Applicative action.  Computes the first applicative action and then computes the second.\n    /// </summary>\n    /// <param name=\"ma\">First applicative structure</param>\n    /// <param name=\"mb\">Second applicative structure</param>\n    /// <typeparam name=\"A\">First applicative structure bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative structure bound value type</typeparam>\n    /// <returns>The result of the second applicative action (if there wasn't a failure beforehand)</returns>\n    [Pure]\n    public static virtual K<F, A> BackAction<A, B>(Memo<F, A> ma, Memo<F, B> mb) =>\n        Applicative.lift<F, A, B, A>(x => _ => x, ma, mb);\n\n    /// <summary>\n    /// Applicative action.  Computes the first applicative action and then computes the second.\n    /// </summary>\n    /// <param name=\"ma\">First applicative structure</param>\n    /// <param name=\"mb\">Second applicative structure</param>\n    /// <typeparam name=\"A\">First applicative structure bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative structure bound value type</typeparam>\n    /// <returns>The result of the second applicative action (if there wasn't a failure beforehand)</returns>\n    [Pure]\n    public static virtual K<F, B> Action<A, B>(Memo<F, A> ma, K<F, B> mb) =>\n        Applicative.lift<F, A, B, B>(_ => y => y, ma, memoK(mb));\n\n    /// <summary>\n    /// Applicative action.  Computes the first applicative action and then computes the second.\n    /// </summary>\n    /// <param name=\"ma\">First applicative structure</param>\n    /// <param name=\"mb\">Second applicative structure</param>\n    /// <typeparam name=\"A\">First applicative structure bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative structure bound value type</typeparam>\n    /// <returns>The result of the second applicative action (if there wasn't a failure beforehand)</returns>\n    [Pure]\n    public static virtual K<F, A> BackAction<A, B>(Memo<F, A> ma, K<F, B> mb) =>\n        Applicative.lift<F, A, B, A>(x => _ => x, ma, memoK(mb));\n\n    /// <summary>\n    /// Chains a sequence of applicative actions\n    /// </summary>\n    /// <remarks>\n    /// Because this is an abstract chaining of actions, it can't actually run anything, and so if your\n    /// actions are expected to have side effects (IO effects, for example), then you won't see them until\n    /// the resulting `K〈F, A〉` is 'run'.\n    ///\n    /// This matters for infinite streams, where the result of `Actions` isn't realised at all, and so to\n    /// avoid nothing happening (no side effects), you should override this function and unpack the IO\n    /// type within, then run that enumerable of IOs.\n    ///\n    /// A good example is with the `Eff` type.  It's a `ReaderT〈IO, A〉` internally:\n    ///\n    ///     static K〈Eff〈RT〉, A〉 Actions〈A〉(IEnumerable〈K〈Eff〈RT〉, A〉〉 fas) =〉\n    ///         new Eff〈RT, A〉(\n    ///             new ReaderT〈RT, IO, A〉(\n    ///                 rt =〉fas.Select(fa =〉fa.RunIO(rt)).Actions()));\n    ///  \n    /// </remarks>\n    /// <param name=\"fas\">Actions to chain</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    /// <exception cref=\"ExpectedException\">Sequence is empty</exception>\n    [Pure]\n    public static virtual K<F, A> Actions<A>(IterableNE<K<F, A>> fas) =>\n        // TODO: Consider ways to make this not be blocking as a sensible default implementation\n        fas.Tail.Fold(fas.Head, (h, t) => h.Action(t));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Supplementary members\n    //\n    \n    /// <summary>\n    /// `between(open, close, p) parses `open`, followed by `p` and `close`.\n    /// </summary>\n    /// <param name=\"open\">Open computation</param>\n    /// <param name=\"close\">Close computation</param>\n    /// <param name=\"p\">Between computation</param>\n    /// <typeparam name=\"A\">Return value type</typeparam>\n    /// <typeparam name=\"OPEN\">OPEN value type</typeparam>\n    /// <typeparam name=\"CLOSE\">CLOSE value type</typeparam>\n    /// <returns>The value returned by `p`</returns>\n    [Pure]\n    public static virtual K<F, A> Between<A, OPEN, CLOSE>(\n        K<F, OPEN> open, \n        K<F, CLOSE> close, \n        K<F, A> p) =>\n        open.Action(p).BackAction(close);\n    \n    /// <summary>\n    /// Construct a sequence of `count` repetitions of `fa`\n    /// </summary>\n    /// <param name=\"count\">Number of repetitions</param>\n    /// <param name=\"fa\">Applicative computation to run</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Applicative structure of `count` items</returns>\n    [Pure]\n    public static virtual K<F, Seq<A>> Replicate<A>(int count, K<F, A> fa) =>\n        count switch\n        {\n            <= 0 => F.Pure<Seq<A>>([]),\n            _    => Applicative.lift(Seq.cons, fa, F.Replicate(count - 1, fa))\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Action.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    extension<F, A>(K<F, A> ma) where F : Applicative<F>\n    {\n        [Pure]\n        public K<F, B> Action<B>(K<F, B> mb) =>\n            F.Action(ma, mb);\n        \n        public K<F, A> BackAction<B>(K<F, B> mb) =>\n            F.BackAction(ma, mb);\n    }\n\n    extension<F, A>(Memo<F, A> ma) where F : Applicative<F>\n    {\n        [Pure]\n        public K<F, B> Action<B>(K<F, B> mb) =>\n            F.Action(ma, mb);\n        \n        public K<F, A> BackAction<B>(K<F, B> mb) =>\n            F.BackAction(ma, mb);\n    }\n    \n    [Pure]\n    public static K<F, A> Actions<F, A>(this IterableNE<K<F, A>> ma)\n        where F : Applicative<F> =>\n        F.Actions(ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    extension<AF, A, B>(K<AF, Func<A, B>> mf)\n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, B> Apply(K<AF, A> ma) =>\n            AF.Apply(mf, ma);\n    }\n\n    extension<AF, A, B, C>(K<AF, Func<A, B, C>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B, C>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D>(K<AF, Func<A, B, C, D>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, D>>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E>(K<AF, Func<A, B, C, D, E>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, E>>>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F>(K<AF, Func<A, B, C, D, E, F>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, F>>>>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G>(K<AF, Func<A, B, C, D, E, F, G>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, G>>>>>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H>(K<AF, Func<A, B, C, D, E, F, G, H>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I>(K<AF, Func<A, B, C, D, E, F, G, H, I>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I, J>(K<AF, Func<A, B, C, D, E, F, G, H, I, J>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I, J, K>(K<AF, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> Apply(K<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, R>(\n        this (K<Fnctr, A>, K<Fnctr, B>) items,\n        Func<A, B, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2);\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, C, R>(\n        this (K<Fnctr, A>, K<Fnctr, B>, K<Fnctr, C>) items, Func<A, B, C, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3);\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, C, D, R>(\n        this (K<Fnctr, A>, K<Fnctr, B>, K<Fnctr, C>, K<Fnctr, D>) items,\n        Func<A, B, C, D, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4);\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, C, D, E, R>(\n        this (K<Fnctr, A>, K<Fnctr, B>, K<Fnctr, C>, K<Fnctr, D>, K<Fnctr, E>) items,\n        Func<A, B, C, D, E, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5);\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, C, D, E, F, R>(\n        this (K<Fnctr, A>, K<Fnctr, B>, K<Fnctr, C>, K<Fnctr, D>, K<Fnctr, E>, K<Fnctr, F>) items,\n        Func<A, B, C, D, E, F, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6);\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, C, D, E, F, G, R>(\n        this (K<Fnctr, A>, K<Fnctr, B>, K<Fnctr, C>, K<Fnctr, D>, K<Fnctr, E>, K<Fnctr, F>, K<Fnctr, G>) items,\n        Func<A, B, C, D, E, F, G, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7);\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, C, D, E, F, G, H, R>(\n        this (K<Fnctr, A>, K<Fnctr, B>, K<Fnctr, C>, K<Fnctr, D>, K<Fnctr, E>, K<Fnctr, F>, K<Fnctr, G>, K<Fnctr, H>) items,\n        Func<A, B, C, D, E, F, G, H, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8);\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, C, D, E, F, G, H, I, R>(\n        this (K<Fnctr, A>,\n              K<Fnctr, B>,\n              K<Fnctr, C>,\n              K<Fnctr, D>,\n              K<Fnctr, E>,\n              K<Fnctr, F>,\n              K<Fnctr, G>,\n              K<Fnctr, H>,\n              K<Fnctr, I>) items,\n        Func<A, B, C, D, E, F, G, H, I, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8)\n         .Apply(items.Item9);\n\n    [Pure]\n    public static K<Fnctr, R> Apply<Fnctr, A, B, C, D, E, F, G, H, I, J, R>(\n        this (K<Fnctr, A>,\n            K<Fnctr, B>,\n            K<Fnctr, C>,\n            K<Fnctr, D>,\n            K<Fnctr, E>,\n            K<Fnctr, F>,\n            K<Fnctr, G>,\n            K<Fnctr, H>,\n            K<Fnctr, I>,\n            K<Fnctr, J>) items,\n        Func<A, B, C, D, E, F, G, H, I, J, R> f)\n        where Fnctr : Applicative<Fnctr> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8)\n         .Apply(items.Item9)\n         .Apply(items.Item10);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.ApplyM.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    extension<M, A, B>((K<M, A>, K<M, B>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n\n    extension<M, A, B, C>((K<M, A>, K<M, B>, K<M, C>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, C, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n\n    extension<M, A, B, C, D>((K<M, A>, K<M, B>, K<M, C>, K<M, D>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, C, D, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n\n    extension<M, A, B, C, D, E>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, C, D, E, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n\n    extension<M, A, B, C, D, E, F>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, C, D, E, F, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n\n    extension<M, A, B, C, D, E, F, G>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>, K<M, G>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, C, D, E, F, G, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n\n    extension<M, A, B, C, D, E, F, G, H>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>, K<M, G>, K<M, H>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, C, D, E, F, G, H, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n\n    extension<M, A, B, C, D, E, F, G, H, I>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>, K<M, G>, K<M, H>, K<M, I>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, C, D, E, F, G, H, I, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n\n    extension<M, A, B, C, D, E, F, G, H, I, J>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>, K<M, G>, K<M, H>, K<M, I>, K<M, J>) items) \n        where M : Monad<M>\n    {\n        [Pure]\n        public K<M, R> ApplyM<R>(Func<A, B, C, D, E, F, G, H, I, J, K<M, R>> f) =>\n            items.Apply(f).Flatten();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Arithmetic.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    /// <summary>\n    /// Sum the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Add<NumA, F, A>(this K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Num<A> =>\n        (fa, fb).Apply(NumA.Add);\n\n    /// <summary>\n    /// Sum the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Add<F, A>(this K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where A : IAdditionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x + y);\n\n    /// <summary>\n    /// Subtract the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Subtract<NumA, F, A>(this K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Arithmetic<A> =>\n        (fa, fb).Apply(NumA.Subtract);\n\n    /// <summary>\n    /// Subtract the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Subtract<F, A>(this K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where A : ISubtractionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x - y);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Multiply<NumA, F, A>(this K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Arithmetic<A> =>\n        (fa, fb).Apply(NumA.Multiply);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Multiply<F, A>(this K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where A : IMultiplyOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x * y);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Divide<NumA, F, A>(this K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Num<A> =>\n        (fa, fb).Apply(NumA.Divide);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Divide<F, A>(this K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where A : IDivisionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x / y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Lift.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    [Pure]\n    public static K<F, B> Lift<F, A, B>(this Func<A, B> f, K<F, A> fa)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa);\n\n    [Pure]\n    public static K<F, C> Lift<F, A, B, C>(this Func<A, B, C> f, K<F, A> fa, K<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, C> Lift<F, A, B, C>(this Func<A, Func<B, C>> f, K<F, A> fa, K<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, D> Lift<F, A, B, C, D>(this Func<A, B, C, D> f, K<F, A> fa, K<F, B> fb, K<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> Lift<F, A, B, C, D>(this Func<A, Func<B, Func<C, D>>> f, K<F, A> fa, K<F, B> fb, K<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Memo.Action.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    extension<F, A>(K<F, A> ma) where F : Applicative<F>\n    {\n        [Pure]\n        public K<F, B> Action<B>(Memo<F, B> mb) =>\n            F.Action(ma, mb);\n        \n        [Pure]\n        public K<F, A> BackAction<B>(Memo<F, B> mb) =>\n            F.BackAction(ma, mb);\n    }\n    \n    extension<F, A>(Memo<F, A> ma) where F : Applicative<F>\n    {\n        [Pure]\n        public K<F, B> Action<B>(Memo<F, B> mb) =>\n            F.Action(ma, mb);\n        \n        [Pure]\n        public K<F, A> BackAction<B>(Memo<F, B> mb) =>\n            F.BackAction(ma, mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Memo.Apply.Tuple.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    extension<AF, A, B>((Memo<AF, A>, Memo<AF, B>) items) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2);\n    }\n\n    extension<AF, A, B, C>((Memo<AF, A>, Memo<AF, B>, Memo<AF, C>) items) where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, C, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2)\n             .Apply(items.Item3);\n    }\n\n    extension<AF, A, B, C, D>((Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>) items) where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, C, D, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2)\n             .Apply(items.Item3)\n             .Apply(items.Item4);\n    }\n\n    extension<AF, A, B, C, D, E>((Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>, Memo<AF, E>) items) where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, C, D, E, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2)\n             .Apply(items.Item3)\n             .Apply(items.Item4)\n             .Apply(items.Item5);\n    }\n\n    extension<AF, A, B, C, D, E, F>((Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>, Memo<AF, E>, Memo<AF, F>) items) where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, C, D, E, F, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2)\n             .Apply(items.Item3)\n             .Apply(items.Item4)\n             .Apply(items.Item5)\n             .Apply(items.Item6);\n    }\n\n    extension<AF, A, B, C, D, E, F, G>((Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>, Memo<AF, E>, Memo<AF, F>, Memo<AF, G>) items) where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, C, D, E, F, G, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2)\n             .Apply(items.Item3)\n             .Apply(items.Item4)\n             .Apply(items.Item5)\n             .Apply(items.Item6)\n             .Apply(items.Item7);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H>((Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>, Memo<AF, E>, Memo<AF, F>, Memo<AF, G>, Memo<AF, H>) items) where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, C, D, E, F, G, H, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2)\n             .Apply(items.Item3)\n             .Apply(items.Item4)\n             .Apply(items.Item5)\n             .Apply(items.Item6)\n             .Apply(items.Item7)\n             .Apply(items.Item8);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I>((Memo<AF, A>,\n                                                 Memo<AF, B>,\n                                                 Memo<AF, C>,\n                                                 Memo<AF, D>,\n                                                 Memo<AF, E>,\n                                                 Memo<AF, F>,\n                                                 Memo<AF, G>,\n                                                 Memo<AF, H>,\n                                                 Memo<AF, I>) items) where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, C, D, E, F, G, H, I, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2)\n             .Apply(items.Item3)\n             .Apply(items.Item4)\n             .Apply(items.Item5)\n             .Apply(items.Item6)\n             .Apply(items.Item7)\n             .Apply(items.Item8)\n             .Apply(items.Item9);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I, J>((Memo<AF, A>,\n                                                    Memo<AF, B>,\n                                                    Memo<AF, C>,\n                                                    Memo<AF, D>,\n                                                    Memo<AF, E>,\n                                                    Memo<AF, F>,\n                                                    Memo<AF, G>,\n                                                    Memo<AF, H>,\n                                                    Memo<AF, I>,\n                                                    Memo<AF, J>) items) where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, R> Apply<R>(Func<A, B, C, D, E, F, G, H, I, J, R> f) =>\n            f.Map(items.Item1)\n             .Apply(items.Item2)\n             .Apply(items.Item3)\n             .Apply(items.Item4)\n             .Apply(items.Item5)\n             .Apply(items.Item6)\n             .Apply(items.Item7)\n             .Apply(items.Item8)\n             .Apply(items.Item9)\n             .Apply(items.Item10);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Memo.Apply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    extension<AF, A, B>(K<AF, Func<A, B>> mf)\n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, B> Apply(Memo<AF, A> ma) =>\n            AF.Apply(mf, ma);\n    }\n\n    extension<AF, A, B>(Memo<AF, Func<A, B>> mf)\n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, B> Apply(Memo<AF, A> ma) =>\n            AF.Apply(mf, ma);\n    }\n\n    extension<AF, A, B, C>(K<AF, Func<A, B, C>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B, C>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C>(Memo<AF, Func<A, B, C>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B, C>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D>(K<AF, Func<A, B, C, D>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, D>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D>(Memo<AF, Func<A, B, C, D>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, D>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E>(K<AF, Func<A, B, C, D, E>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, E>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E>(Memo<AF, Func<A, B, C, D, E>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, E>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F>(K<AF, Func<A, B, C, D, E, F>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, F>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F>(Memo<AF, Func<A, B, C, D, E, F>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, F>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G>(K<AF, Func<A, B, C, D, E, F, G>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, G>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G>(Memo<AF, Func<A, B, C, D, E, F, G>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, G>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H>(K<AF, Func<A, B, C, D, E, F, G, H>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H>(Memo<AF, Func<A, B, C, D, E, F, G, H>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I>(K<AF, Func<A, B, C, D, E, F, G, H, I>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I>(Memo<AF, Func<A, B, C, D, E, F, G, H, I>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I, J>(K<AF, Func<A, B, C, D, E, F, G, H, I, J>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I, J>(Memo<AF, Func<A, B, C, D, E, F, G, H, I, J>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I, J, K>(K<AF, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n\n    extension<AF, A, B, C, D, E, F, G, H, I, J, K>(Memo<AF, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) \n        where AF : Applicative<AF>\n    {\n        [Pure]\n        public K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> Apply(Memo<AF, A> ma) =>\n            AF.Apply(AF.Map(curry, mf), ma);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Memo.Arithmetic.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    /// <summary>\n    /// Sum the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Add<NumA, F, A>(this Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Num<A> =>\n        (fa, fb).Apply(NumA.Add);\n\n    /// <summary>\n    /// Sum the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Add<F, A>(this Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where A : IAdditionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x + y);\n\n    /// <summary>\n    /// Subtract the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Subtract<NumA, F, A>(this Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Arithmetic<A> =>\n        (fa, fb).Apply(NumA.Subtract);\n\n    /// <summary>\n    /// Subtract the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Subtract<F, A>(this Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where A : ISubtractionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x - y);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Multiply<NumA, F, A>(this Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Arithmetic<A> =>\n        (fa, fb).Apply(NumA.Multiply);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Multiply<F, A>(this Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where A : IMultiplyOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x * y);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Divide<NumA, F, A>(this Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Num<A> =>\n        (fa, fb).Apply(NumA.Divide);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> Divide<F, A>(this Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where A : IDivisionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x / y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Memo.Lift.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    [Pure]\n    public static K<F, B> Lift<F, A, B>(this Func<A, B> f, Memo<F, A> fa)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa);\n\n    [Pure]\n    public static K<F, C> Lift<F, A, B, C>(this Func<A, B, C> f, Memo<F, A> fa, Memo<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, C> Lift<F, A, B, C>(this Func<A, Func<B, C>> f, Memo<F, A> fa, Memo<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, D> Lift<F, A, B, C, D>(this Func<A, B, C, D> f, Memo<F, A> fa, Memo<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> Lift<F, A, B, C, D>(this Func<A, Func<B, Func<C, D>>> f, Memo<F, A> fa, Memo<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Memo.Zip.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    extension<F, A, B>((Memo<F, A> First, Memo<F, B> Second) tuple) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second)> Zip() =>\n            map((A a, B b) => (a, b), tuple.First).Apply(tuple.Second);\n    }\n\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    extension<F, A, B, C>((Memo<F, A> First, Memo<F, B> Second, Memo<F, C> Third) tuple) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third)> Zip() =>\n            map((A a, B b, C c) => (a, b, c), tuple.First)\n               .Apply(tuple.Second)\n               .Apply(tuple.Third);\n    }\n\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    extension<F, A, B, C, D>((Memo<F, A> First, Memo<F, B> Second, Memo<F, C> Third, Memo<F, D> Fourth) tuple) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third, D Fourth)> Zip() =>\n            map((A a, B b, C c, D d) => (a, b, c, d), tuple.First)\n               .Apply(tuple.Second)\n               .Apply(tuple.Third)\n               .Apply(tuple.Fourth);\n    }\n\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    extension<F, A, B, C, D, E>((Memo<F, A> First, Memo<F, B> Second, Memo<F, C> Third, Memo<F, D> Fourth, Memo<F, E> Fifth) tuple) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third, D Fourth, E Fifth)> Zip() =>\n            map((A a, B b, C c, D d, E e) => (a, b, c, d, e), tuple.First)\n               .Apply(tuple.Second)\n               .Apply(tuple.Third)\n               .Apply(tuple.Fourth)\n               .Apply(tuple.Fifth);\n    }\n\n\n    /// <param name=\"First\">First applicative</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    extension<F, A>(Memo<F, A> First) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <param name=\"Second\">Second applicative</param>\n        /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second)> Zip<B>(Memo<F, B> Second) =>\n            map((A a, B b) => (a, b), First).Apply(Second);\n\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <param name=\"Second\">Second applicative</param>\n        /// <param name=\"Third\">Third applicative</param>\n        /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n        /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third)> Zip<B, C>(Memo<F, B> Second, Memo<F, C> Third) =>\n            map((A a, B b, C c) => (a, b, c), First)\n               .Apply(Second)\n               .Apply(Third);\n\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <param name=\"Second\">Second applicative</param>\n        /// <param name=\"Third\">Third applicative</param>\n        /// <param name=\"Fourth\">Fourth applicative</param>\n        /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n        /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n        /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third, D Fourth)> Zip<B, C, D>(Memo<F, B> Second, Memo<F, C> Third, Memo<F, D> Fourth) =>\n            map((A a, B b, C c, D d) => (a, b, c, d), First)\n               .Apply(Second)\n               .Apply(Third)\n               .Apply(Fourth);\n\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <param name=\"Second\">Second applicative</param>\n        /// <param name=\"Third\">Third applicative</param>\n        /// <param name=\"Fourth\">Fourth applicative</param>\n        /// <param name=\"Fifth\">Fifth applicative</param>\n        /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n        /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n        /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third, D Fourth, E Fifth)> Zip<B, C, D, E>(Memo<F, B> Second, Memo<F, C> Third, Memo<F, D> Fourth, Memo<F, E> Fifth) =>\n            map((A a, B b, C c, D d, E e) => (a, b, c, d, e), First)\n               .Apply(Second)\n               .Apply(Third)\n               .Apply(Fourth)\n               .Apply(Fifth);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.Zip.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    extension<F, A, B>((K<F, A> First, K<F, B> Second) tuple) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second)> Zip() =>\n            map((A a, B b) => (a, b), tuple.First).Apply(tuple.Second);\n    }\n\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    extension<F, A, B, C>((K<F, A> First, K<F, B> Second, K<F, C> Third) tuple) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third)> Zip() =>\n            map((A a, B b, C c) => (a, b, c), tuple.First)\n               .Apply(tuple.Second)\n               .Apply(tuple.Third);\n    }\n\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    extension<F, A, B, C, D>((K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth) tuple) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third, D Fourth)> Zip() =>\n            map((A a, B b, C c, D d) => (a, b, c, d), tuple.First)\n               .Apply(tuple.Second)\n               .Apply(tuple.Third)\n               .Apply(tuple.Fourth);\n    }\n\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    extension<F, A, B, C, D, E>((K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth, K<F, E> Fifth) tuple) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third, D Fourth, E Fifth)> Zip() =>\n            map((A a, B b, C c, D d, E e) => (a, b, c, d, e), tuple.First)\n               .Apply(tuple.Second)\n               .Apply(tuple.Third)\n               .Apply(tuple.Fourth)\n               .Apply(tuple.Fifth);\n    }\n\n\n    /// <param name=\"First\">First applicative</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    extension<F, A>(K<F, A> First) where F : Applicative<F>\n    {\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <param name=\"Second\">Second applicative</param>\n        /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second)> Zip<B>(K<F, B> Second) =>\n            map((A a, B b) => (a, b), First).Apply(Second);\n\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <param name=\"Second\">Second applicative</param>\n        /// <param name=\"Third\">Third applicative</param>\n        /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n        /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third)> Zip<B, C>(K<F, B> Second, K<F, C> Third) =>\n            map((A a, B b, C c) => (a, b, c), First)\n               .Apply(Second)\n               .Apply(Third);\n\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <param name=\"Second\">Second applicative</param>\n        /// <param name=\"Third\">Third applicative</param>\n        /// <param name=\"Fourth\">Fourth applicative</param>\n        /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n        /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n        /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third, D Fourth)> Zip<B, C, D>(K<F, B> Second, K<F, C> Third, K<F, D> Fourth) =>\n            map((A a, B b, C c, D d) => (a, b, c, d), First)\n               .Apply(Second)\n               .Apply(Third)\n               .Apply(Fourth);\n\n        /// <summary>\n        /// Zips applicatives into a tuple\n        /// </summary>\n        /// <param name=\"Second\">Second applicative</param>\n        /// <param name=\"Third\">Third applicative</param>\n        /// <param name=\"Fourth\">Fourth applicative</param>\n        /// <param name=\"Fifth\">Fifth applicative</param>\n        /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n        /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n        /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n        /// <returns>Zipped applicative</returns>\n        public K<F, (A First, B Second, C Third, D Fourth, E Fifth)> Zip<B, C, D, E>(K<F, B> Second, K<F, C> Third, K<F, D> Fourth, K<F, E> Fifth) =>\n            map((A a, B b, C c, D d, E e) => (a, b, c, d, e), First)\n               .Apply(Second)\n               .Apply(Third)\n               .Apply(Fourth)\n               .Apply(Fifth);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Extensions/Applicative.Extensions.cs",
    "content": "﻿using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Action.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<F, B> action<F, A ,B>(K<F, A> ma, K<F, B> mb) \n        where F : Applicative<F> =>\n        F.Action(ma, mb);\n\n    [Pure]\n    public static K<F, A> actions<F, A>(IterableNE<K<F, A>> ma)\n        where F : Applicative<F> =>\n        F.Actions(ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Apply.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<AF, B> apply<AF, A, B>(K<AF, Func<A, B>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(mf, ma);\n\n    [Pure]\n    public static K<AF, Func<B, C>> apply<AF, A, B, C>(K<AF, Func<A, B, C>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, D>>> apply<AF, A, B, C, D>(K<AF, Func<A, B, C, D>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, E>>>> apply<AF, A, B, C, D, E>(K<AF, Func<A, B, C, D, E>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, F>>>>> apply<AF, A, B, C, D, E, F>(K<AF, Func<A, B, C, D, E, F>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, G>>>>>> apply<AF, A, B, C, D, E, F, G>(K<AF, Func<A, B, C, D, E, F, G>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> apply<AF, A, B, C, D, E, F, G, H>(K<AF, Func<A, B, C, D, E, F, G, H>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I>(K<AF, Func<A, B, C, D, E, F, G, H, I>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I, J>(K<AF, Func<A, B, C, D, E, F, G, H, I, J>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I, J, K>(K<AF, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, K<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, R>(\n        (K<AF, A>, K<AF, B>) items,\n        Func<A, B, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, R>(\n        (K<AF, A>, K<AF, B>, K<AF, C>) items, Func<A, B, C, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, R>(\n        (K<AF, A>, K<AF, B>, K<AF, C>, K<AF, D>) items,\n        Func<A, B, C, D, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, R>(\n        (K<AF, A>, K<AF, B>, K<AF, C>, K<AF, D>, K<AF, E>) items,\n        Func<A, B, C, D, E, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, R>(\n        (K<AF, A>, K<AF, B>, K<AF, C>, K<AF, D>, K<AF, E>, K<AF, F>) items,\n        Func<A, B, C, D, E, F, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, G, R>(\n        (K<AF, A>, K<AF, B>, K<AF, C>, K<AF, D>, K<AF, E>, K<AF, F>, K<AF, G>) items,\n        Func<A, B, C, D, E, F, G, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, G, H, R>(\n        (K<AF, A>, K<AF, B>, K<AF, C>, K<AF, D>, K<AF, E>, K<AF, F>, K<AF, G>, K<AF, H>) items,\n        Func<A, B, C, D, E, F, G, H, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, G, H, I, R>(\n        (K<AF, A>,\n              K<AF, B>,\n              K<AF, C>,\n              K<AF, D>,\n              K<AF, E>,\n              K<AF, F>,\n              K<AF, G>,\n              K<AF, H>,\n              K<AF, I>) items,\n        Func<A, B, C, D, E, F, G, H, I, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8)\n         .Apply(items.Item9);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, G, H, I, J, R>(\n        (K<AF, A>,\n            K<AF, B>,\n            K<AF, C>,\n            K<AF, D>,\n            K<AF, E>,\n            K<AF, F>,\n            K<AF, G>,\n            K<AF, H>,\n            K<AF, I>,\n            K<AF, J>) items,\n        Func<A, B, C, D, E, F, G, H, I, J, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8)\n         .Apply(items.Item9)\n         .Apply(items.Item10);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.ApplyM.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<M, R> applyM<M, A, B, R>((K<M, A>, K<M, B>) items, Func<A, B, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, R>((K<M, A>, K<M, B>, K<M, C>) items, Func<A, B, C, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, R>((K<M, A>, K<M, B>, K<M, C>, K<M, D>) items, Func<A, B, C, D, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, R>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>) items, Func<A, B, C, D, E, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, R>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>) items, Func<A, B, C, D, E, F, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, G, R>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>, K<M, G>) items, Func<A, B, C, D, E, F, G, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, G, H, R>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>, K<M, G>, K<M, H>) items, Func<A, B, C, D, E, F, G, H, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, G, H, I, R>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>, K<M, G>, K<M, H>, K<M, I>) items, Func<A, B, C, D, E, F, G, H, I, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, G, H, I, J, R>((K<M, A>, K<M, B>, K<M, C>, K<M, D>, K<M, E>, K<M, F>, K<M, G>, K<M, H>, K<M, I>, K<M, J>) items, Func<A, B, C, D, E, F, G, H, I, J, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Arithmetic.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Numerics;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    /// <summary>\n    /// Sum the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> add<NumA, F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Num<A> =>\n        (fa, fb).Apply(NumA.Add);\n\n    /// <summary>\n    /// Sum the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> add<F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where A : IAdditionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x + y);\n\n    /// <summary>\n    /// Subtract the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> subtract<NumA, F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Arithmetic<A> =>\n        (fa, fb).Apply(NumA.Subtract);\n\n    /// <summary>\n    /// Subtract the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> subtract<F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where A : ISubtractionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x - y);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> multiply<NumA, F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Arithmetic<A> =>\n        (fa, fb).Apply(NumA.Multiply);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> multiply<F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where A : IMultiplyOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x * y);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> divide<NumA, F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Num<A> =>\n        (fa, fb).Apply(NumA.Divide);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> divide<F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Applicative<F>\n        where A : IDivisionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x / y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Lift.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<F, B> lift<F, A, B>(Func<A, B> f, K<F, A> fa)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa);\n\n    [Pure]\n    public static K<F, C> lift<F, A, B, C>(Func<A, B, C> f, K<F, A> fa, K<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, C> lift<F, A, B, C>(Func<A, Func<B, C>> f, K<F, A> fa, K<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, B, C, D> f, K<F, A> fa, K<F, B> fb, K<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, Func<B, Func<C, D>>> f, K<F, A> fa, K<F, B> fb, K<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Memo.Action.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<F, B> action<F, A ,B>(K<F, A> ma, Memo<F, B> mb) \n        where F : Applicative<F> =>\n        F.Action(ma, mb);\n    \n    [Pure]\n    public static K<F, B> action<F, A ,B>(Memo<F, A> ma, Memo<F, B> mb) \n        where F : Applicative<F> =>\n        F.Action(ma, mb);    \n    \n    [Pure]\n    public static K<F, B> action<F, A ,B>(Memo<F, A> ma, K<F, B> mb) \n        where F : Applicative<F> =>\n        F.Action(ma, mb);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Memo.Apply.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<AF, B> apply<AF, A, B>(K<AF, Func<A, B>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(mf, ma);\n\n    [Pure]\n    public static K<AF, Func<B, C>> apply<AF, A, B, C>(K<AF, Func<A, B, C>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, D>>> apply<AF, A, B, C, D>(K<AF, Func<A, B, C, D>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, E>>>> apply<AF, A, B, C, D, E>(K<AF, Func<A, B, C, D, E>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, F>>>>> apply<AF, A, B, C, D, E, F>(K<AF, Func<A, B, C, D, E, F>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, G>>>>>> apply<AF, A, B, C, D, E, F, G>(K<AF, Func<A, B, C, D, E, F, G>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> apply<AF, A, B, C, D, E, F, G, H>(K<AF, Func<A, B, C, D, E, F, G, H>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I>(K<AF, Func<A, B, C, D, E, F, G, H, I>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I, J>(K<AF, Func<A, B, C, D, E, F, G, H, I, J>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I, J, K>(K<AF, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, Memo<AF, A> ma) where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, R>(\n        (Memo<AF, A>, Memo<AF, B>) items,\n        Func<A, B, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, R>(\n        (Memo<AF, A>, Memo<AF, B>, Memo<AF, C>) items, Func<A, B, C, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, R>(\n        (Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>) items,\n        Func<A, B, C, D, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, R>(\n        (Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>, Memo<AF, E>) items,\n        Func<A, B, C, D, E, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, R>(\n        (Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>, Memo<AF, E>, Memo<AF, F>) items,\n        Func<A, B, C, D, E, F, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, G, R>(\n        (Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>, Memo<AF, E>, Memo<AF, F>, Memo<AF, G>) items,\n        Func<A, B, C, D, E, F, G, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, G, H, R>(\n        (Memo<AF, A>, Memo<AF, B>, Memo<AF, C>, Memo<AF, D>, Memo<AF, E>, Memo<AF, F>, Memo<AF, G>, Memo<AF, H>) items,\n        Func<A, B, C, D, E, F, G, H, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, G, H, I, R>(\n        (Memo<AF, A>,\n            Memo<AF, B>,\n            Memo<AF, C>,\n            Memo<AF, D>,\n            Memo<AF, E>,\n            Memo<AF, F>,\n            Memo<AF, G>,\n            Memo<AF, H>,\n            Memo<AF, I>) items,\n        Func<A, B, C, D, E, F, G, H, I, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8)\n         .Apply(items.Item9);\n\n    [Pure]\n    public static K<AF, R> apply<AF, A, B, C, D, E, F, G, H, I, J, R>(\n        (Memo<AF, A>,\n            Memo<AF, B>,\n            Memo<AF, C>,\n            Memo<AF, D>,\n            Memo<AF, E>,\n            Memo<AF, F>,\n            Memo<AF, G>,\n            Memo<AF, H>,\n            Memo<AF, I>,\n            Memo<AF, J>) items,\n        Func<A, B, C, D, E, F, G, H, I, J, R> f)\n        where AF : Applicative<AF> =>\n        f.Map(items.Item1)\n         .Apply(items.Item2)\n         .Apply(items.Item3)\n         .Apply(items.Item4)\n         .Apply(items.Item5)\n         .Apply(items.Item6)\n         .Apply(items.Item7)\n         .Apply(items.Item8)\n         .Apply(items.Item9)\n         .Apply(items.Item10);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Memo.ApplyM.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<M, R> applyM<M, A, B, R>((Memo<M, A>, Memo<M, B>) items, Func<A, B, K<M, R>> f)\n        where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, R>((Memo<M, A>, Memo<M, B>, Memo<M, C>) items, Func<A, B, C, K<M, R>> f)\n        where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, R>((Memo<M, A>, Memo<M, B>, Memo<M, C>, Memo<M, D>) items,\n                                                   Func<A, B, C, D, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, R>(\n        (Memo<M, A>, Memo<M, B>, Memo<M, C>, Memo<M, D>, Memo<M, E>) items, Func<A, B, C, D, E, K<M, R>> f)\n        where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, R>(\n        (Memo<M, A>, Memo<M, B>, Memo<M, C>, Memo<M, D>, Memo<M, E>, Memo<M, F>) items,\n        Func<A, B, C, D, E, F, K<M, R>> f)\n        where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, G, R>(\n        (Memo<M, A>, Memo<M, B>, Memo<M, C>, Memo<M, D>, Memo<M, E>, Memo<M, F>, Memo<M, G>) items,\n        Func<A, B, C, D, E, F, G, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, G, H, R>(\n        (Memo<M, A>, Memo<M, B>, Memo<M, C>, Memo<M, D>, Memo<M, E>, Memo<M, F>, Memo<M, G>, Memo<M, H>) items,\n        Func<A, B, C, D, E, F, G, H, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, G, H, I, R>(\n        (Memo<M, A>, Memo<M, B>, Memo<M, C>, Memo<M, D>, Memo<M, E>, Memo<M, F>, Memo<M, G>, Memo<M, H>, Memo<M, I>)\n            items,\n        Func<A, B, C, D, E, F, G, H, I, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n\n    [Pure]\n    public static K<M, R> applyM<M, A, B, C, D, E, F, G, H, I, J, R>(\n        (Memo<M, A>, Memo<M, B>, Memo<M, C>, Memo<M, D>, Memo<M, E>, Memo<M, F>, Memo<M, G>, Memo<M, H>, Memo<M, I>,\n            Memo<M, J>) items, Func<A, B, C, D, E, F, G, H, I, J, K<M, R>> f) where M : Monad<M> =>\n        items.Apply(f).Flatten();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Memo.Arithmetic.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing System.Numerics;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    /// <summary>\n    /// Sum the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> add<NumA, F, A>(Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Num<A> =>\n        (fa, fb).Apply(NumA.Add);\n\n    /// <summary>\n    /// Sum the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> add<F, A>(Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where A : IAdditionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x + y);\n\n    /// <summary>\n    /// Subtract the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> subtract<NumA, F, A>(Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Arithmetic<A> =>\n        (fa, fb).Apply(NumA.Subtract);\n\n    /// <summary>\n    /// Subtract the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> subtract<F, A>(Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where A : ISubtractionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x - y);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> multiply<NumA, F, A>(Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Arithmetic<A> =>\n        (fa, fb).Apply(NumA.Multiply);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> multiply<F, A>(Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where A : IMultiplyOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x * y);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> divide<NumA, F, A>(Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where NumA : Num<A> =>\n        (fa, fb).Apply(NumA.Divide);\n\n    /// <summary>\n    /// Multiply the bound values of the applicative structures provided\n    /// </summary>\n    /// <typeparam name=\"NumA\">Num of A</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fx\">Left hand side of the operation</param>\n    /// <param name=\"fy\">Right hand side of the operation</param>\n    /// <returns>An applicative structure with the arithmetic operation applied to the bound values.</returns>\n    [Pure]\n    public static K<F, A> divide<F, A>(Memo<F, A> fa, Memo<F, A> fb)\n        where F : Applicative<F>\n        where A : IDivisionOperators<A, A, A> =>\n        (fa, fb).Apply((x, y) => x / y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Memo.Lift.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<F, B> lift<F, A, B>(Func<A, B> f, Memo<F, A> fa)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa);\n\n    [Pure]\n    public static K<F, C> lift<F, A, B, C>(Func<A, B, C> f, Memo<F, A> fa, Memo<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, C> lift<F, A, B, C>(Func<A, B, C> f, K<F, A> fa, Memo<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, C> lift<F, A, B, C>(Func<A, Func<B, C>> f, Memo<F, A> fa, Memo<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, C> lift<F, A, B, C>(Func<A, Func<B, C>> f, K<F, A> fa, Memo<F, B> fb)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, B, C, D> f, Memo<F, A> fa, Memo<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, B, C, D> f, K<F, A> fa, Memo<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, B, C, D> f, Memo<F, A> fa, K<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, B, C, D> f, Memo<F, A> fa, Memo<F, B> fb, K<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, B, C, D> f, K<F, A> fa, K<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, B, C, D> f, Memo<F, A> fa, K<F, B> fb, K<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, Func<B, Func<C, D>>> f, Memo<F, A> fa, Memo<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, Func<B, Func<C, D>>> f, K<F, A> fa, Memo<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);    \n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, Func<B, Func<C, D>>> f, Memo<F, A> fa, K<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);    \n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, Func<B, Func<C, D>>> f, Memo<F, A> fa, Memo<F, B> fb, K<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, Func<B, Func<C, D>>> f, K<F, A> fa, K<F, B> fb, Memo<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);    \n\n    [Pure]\n    public static K<F, D> lift<F, A, B, C, D>(Func<A, Func<B, Func<C, D>>> f, Memo<F, A> fa, K<F, B> fb, K<F, C> fc)\n        where F : Applicative<F> =>\n        F.Pure(f).Apply(fa).Apply(fb).Apply(fc);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.Zip.cs",
    "content": "﻿using static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second)> zip<F, A, B>((K<F, A> First, K<F, B> Second) tuple) where F : Applicative<F> =>\n        map((A a, B b) => (a, b), tuple.First).Apply(tuple.Second);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third)> zip<F, A, B, C>((K<F, A> First, K<F, B> Second, K<F, C> Third) tuple) where F : Applicative<F> =>\n        map((A a, B b, C c) => (a, b, c), tuple.First)\n           .Apply(tuple.Second)\n           .Apply(tuple.Third);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third, D Fourth)> zip<F, A, B, C, D>((K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth) tuple) where F : Applicative<F> =>\n        map((A a, B b, C c, D d) => (a, b, c, d), tuple.First)\n           .Apply(tuple.Second)\n           .Apply(tuple.Third)\n           .Apply(tuple.Fourth);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third, D Fourth, E Fifth)> zip<F, A, B, C, D, E>((K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth, K<F, E> Fifth) tuple) where F : Applicative<F> =>\n        map((A a, B b, C c, D d, E e) => (a, b, c, d, e), tuple.First)\n           .Apply(tuple.Second)\n           .Apply(tuple.Third)\n           .Apply(tuple.Fourth)\n           .Apply(tuple.Fifth);\n\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"Second\">Second applicative</param>\n    /// <param name=\"First\">First applicative</param>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second)> zip<F, A, B>(K<F, A> First, K<F, B> Second) where F : Applicative<F> =>\n        map((A a, B b) => (a, b), First).Apply(Second);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"Second\">Second applicative</param>\n    /// <param name=\"Third\">Third applicative</param>\n    /// <param name=\"First\">First applicative</param>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third)> zip<F, A, B, C>(K<F, A> First, K<F, B> Second, K<F, C> Third) where F : Applicative<F> =>\n        map((A a, B b, C c) => (a, b, c), First)\n           .Apply(Second)\n           .Apply(Third);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"Second\">Second applicative</param>\n    /// <param name=\"Third\">Third applicative</param>\n    /// <param name=\"Fourth\">Fourth applicative</param>\n    /// <param name=\"First\">First applicative</param>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third, D Fourth)> zip<F, A, B, C, D>(K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth) where F : Applicative<F> =>\n        map((A a, B b, C c, D d) => (a, b, c, d), First)\n           .Apply(Second)\n           .Apply(Third)\n           .Apply(Fourth);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"Second\">Second applicative</param>\n    /// <param name=\"Third\">Third applicative</param>\n    /// <param name=\"Fourth\">Fourth applicative</param>\n    /// <param name=\"Fifth\">Fifth applicative</param>\n    /// <param name=\"First\">First applicative</param>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third, D Fourth, E Fifth)> zip<F, A, B, C, D, E>(K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth, K<F, E> Fifth) where F : Applicative<F> =>\n        map((A a, B b, C c, D d, E e) => (a, b, c, d, e), First)\n           .Apply(Second)\n           .Apply(Third)\n           .Apply(Fourth)\n           .Apply(Fifth);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Module/Applicative.Module.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Applicative\n{\n    [Pure]\n    public static K<F, A> pure<F, A>(A value) \n        where F : Applicative<F> =>\n        F.Pure(value);\n\n    [Pure]\n    public static K<F, Unit> when<F>(bool flag, K<F, Unit> fx)\n        where F : Applicative<F> =>\n        flag ? fx : F.Pure<Unit>(default);\n\n    [Pure]\n    public static K<F, Unit> unless<F>(bool flag, K<F, Unit> fx)\n        where F : Applicative<F> =>\n        when(!flag, fx);\n    \n    /// <summary>\n    /// `between(open, close, p) parses `open`, followed by `p` and `close`.\n    /// </summary>\n    /// <param name=\"open\">Open computation</param>\n    /// <param name=\"close\">Close computation</param>\n    /// <param name=\"p\">Between computation</param>\n    /// <typeparam name=\"A\">Return value type</typeparam>\n    /// <typeparam name=\"OPEN\">OPEN value type</typeparam>\n    /// <typeparam name=\"CLOSE\">CLOSE value type</typeparam>\n    /// <returns>The value returned by `p`</returns>\n    [Pure]\n    public static K<F, A> between<F, A, OPEN, CLOSE>(\n        K<F, OPEN> open, \n        K<F, CLOSE> close, \n        K<F, A> p)\n        where F : Applicative<F> =>\n        F.Between(open, close, p);\n    \n    \n    /// <summary>\n    /// Construct a sequence of `count` repetitions of `fa`\n    /// </summary>\n    /// <param name=\"count\">Number of repetitions</param>\n    /// <param name=\"fa\">Applicative computation to run</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Applicative structure of `count` items</returns>\n    [Pure]\n    public static K<F, Seq<A>> replicate<F, A>(int count, K<F, A> fa) \n        where F : Applicative<F> =>\n        F.Replicate(count, fa);\n    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Operators/Applicative.Memo.Operators.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    extension<M, A, B>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static K<M, B> operator >> (K<M, A> ma, Memo<M, B> mb) =>\n            M.Action(ma, mb);\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static K<M, A> operator << (K<M, A> ma, Memo<M, B> mb) =>\n            Applicative.lift((x, _) => x, memoK(ma), mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, B> operator * (K<M, A> ma, Memo<M, Func<A, B>> mf) =>\n            M.Apply(mf, ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, B> operator * (Memo<M, Func<A, B>> mf, K<M, A> ma) =>\n            M.Apply(mf, ma);\n    }\n    \n    extension<M, A, B>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, B> operator * (Memo<M, A> ma, K<M, Func<A, B>> mf) =>\n            M.Apply(mf, ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, B> operator * (Memo<M, A> ma, Memo<M, Func<A, B>> mf) =>\n            M.Apply(mf, ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, B> operator * (K<M, Func<A, B>> mf, Memo<M, A> ma) =>\n            M.Apply(mf, ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, B> operator * (Memo<M, Func<A, B>> mf, Memo<M, A> ma) =>\n            M.Apply(mf, ma);\n    }\n    \n    extension<M, A, B, C>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            Memo<M, Func<A, B, C>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            Memo<M, Func<A, B, C>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            K<M, Func<A, B, C>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            Memo<M, Func<A, B, C, D>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            Memo<M, Func<A, B, C, D>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            K<M, Func<A, B, C, D>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Memo<M, Func<A, B, C, D, E>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Memo<M, Func<A, B, C, D, E>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<M, Func<A, B, C, D, E>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G, H>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G, H>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G, H>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G, H>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G, H>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G, H, I>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G, H, I>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G, H, I>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G, H, I>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G, H, I, J>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n    \n    \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n    \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(Memo<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Memo<M, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            Memo<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Memo<M, A> ma,\n            Memo<M, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Memo<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Operators/Applicative.Operators.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class ApplicativeExtensions\n{\n    extension<M, A, B>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static K<M, B> operator >>> (K<M, A> ma, K<M, B> mb) =>\n            M.Action(ma, mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, B> operator * (K<M, Func<A, B>> mf, K<M, A> ma) =>\n            M.Apply(mf, ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, B> operator * (K<M, A> ma, K<M, Func<A, B>> mf) =>\n            M.Apply(mf, ma);\n    }\n    \n    extension<M, A, B, C>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            K<M, Func<A, B, C>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            K<M, Func<A, B, C, D>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;        \n    }\n            \n    extension<M, A, B, C, D, E>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<M, Func<A, B, C, D, E>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;        \n    }\n                \n    extension<M, A, B, C, D, E, F>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;        \n    }\n                    \n    extension<M, A, B, C, D, E, F, G, H>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G, H>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;        \n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;        \n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;        \n    }\n                                \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<M, A> self)\n        where M : Applicative<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<M, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<M, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<M, A> ma,\n            K<M, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;        \n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/Prelude/Applicative.Prelude.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Construct an applicative structure from a pure value  \n    /// </summary>\n    /// <param name=\"value\">Pure value to lift into the applicative structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Applicative structure</returns>\n    [Pure]\n    public static K<F, A> pure<F, A>(A value)\n        where F : Applicative<F> =>\n        F.Pure(value);    \n    \n    [Pure]\n    public static K<M, B> applyM<M, A, B>(K<M, Func<A, K<M, B>>> mf, K<M, A> ma)\n        where M : Monad<M> =>\n        M.Apply(mf, ma).Flatten();\n    \n    [Pure]\n    public static K<AF, B> apply<AF, A, B>(K<AF, Func<A, B>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(mf, ma);\n\n    [Pure]\n    public static K<AF, Func<B, C>> apply<AF, A, B, C>(K<AF, Func<A, B, C>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, D>>> apply<AF, A, B, C, D>(K<AF, Func<A, B, C, D>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, E>>>> apply<AF, A, B, C, D, E>(K<AF, Func<A, B, C, D, E>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, F>>>>> apply<AF, A, B, C, D, E, F>(K<AF, Func<A, B, C, D, E, F>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, G>>>>>> apply<AF, A, B, C, D, E, F, G>(K<AF, Func<A, B, C, D, E, F, G>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> apply<AF, A, B, C, D, E, F, G, H>(K<AF, Func<A, B, C, D, E, F, G, H>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I>(K<AF, Func<A, B, C, D, E, F, G, H, I>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I, J>(K<AF, Func<A, B, C, D, E, F, G, H, I, J>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n\n    [Pure]\n    public static K<AF, Func<B,Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> apply<AF, A, B, C, D, E, F, G, H, I, J, K>(K<AF, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, K<AF, A> ma)\n        where AF : Applicative<AF> =>\n        AF.Apply(AF.Map(curry, mf), ma);\n    \n    [Pure]\n    public static K<F, B> action<F, A, B>(K<F, A> ma, K<F, B> mb)\n        where F : Applicative<F> =>\n        F.Action(ma, mb);\n    \n    [Pure]\n    public static K<F, A> actions<F, A>(IterableNE<K<F, A>> ma)\n        where F : Applicative<F> =>\n        F.Actions(ma);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Zipping\n    //\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second)> zip<F, A, B>(\n        (K<F, A> First, K<F, B> Second) tuple)\n        where F : Applicative<F> =>\n        map((A a, B b) => (a, b), tuple.First).Apply(tuple.Second);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third)> zip<F, A, B, C>(\n        (K<F, A> First, K<F, B> Second, K<F, C> Third) tuple)\n        where F : Applicative<F> =>\n        map((A a, B b, C c) => (a, b, c), tuple.First)\n           .Apply(tuple.Second)\n           .Apply(tuple.Third);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third, D Fourth)> zip<F, A, B, C, D>(\n        (K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth) tuple)\n        where F : Applicative<F> =>\n        map((A a, B b, C c, D d) => (a, b, c, d), tuple.First)\n           .Apply(tuple.Second)\n           .Apply(tuple.Third)\n           .Apply(tuple.Fourth);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"tuple\">Tuple of applicatives to run</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third, D Fourth, E Fifth)> zip<F, A, B, C, D, E>(\n        (K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth, K<F, E> Fifth) tuple)\n        where F : Applicative<F> =>\n        map((A a, B b, C c, D d, E e) => (a, b, c, d, e), tuple.First)\n           .Apply(tuple.Second)\n           .Apply(tuple.Third)\n           .Apply(tuple.Fourth)\n           .Apply(tuple.Fifth);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"First\">First applicative</param>\n    /// <param name=\"Second\">Second applicative</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second)> zip<F, A, B>(\n        K<F, A> First, K<F, B> Second)\n        where F : Applicative<F> =>\n        map((A a, B b) => (a, b), First).Apply(Second);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"First\">First applicative</param>\n    /// <param name=\"Second\">Second applicative</param>\n    /// <param name=\"Third\">Third applicative</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third)> zip<F, A, B, C>(\n        K<F, A> First, K<F, B> Second, K<F, C> Third)\n        where F : Applicative<F> =>\n        map((A a, B b, C c) => (a, b, c), First)\n           .Apply(Second)\n           .Apply(Third);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"First\">First applicative</param>\n    /// <param name=\"Second\">Second applicative</param>\n    /// <param name=\"Third\">Third applicative</param>\n    /// <param name=\"Fourth\">Fourth applicative</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third, D Fourth)> zip<F, A, B, C, D>(\n        K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth)\n        where F : Applicative<F> =>\n        map((A a, B b, C c, D d) => (a, b, c, d), First)\n           .Apply(Second)\n           .Apply(Third)\n           .Apply(Fourth);\n\n    /// <summary>\n    /// Zips applicatives into a tuple\n    /// </summary>\n    /// <param name=\"First\">First applicative</param>\n    /// <param name=\"Second\">Second applicative</param>\n    /// <param name=\"Third\">Third applicative</param>\n    /// <param name=\"Fourth\">Fourth applicative</param>\n    /// <param name=\"Fifth\">Fifth applicative</param>\n    /// <typeparam name=\"F\">Applicative trait type</typeparam>\n    /// <typeparam name=\"A\">First applicative's bound value type</typeparam>\n    /// <typeparam name=\"B\">Second applicative's bound value type</typeparam>\n    /// <typeparam name=\"C\">Third applicative's bound value type</typeparam>\n    /// <typeparam name=\"D\">Fourth applicative's bound value type</typeparam>\n    /// <returns>Zipped applicative</returns>\n    public static K<F, (A First, B Second, C Third, D Fourth, E Fifth)> zip<F, A, B, C, D, E>(\n        K<F, A> First, K<F, B> Second, K<F, C> Third, K<F, D> Fourth, K<F, E> Fifth)\n        where F : Applicative<F> =>\n        map((A a, B b, C c, D d, E e) => (a, b, c, d, e), First)\n           .Apply(Second)\n           .Apply(Third)\n           .Apply(Fourth)\n           .Apply(Fifth);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Applicative/README.md",
    "content": "**Applicative Functors** are a _'stepping stone'_ between functors and monads – they're probably less well-known but have some \ninteresting properties of their own when it comes to lifted expression evaluation. \n\nTwo of the major uses in language-ext is to enable _automatic parallel processing of effectful computations_ and to \n_automatically collect multiple errors when validating_. Those aren't the only usages – all the higher-kinded-types, \nincluding the collection-types, have applicative traits.\n\nThe topic is too large to cover here, so take a look at [Paul Louth's Higher-Kinds series](https://paullouth.com/higher-kinds-in-c-with-language-ext-part-4-applicatives/) for more information."
  },
  {
    "path": "LanguageExt.Core/Traits/Arithmetic/Arithmetic.Prelude.cs",
    "content": "﻿#nullable enable\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Trait\n{\n    /// <summary>\n    /// Find the sum of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static A plus<ARITH, A>(A x, A y) where ARITH : Arithmetic<A> =>\n        ARITH.Add(x, y);\n\n    /// <summary>\n    /// Find the subtract between two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The sum subtract between x and y</returns>\n    [Pure]\n    public static A subtract<ARITH, A>(A x, A y) where ARITH : Arithmetic<A> =>\n        ARITH.Subtract(x, y);\n\n    /// <summary>\n    /// Find the product of two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static A product<ARITH, A>(A x, A y) where ARITH : Arithmetic<A> =>\n        ARITH.Multiply(x, y);\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static A negate<ARITH, A>(A x) where ARITH : Arithmetic<A> =>\n        ARITH.Negate(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Arithmetic/Arithmetic.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt.Traits;\n\n[Trait(\"Num*\")]\npublic interface Arithmetic<A> : Trait\n{\n    /// <summary>\n    /// Find the sum of two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the addition operation</param>\n    /// <param name=\"y\">right hand side of the addition operation</param>\n    /// <returns>The sum of x and y</returns>\n    [Pure]\n    public static abstract A Add(A x, A y);\n    \n    /// <summary>\n    /// Find the difference between two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the subtraction operation</param>\n    /// <param name=\"y\">right hand side of the subtraction operation</param>\n    /// <returns>The difference between x and y</returns>\n    [Pure]\n    public static abstract A Subtract(A x, A y);\n\n    /// <summary>\n    /// Find the product of two values\n    /// </summary>\n    /// <param name=\"x\">left hand side of the product operation</param>\n    /// <param name=\"y\">right hand side of the product operation</param>\n    /// <returns>The product of x and y</returns>\n    [Pure]\n    public static abstract A Multiply(A x, A y);\n\n    /// <summary>\n    /// Negate the value\n    /// </summary>\n    /// <param name=\"x\">Value to negate</param>\n    /// <returns>The negated source value</returns>\n    [Pure]\n    public static abstract A Negate(A x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Biapplicative/Biapplicative.Trait.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Applicative functor \n/// </summary>\n/// <typeparam name=\"FF\">Applicative functor type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic interface Biapplicative<FF> : Bifunctor<FF>\n    where FF : Biapplicative<FF>\n{\n    public static abstract K<FF, C, D> BiApply<A, B, C, D>(\n        K<FF, Func<A, C>, Func<B, D>> ff,\n        K<FF, A, B> fab);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Default implementations\n    //\n\n    public static virtual K<FF, Func<C, E>, Func<D, F>> BiApply<A, B, C, D, E, F>(\n        K<FF, Func<A, C, E>, Func<B, D, F>> ff,\n        K<FF, A, B> fab) =>\n        FF.BiApply(ff.BiMap(curry, curry), fab);\n\n    public static virtual K<FF, E, F> BiApply<A, B, C, D, E, F>(\n        K<FF, Func<A, C, E>, Func<B, D, F>> ff,\n        K<FF, A, B> fab,\n        K<FF, C, D> fcd) =>\n        FF.BiApply(FF.BiApply(ff, fab), fcd);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Bifunctor/Bifunctor.Extensions.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functor module\n/// </summary>\npublic static class BifunctorExtensions\n{\n    /// <summary>\n    /// Functor bimap.  Maps all contained values of `A` to values of `B` and every value of `L` to `M`\n    /// </summary>\n    /// <param name=\"First\">Mapping function</param>\n    /// <param name=\"Second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, M, B> BiMap<F, L, A, M, B>(this K<F, L, A> fab, Func<L, M> First, Func<A, B> Second) \n        where F : Bifunctor<F> =>\n        F.BiMap(First, Second, fab);\n    \n    /// <summary>\n    /// Functor bimap (with function currying)\n    /// </summary>\n    public static K<F, Func<M, N>, Func<B, C>> BiMap<F, L, M, N, A, B, C>(\n        this K<F, L, A> ma, \n        Func<L, M, N> First, \n        Func<A, B, C> Second) \n        where F : Bifunctor<F> =>\n        ma.BiMap(curry(First), curry(Second));    \n    \n    /// <summary>\n    /// Functor bimap (with function currying)\n    /// </summary>\n    public static K<F, Func<M, Func<N, O>>, Func<B, Func<C, D>>> BiMap<F, L, M, N, O, A, B, C, D>(\n        this K<F, L, A> ma, \n        Func<L, M, N, O> First, \n        Func<A, B, C, D> Second) \n        where F : Bifunctor<F> =>\n        ma.BiMap(curry(First), curry(Second));\n\n    /// <summary>\n    /// Functor bimap (with function currying)\n    /// </summary>\n    public static K<F, Func<M, Func<N, Func<O, P>>>, Func<B, Func<C, Func<D, E>>>> BiMap<F, L, M, N, O, P, A, B, C, D, E>(\n        this K<F, L, A> ma,\n        Func<L, M, N, O, P> First,\n        Func<A, B, C, D, E> Second)\n        where F : Bifunctor<F> =>\n        ma.BiMap(curry(First), curry(Second));\n\n    /// <summary>\n    /// Functor bimap (with function currying)\n    /// </summary>\n    public static K<Fnctr, Func<M, Func<N, Func<O, Func<P, Q>>>>, Func<B, Func<C, Func<D, Func<E, F>>>>> BiMap<Fnctr, L, M, N, O, P, Q, A, B, C, D, E, F>(\n        this K<Fnctr, L, A> ma,\n        Func<L, M, N, O, P, Q> First,\n        Func<A, B, C, D, E, F> Second)\n        where Fnctr : Bifunctor<Fnctr> =>\n        ma.BiMap(curry(First), curry(Second));\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, M, A> MapFirst<F, L, A, M>(this K<F, L, A> fab, Func<L, M> first) \n        where F : Bifunctor<F> =>\n        F.MapFirst(first, fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Func<M, N>, A> MapFirst<F, L, A, M, N>(this K<F, L, A> fab, Func<L, M, N> first) \n        where F : Bifunctor<F> =>\n        F.MapFirst(curry(first), fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Func<M, Func<N, O>>, A> MapFirst<F, L, A, M, N, O>(this K<F, L, A> fab, Func<L, M, N, O> first) \n        where F : Bifunctor<F> =>\n        F.MapFirst(curry(first), fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Func<M, Func<N, Func<O, P>>>, A> MapFirst<F, L, A, M, N, O, P>(this K<F, L, A> fab, Func<L, M, N, O, P> first) \n        where F : Bifunctor<F> =>\n        F.MapFirst(curry(first), fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Func<M, Func<N, Func<O, Func<P, Q>>>>, A> MapFirst<F, L, A, M, N, O, P, Q>(this K<F, L, A> fab, Func<L, M, N, O, P, Q> first) \n        where F : Bifunctor<F> =>\n        F.MapFirst(curry(first), fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, M, A> MapFirst<F, L, A, M>(this Func<L, M> first, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapFirst(first, fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Func<M, N>, A> MapFirst<F, L, A, M, N>(this Func<L, M, N> first, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapFirst(curry(first), fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Func<M, Func<N, O>>, A> MapFirst<F, L, A, M, N, O>(this Func<L, M, N, O> first, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapFirst(curry(first), fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Func<M, Func<N, Func<O, P>>>, A> MapFirst<F, L, A, M, N, O, P>(this Func<L, M, N, O, P> first, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapFirst(curry(first), fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Func<M, Func<N, Func<O, Func<P, Q>>>>, A> MapFirst<F, L, A, M, N, O, P, Q>(this Func<L, M, N, O, P, Q> first, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapFirst(curry(first), fab);\n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, L, B> MapSecond<F, L, A, B>(this K<F, L, A> fab, Func<A, B> second) \n        where F : Bifunctor<F> =>\n        F.MapSecond(second, fab);\n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, L, Func<B, C>> MapSecond<F, L, A, B, C>(this K<F, L, A> fab, Func<A, B, C> second) \n        where F : Bifunctor<F> =>\n        F.MapSecond(curry(second), fab);    \n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, L, Func<B, Func<C, D>>> MapSecond<F, L, A, B, C, D>(this K<F, L, A> fab, Func<A, B, C, D> second) \n        where F : Bifunctor<F> =>\n        F.MapSecond(curry(second), fab);    \n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, L, Func<B, Func<C, Func<D, E>>>> MapSecond<F, L, A, B, C, D, E>(this K<F, L, A> fab, Func<A, B, C, D, E> second) \n        where F : Bifunctor<F> =>\n        F.MapSecond(curry(second), fab);\n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<BF, L, Func<B, Func<C, Func<D, Func<E, F>>>>> MapSecond<BF, L, A, B, C, D, E, F>(this K<BF, L, A> fab, Func<A, B, C, D, E, F> second) \n        where BF : Bifunctor<BF> =>\n        BF.MapSecond(curry(second), fab);\n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, L, B> MapSecond<F, L, A, B>(this Func<A, B> second, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapSecond(second, fab);\n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, L, Func<B, C>> MapSecond<F, L, A, B, C>(this Func<A, B, C> second, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapSecond(curry(second), fab);    \n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, L, Func<B, Func<C, D>>> MapSecond<F, L, A, B, C, D>(this Func<A, B, C, D> second, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapSecond(curry(second), fab);    \n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, L, Func<B, Func<C, Func<D, E>>>> MapSecond<F, L, A, B, C, D, E>(this Func<A, B, C, D, E> second, K<F, L, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapSecond(curry(second), fab);     \n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<BF, L, Func<B, Func<C, Func<D, Func<E, F>>>>> MapSecond<BF, L, A, B, C, D, E, F>(this Func<A, B, C, D, E, F> second, K<BF, L, A> fab) \n        where BF : Bifunctor<BF> =>\n        BF.MapSecond(curry(second), fab);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Bifunctor/Bifunctor.Module.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functor module\n/// </summary>\npublic static class Bifunctor\n{\n    /// <summary>\n    /// Functor bimap.  Maps all contained values of `A` to values of `X` and every value of `B` to `Y`\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Q, B> bimap<F, P, A, Q, B>(Func<P, Q> first, Func<A, B> second, K<F, P, A> fab) \n        where F : Bifunctor<F> =>\n        F.BiMap(first, second, fab);\n    \n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, Q, A> first<F, P, A, Q>(Func<P, Q> first, K<F, P, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapFirst(first, fab);\n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static K<F, P, B> second<F, P, A, B>(Func<A, B> second, K<F, P, A> fab) \n        where F : Bifunctor<F> =>\n        F.MapSecond(second, fab);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Bifunctor/Bifunctor.Trait.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Bi-functor\n/// </summary>\n/// <typeparam name=\"F\">Bi-functor self-type</typeparam>\npublic interface Bifunctor<F> \n    where F : Bifunctor<F>\n{\n    /// <summary>\n    /// Functor bimap.  Maps all contained values of `L` to values of `M` and every value of `A` to `B`\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Functor structure</param>\n    /// <typeparam name=\"F\">Functor trait</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static abstract K<F, M, B> BiMap<L, A, M, B>(Func<L, M> first, Func<A, B> second, K<F, L, A> fab);\n\n    /// <summary>\n    /// Map covariantly over the first argument.\n    /// </summary>\n    /// <param name=\"first\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static virtual K<F, M, A> MapFirst<L, A, M>(Func<L, M> first, K<F, L, A> fab) =>\n        F.BiMap(first, identity, fab);\n    \n    /// <summary>\n    /// Map covariantly over the second argument.\n    /// </summary>\n    /// <param name=\"second\">Mapping function</param>\n    /// <param name=\"fab\">Bifunctor structure</param>\n    /// <typeparam name=\"F\">Bifunctor trait</typeparam>\n    /// <returns>Mapped bifunctor</returns>\n    public static virtual K<F, L, B> MapSecond<L, A, B>(Func<A, B> second, K<F, L, A> fab) =>\n        F.BiMap(identity, second, fab);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Bimonad/Bimonad.Extensions.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class BimonadExtensions \n{\n    public static K<M, Y, A> BindFirst<M, X, Y, A>(this K<M, X, A> ma, Func<X, K<M, Y, A>> f) \n        where M : Bimonad<M> =>\n        M.BindFirst(ma, f);\n    \n    public static K<M, X, B> BindSecond<M, X, A, B>(this K<M, X, A> ma, Func<A, K<M, X, B>> f)\n        where M : Bimonad<M> =>\n        M.BindSecond(ma, f);\n    \n    public static K<M, X, A> FlattenFirst<M, X, A>(K<M, K<M, X, A>, A> mma) \n        where M : Bimonad<M> =>\n        M.FlattenFirst(mma);    \n    \n    public static K<M, X, A> FlattenSecond<M, X, A>(K<M, X, K<M, X, A>> mma) \n        where M : Bimonad<M> =>\n        M.FlattenSecond(mma);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Bimonad/Bimonad.Module.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class Bimonad \n{\n    public static K<M, Y, A> bindFirst<M, X, Y, A>(K<M, X, A> ma, Func<X, K<M, Y, A>> f) \n        where M : Bimonad<M> =>\n        M.BindFirst(ma, f);\n    \n    \n    public static K<M, X, B> bindSecond<M, X, A, B>(K<M, X, A> ma, Func<A, K<M, X, B>> f)\n        where M : Bimonad<M> =>\n        M.BindSecond(ma, f);\n    \n    public static K<M, X, A> flattenFirst<M, X, A>(K<M, K<M, X, A>, A> mma) \n        where M : Bimonad<M> =>\n        M.FlattenFirst(mma);    \n    \n    public static K<M, X, A> flattenSecond<M, X, A>(K<M, X, K<M, X, A>> mma) \n        where M : Bimonad<M> =>\n        M.FlattenSecond(mma);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Bimonad/Bimonad.Trait.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic interface Bimonad<M> : Bifunctor<M> \n    where M : Bimonad<M>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Abstract members\n    //\n    \n    public static abstract K<M, Y, A> BindFirst<X, Y, A>(K<M, X, A> ma, Func<X, K<M, Y, A>> f);\n    \n    public static abstract K<M, X, B> BindSecond<X, A, B>(K<M, X, A> ma, Func<A, K<M, X, B>> f);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Default implementations\n    //\n    \n    public static virtual K<M, X, A> FlattenFirst<X, A>(K<M, K<M, X, A>, A> mma) =>\n        M.BindFirst(mma, identity);    \n    \n    public static virtual K<M, X, A> FlattenSecond<X, A>(K<M, X, K<M, X, A>> mma) =>\n        M.BindSecond(mma, identity);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Bool/Bool.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Trait for things that have true and false values.\n/// </summary>\n[Trait(\"Bool*\")]\npublic interface Bool<A> : Trait\n{\n    /// <summary>\n    /// Returns True\n    /// </summary>\n    /// <returns>True</returns>\n    [Pure]\n    public static abstract A True();\n\n    /// <summary>\n    /// Returns False\n    /// </summary>\n    /// <returns>False</returns>\n    [Pure]\n    public static abstract A False();\n\n    /// <summary>\n    /// Returns the result of the logical AND operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical AND operation between `a` and `b`</returns>\n    [Pure]\n    public static abstract A And(A a, A b);\n\n    /// <summary>\n    /// Returns the result of the logical OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical OR operation between `a` and `b`</returns>\n    [Pure]\n    public static abstract A Or(A a, A b);\n\n    /// <summary>\n    /// Returns the result of the logical NOT operation on `a`\n    /// </summary>\n    /// <returns>The result of the logical NOT operation on `a`</returns>\n    [Pure]\n    public static abstract A Not(A a);\n\n    /// <summary>\n    /// Returns the result of the logical exclusive-OR operation between `a` and `b`\n    /// </summary>\n    /// <returns>The result of the logical exclusive-OR operation between `a` and `b`</returns>\n    [Pure]\n    public static abstract A XOr(A a, A b);\n\n    /// <summary>\n    /// Logical implication\n    /// </summary>\n    /// <returns>If `a` is true that implies `b`, else `true`</returns>\n    [Pure]\n    public static abstract A Implies(A a, A b);\n\n    /// <summary>\n    /// Logical bi-conditional.  Both `a` and `b` must be `true`, or both `a` and `b` must\n    /// be false.\n    /// </summary>\n    /// <returns>`true` if `a == b`, `false` otherwise</returns>\n    [Pure]\n    public static abstract A BiCondition(A a, A b);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Choice/Choice.Laws.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functions that test that Alternative laws hold for the `F` Alternative provided.\n/// </summary>\n/// <para>\n///     choose(pure(a), pure(b)) = pure(a)\n/// </para>\n/// <remarks>\n/// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n/// can be proven to be true.  If your Alternative structure doesn't have `Equals` then you\n/// must provide the optional `equals` parameter so that the equality of outcomes can be tested.\n/// </remarks>\n/// <typeparam name=\"F\">Alternative type</typeparam>\npublic static class ChoiceLaw<F>\n    where F : Choice<F>, Applicative<F>\n{\n    /// <summary>\n    /// Assert that the Alternative laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Unit assert(K<F, int> failure, Func<K<F, int>, K<F, int>, bool>? equals = null) =>\n        validate(failure, equals)\n           .IfFail(errors => errors.Throw());\n\n    /// <summary>\n    /// Validate that the Alternative laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> validate(K<F, int> failure, Func<K<F, int>, K<F, int>, bool>? equals = null)\n    {\n        equals ??= (fa, fb) => fa.Equals(fb);\n        return leftZeroLaw(failure, equals)  >>\n               rightZeroLaw(failure, equals) >>\n               leftCatchLaw(equals);\n    }\n\n    /// <summary>\n    /// Left-zero law\n    /// </summary>\n    /// <remarks>\n    ///    choose(empty, pure(x)) = pure(x)\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> leftZeroLaw(K<F, int> failure, Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var fa = failure;\n        var fb = F.Pure(100);\n        var fr = choose(fa, fb);\n\n        return equals(fr, fb) \n                   ? unit\n                   : Error.New($\"Choice left-zero law does not hold for {typeof(F).Name}\");\n    }\n\n    /// <summary>\n    /// Right-zero law\n    /// </summary>\n    /// <remarks>\n    ///    choose(pure(x), empty) = pure(x)\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> rightZeroLaw(K<F, int> failure, Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var fa = F.Pure(100);\n        var fb = failure;\n        var fr = choose(fa, fb);\n\n        return equals(fr, fa) \n                   ? unit\n                   : Error.New($\"Choice right-zero law does not hold for {typeof(F).Name}\");\n    }\n    \n    /// <summary>\n    /// Left catch law\n    /// </summary>\n    /// <remarks>\n    ///    choose(pure(x), pure(y)) = pure(x)\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your Alternative structure doesn't have `Equals` then\n    /// you must provide the optional `equals` parameter so that the equality of outcomes can\n    /// be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> leftCatchLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var fa = F.Pure(100);\n        var fb = F.Pure(200);\n        var fr = choose(fa, fb);\n\n        return equals(fr, fa) \n                   ? unit\n                   : Error.New($\"Choice left-catch law does not hold for {typeof(F).Name}\");\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Choice/Choice.Module.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic static class Choice\n{\n    /// <summary>\n    /// Where `F` defines some notion of failure or choice, this function picks the\n    /// first argument that succeeds.  So, if `fa` succeeds, then `fa` is returned;\n    /// if it fails, then `fb` is returned.\n    /// </summary>\n    /// <param name=\"fa\">First structure to test</param>\n    /// <param name=\"fb\">Second structure to return if the first one fails</param>\n    /// <typeparam name=\"F\">Alternative structure type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>First argument to succeed</returns>\n    public static K<F, A> choose<F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Choice<F> =>\n        F.Choose(fa, fb);\n    \n    /// <summary>\n    /// One or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    ///\n    /// Will always succeed if at least one item has been yielded.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: It is important that the `F` applicative-type overrides `Apply` (the one with `Func` laziness) in its\n    /// trait-implementations otherwise this will likely result in a stack-overflow. \n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>One or more values</returns>\n    [Pure]\n    public static K<F, Seq<A>> some<F, A>(K<F, A> fa)\n        where F : Choice<F>, Applicative<F>\n    {\n        return some_v();\n        \n        K<F, Seq<A>> many_v() =>\n            F.Choose(some_v(), F.Pure(Seq<A>()));\n\n        K<F, Seq<A>> some_v() =>\n            Append<A>.cons.Map(fa).Apply(memoK(many_v));\n    }\n    \n    /// <summary>\n    /// Zero or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    /// Will always succeed.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: It is important that the `F` applicative-type overrides `ApplyLazy` in its trait-implementations\n    /// otherwise this will likely result in a stack-overflow. \n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>Zero or more values</returns>\n    [Pure]\n    public static K<F, Seq<A>> many<F, A>(K<F, A> fa)\n        where F : Choice<F>, Applicative<F>\n    {\n        return many_v();\n        \n        K<F, Seq<A>> many_v() =>\n            F.Choose(some_v(), F.Pure(Seq<A>()));\n\n        K<F, Seq<A>> some_v() =>\n            Append<A>.cons.Map(fa).Apply(memoK(many_v));\n    }\n        \n    static class Append<A>\n    {\n        public static readonly Func<A, Func<Seq<A>, Seq<A>>> cons =\n            x => xs => x.Cons(xs);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Choice/Choice.Trait.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Choose between two structures.  If the first succeeds, then return it; otherwise return the second.\n/// </summary>\n/// <typeparam name=\"F\">Structure type</typeparam>\npublic interface Choice<F>\n    where F : Choice<F>\n{\n    /// <summary>\n    /// Where `F` defines some notion of failure or choice, this function picks the\n    /// first argument that succeeds.  So, if `fa` succeeds, then `fa` is returned;\n    /// if it fails, then `fb` is returned.\n    /// </summary>\n    /// <param name=\"fa\">First structure to test</param>\n    /// <param name=\"fb\">Second structure to return if the first one fails</param>\n    /// <typeparam name=\"F\">Alternative structure type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>First argument to succeed</returns>\n    static abstract K<F, A> Choose<A>(K<F, A> fa, K<F, A> fb);\n    \n    /// <summary>\n    /// Where `F` defines some notion of failure or choice, this function picks the\n    /// first argument that succeeds.  So, if `fa` succeeds, then `fa` is returned;\n    /// if it fails, then `fb` is returned.\n    /// </summary>\n    /// <param name=\"fa\">First structure to test</param>\n    /// <param name=\"fb\">Second structure to return if the first one fails</param>\n    /// <typeparam name=\"F\">Alternative structure type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>First argument to succeed</returns>\n    static abstract K<F, A> Choose<A>(K<F, A> fa, Memo<F, A> fb);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Choice/Extensions/Choice.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ChoiceExtensions\n{\n    /// <param name=\"fa\">First structure to test</param>\n    /// <typeparam name=\"F\">Alternative structure type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    extension<F, A>(K<F, A> fa) \n        where F : Choice<F>\n    {\n        /// <summary>\n        /// Where `F` defines some notion of failure or choice, this function picks the\n        /// first argument that succeeds.  So, if `fa` succeeds, then `fa` is returned;\n        /// if it fails, then `fb` is returned.\n        /// </summary>\n        /// <param name=\"fb\">Second structure to return if the first one fails</param>\n        /// <returns>First argument to succeed</returns>\n        public K<F, A> Choose(K<F, A> fb) =>\n            F.Choose(fa, fb);\n\n        /// <summary>\n        /// Where `F` defines some notion of failure or choice, this function picks the\n        /// first argument that succeeds.  So, if `fa` succeeds, then `fa` is returned;\n        /// if it fails, then `fb` is returned.\n        /// </summary>\n        /// <param name=\"fb\">Second structure to return if the first one fails</param>\n        /// <returns>First argument to succeed</returns>\n        public K<F, A> Choose(Memo<F, A> fb) =>\n            F.Choose(fa, fb);\n    }\n\n    /// <param name=\"v\">Applicative functor</param>\n    extension<F, A>(K<F, A> v) \n        where F : Choice<F>, Applicative<F>\n    {\n        /// <summary>\n        /// One or more...\n        /// </summary>\n        /// <remarks>\n        /// Run the applicative functor repeatedly, collecting the results, until failure.\n        /// \n        /// Will always succeed if at least one item has been yielded.\n        /// </remarks>\n        /// <returns>One or more values</returns>\n        public K<F, Seq<A>> Some() =>\n            Choice.some(v);\n\n        /// <summary>\n        /// Zero or more...\n        /// </summary>\n        /// <remarks>\n        /// Run the applicative functor repeatedly, collecting the results, until failure.\n        /// \n        /// Will always succeed.\n        /// </remarks>\n        /// <returns>Zero or more values</returns>\n        public K<F, Seq<A>> Many() =>\n            Choice.many(v);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Choice/Operators/Choice.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class ChoiceExtensions\n{\n    extension<F, A>(K<F, A> _)\n        where F : Choice<F>\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static K<F, A> operator |(K<F, A> lhs, K<F, A> rhs) =>\n            lhs.Choose(rhs);\n    }\n\n    extension<F, A>(K<F, A> _)\n        where F : Choice<F>, Applicative<F>\n    {\n        /// <summary>\n        /// Choice operator.  Usually means if the first argument succeeds, return it, otherwise return the second\n        /// argument.\n        /// </summary>\n        /// <param name=\"lhs\">Left hand side operand</param>\n        /// <param name=\"rhs\">Right hand side operand</param>\n        /// <returns></returns>\n        public static K<F, A> operator |(K<F, A> lhs, Pure<A> rhs) =>\n            lhs.Choose(F.Pure(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Choice/Prelude/Choice.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Where `F` defines some notion of failure or choice, this function picks the\n    /// first argument that succeeds.  So, if `fa` succeeds, then `fa` is returned;\n    /// if it fails, then `fb` is returned.\n    /// </summary>\n    /// <param name=\"fa\">First structure to test</param>\n    /// <param name=\"fb\">Second structure to return if the first one fails</param>\n    /// <typeparam name=\"F\">Alternative structure type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>First argument to succeed</returns>\n    public static K<F, A> choose<F, A>(K<F, A> fa, K<F, A> fb)\n        where F : Choice<F> =>\n        Choice.choose(fa, fb);\n    \n    /// <summary>\n    /// One or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    ///\n    /// Will always succeed if at least one item has been yielded.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: It is important that the `F` applicative-type overrides `Apply` (the one with `Func` laziness) in its\n    /// trait-implementations otherwise this will likely result in a stack-overflow. \n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>One or more values</returns>\n    [Pure]\n    public static K<F, Seq<A>> some<F, A>(K<F, A> fa)\n        where F : Choice<F>, Applicative<F> =>\n        Choice.some(fa);\n\n    /// <summary>\n    /// Zero or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    /// Will always succeed.\n    /// </remarks>\n    /// <remarks>\n    /// NOTE: It is important that the `F` applicative-type overrides `ApplyLazy` in its trait-implementations\n    /// otherwise this will likely result in a stack-overflow. \n    /// </remarks>\n    /// <param name=\"fa\">Applicative functor</param>\n    /// <returns>Zero or more values</returns>\n    [Pure]\n    public static K<F, Seq<A>> many<F, A>(K<F, A> fa)\n        where F : Choice<F>, Applicative<F> =>\n        Choice.many(fa);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Choice/README.md",
    "content": "`Choice<F>` allows for propagation of 'failure' and 'choice' (in some appropriate sense, depending on the type).\n\n`Choice` is a `SemigroupK`, but has a `Choose` method, rather than relying on the `SemigroupK.Combine` method, (which \nnow has a default implementation of invoking `Choose`).  That creates a new semantic meaning for `Choose`, which is \nabout choice propagation rather than the broader meaning of `Combine`.  It also allows for `Choose` and `Combine` to \nhave separate implementations depending on the type.\n\nThe way to think about `Choose` and the inherited `SemigroupK.Combine` methods is:\n* `Choose` is the failure/choice propagation operator: `|`\n* `Combine` is the concatenation/combination/addition operator: `+`\n\nAny type that supports the `Choice` trait should also implement the `|` operator, to enable easy choice/failure \npropagation.  If there is a different implementation of `Combine` (rather than accepting the default), then the type \nshould also implement the `+` operator.\n\n`ChoiceLaw` can help you test your implementation:\n\n    choose(Pure(a),   Pure(b))  = Pure(a)\n    choose(Fail,      Pure(b))  = Pure(b)\n    choose(Pure(a),   Fail)     = Pure(a)\n    choose(Fail [1],  Fail [2]) = Fail [2]\n\nIt also tests the `Applicative` and `Functor` laws."
  },
  {
    "path": "LanguageExt.Core/Traits/Chronicaler/Chronicaler.Extensions.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\npublic static class ChronicalerExtensions\n{\n    /// <summary>\n    /// `Memento` is an action that executes the action within this structure, returning either\n    /// its record, if it ended with `Confess`, or its final value otherwise, with any record\n    /// added to the current record.\n    ///\n    /// Similar to 'Catch' in the 'Fallible' trait, but with a notion of non-fatal errors (which\n    /// are accumulated) vs. fatal errors (which are caught without accumulating).\n    /// </summary>\n    /// <param name=\"ma\">Action to memento</param>\n    public static K<M, Either<Ch, A>> Memento<Ch, M, A>(this K<M, A> ma)\n        where M : Chronicaler<M, Ch> =>\n        M.Memento(ma);\n        \n    /// <summary>\n    /// `Absolve` is an action that executes this structure and discards any record it had.\n    /// The `defaultValue` will be used if the action ended via `Confess`. \n    /// </summary>\n    /// <param name=\"defaultValue\"></param>\n    /// <param name=\"ma\">Action to absolve</param>\n    public static K<M, A> Absolve<Ch, M, A>(this K<M, A> ma, A defaultValue)\n        where M : Chronicaler<M, Ch> =>\n        M.Absolve(defaultValue, ma);\n        \n    /// <summary>\n    /// `Condemn` is an action that executes the structure and keeps its value\n    /// only if it had no record. Otherwise, the value (if any) will be discarded\n    /// and only the record kept.\n    /// \n    /// This can be seen as converting non-fatal errors into fatal ones.\n    /// </summary>\n    /// <param name=\"ma\">Action to condemn</param>\n    public static K<M, A> Condemn<Ch, M, A>(this K<M, A> ma)\n        where M : Chronicaler<M, Ch> =>\n        M.Condemn(ma);\n        \n    /// <summary>\n    /// An action that executes the structure and applies the function `f` to its output, leaving\n    /// the return value unchanged.-\n    /// </summary>\n    /// <remarks>\n    /// Equivalent to `censor` for the 'Writable` trait.\n    /// </remarks>\n    /// <param name=\"f\">Censoring function</param>\n    /// <param name=\"ma\">Action to censor</param>\n    public static K<M, A> Censor<Ch, M, A>(this K<M, A> ma, Func<Ch, Ch> f)\n        where M : Chronicaler<M, Ch> =>\n        M.Censor(f, ma);\n        \n    /// <summary>\n    /// Construct a new chronicle with `these`.\n    /// </summary>\n    /// <param name=\"these\">What to chronicle</param>\n    /// <returns>Chronicle structure</returns>\n    public static K<M, A> Chronicle<Ch, M, A>(this These<Ch, A> ma)\n        where M : Chronicaler<M, Ch> =>\n        M.Chronicle(ma);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Chronicaler/Chronicaler.Module.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\npublic static class Chronicaler<Ch>\n{\n    /// <summary>\n    /// `Dictate` is an action that records the output `value`.\n    /// Equivalent to `tell` for the `Writable` traits.\n    /// </summary>\n    /// <param name=\"value\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static K<M, A> dictate<M, A>(A value) \n        where M : Chronicaler<M, Ch> =>\n        M.Dictate(value);\n    \n    /// <summary>\n    /// `Confess` is an action that ends with a final output `value`.\n    /// Equivalent to `fail` for the 'Fallible' trait.\n    /// </summary>\n    /// <param name=\"confession\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static K<M, A> confess<M, A>(Ch confession) \n        where M : Chronicaler<M, Ch> =>\n        M.Confess<A>(confession);\n\n    /// <summary>\n    /// `Memento` is an action that executes the action within this structure, returning either\n    /// its record, if it ended with `Confess`, or its final value otherwise, with any record\n    /// added to the current record.\n    ///\n    /// Similar to 'Catch' in the 'Fallible' trait, but with a notion of non-fatal errors (which\n    /// are accumulated) vs. fatal errors (which are caught without accumulating).\n    /// </summary>\n    /// <param name=\"ma\">Action to memento</param>\n    public static K<M, Either<Ch, A>> memento<M, A>(K<M, A> ma)\n        where M : Chronicaler<M, Ch> =>\n        M.Memento(ma);\n        \n    /// <summary>\n    /// `Absolve` is an action that executes this structure and discards any record it had.\n    /// The `defaultValue` will be used if the action ended via `Confess`. \n    /// </summary>\n    /// <param name=\"defaultValue\"></param>\n    /// <param name=\"ma\">Action to absolve</param>\n    public static K<M, A> absolve<M, A>(A defaultValue, K<M, A> ma)\n        where M : Chronicaler<M, Ch> =>\n        M.Absolve(defaultValue, ma);\n        \n    /// <summary>\n    /// `Condemn` is an action that executes the structure and keeps its value\n    /// only if it had no record. Otherwise, the value (if any) will be discarded\n    /// and only the record kept.\n    /// \n    /// This can be seen as converting non-fatal errors into fatal ones.\n    /// </summary>\n    /// <param name=\"ma\">Action to condemn</param>\n    public static K<M, A> condemn<M, A>(K<M, A> ma)\n        where M : Chronicaler<M, Ch> =>\n        M.Condemn(ma);\n        \n    /// <summary>\n    /// An action that executes the structure and applies the function `f` to its output, leaving\n    /// the return value unchanged.-\n    /// </summary>\n    /// <remarks>\n    /// Equivalent to `censor` for the 'Writable` trait.\n    /// </remarks>\n    /// <param name=\"f\">Censoring function</param>\n    /// <param name=\"ma\">Action to censor</param>\n    public static K<M, A> censor<M, A>(Func<Ch, Ch> f, K<M, A> ma)\n        where M : Chronicaler<M, Ch> =>\n        M.Censor(f, ma);\n        \n    /// <summary>\n    /// Construct a new chronicle with `these`.\n    /// </summary>\n    /// <param name=\"these\">What to chronicle</param>\n    /// <returns>Chronicle structure</returns>\n    public static K<M, A> chronicle<M, A>(These<Ch, A> ma)\n        where M : Chronicaler<M, Ch> =>\n        M.Chronicle(ma);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Chronicaler/Chronicaler.Trait.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Hybrid error/writer monad class that allows both accumulating outputs and aborting computation with a final output.\n/// \n/// The expected use case is for computations with a notion of fatal vs. non-fatal errors.\n/// </summary>\n/// <typeparam name=\"M\">Self</typeparam>\n/// <typeparam name=\"Ch\">Chronicle type</typeparam>\npublic interface Chronicaler<M, Ch>\n    where M : Chronicaler<M, Ch>\n{\n    /// <summary>\n    /// `Dictate` is an action that records the output `value`.\n    /// Equivalent to `tell` for the `Writable` traits.\n    /// </summary>\n    /// <param name=\"value\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static abstract K<M, A> Dictate<A>(A value);\n    \n    /// <summary>\n    /// `Confess` is an action that ends with a final output `value`.\n    /// Equivalent to `fail` for the 'Fallible' trait.\n    /// </summary>\n    /// <param name=\"confession\">Value to construct with</param>\n    /// <returns>Chronicle structure</returns>\n    public static abstract K<M, A> Confess<A>(Ch confession);\n\n    /// <summary>\n    /// `Memento` is an action that executes the action within this structure, returning either\n    /// its record, if it ended with `Confess`, or its final value otherwise, with any record\n    /// added to the current record.\n    ///\n    /// Similar to 'Catch' in the 'Fallible' trait, but with a notion of non-fatal errors (which\n    /// are accumulated) vs. fatal errors (which are caught without accumulating).\n    /// </summary>\n    /// <param name=\"ma\">Action to memento</param>\n    public static abstract K<M, Either<Ch, A>> Memento<A>(K<M, A> ma);\n        \n    /// <summary>\n    /// `Absolve` is an action that executes this structure and discards any record it had.\n    /// The `defaultValue` will be used if the action ended via `Confess`. \n    /// </summary>\n    /// <param name=\"defaultValue\"></param>\n    /// <param name=\"ma\">Action to absolve</param>\n    public static abstract K<M, A> Absolve<A>(A defaultValue, K<M, A> ma);\n        \n    /// <summary>\n    /// `Condemn` is an action that executes the structure and keeps its value\n    /// only if it had no record. Otherwise, the value (if any) will be discarded\n    /// and only the record kept.\n    /// \n    /// This can be seen as converting non-fatal errors into fatal ones.\n    /// </summary>\n    /// <param name=\"ma\">Action to condemn</param>\n    public static abstract K<M, A> Condemn<A>(K<M, A> ma);\n        \n    /// <summary>\n    /// An action that executes the structure and applies the function `f` to its output, leaving\n    /// the return value unchanged.-\n    /// </summary>\n    /// <remarks>\n    /// Equivalent to `censor` for the 'Writable` trait.\n    /// </remarks>\n    /// <param name=\"f\">Censoring function</param>\n    /// <param name=\"ma\">Action to censor</param>\n    public static abstract K<M, A> Censor<A>(Func<Ch, Ch> f, K<M, A> ma);\n        \n    /// <summary>\n    /// Construct a new chronicle with `these`.\n    /// </summary>\n    /// <param name=\"these\">What to chronicle</param>\n    /// <returns>Chronicle structure</returns>\n    public static abstract K<M, A> Chronicle<A>(These<Ch, A> ma);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Cofunctor/Cofunctor.Extensions.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\npublic static class CofunctorExtensions\n{\n    /// <summary>\n    /// The class of contravariant functors.\n    /// Whereas one can think of a `Functor` as containing or producing values, a contravariant functor is a functor that\n    /// can be thought of as consuming values.\n    /// \n    /// Contravariant functors are referred to colloquially as Cofunctor, even though the dual of a `Functor` is just\n    /// a `Functor`. \n    /// </summary>\n    public static K<F, A> Comap<F, A, B>(this K<F, B> fb, Func<A, B> f) \n        where F : Cofunctor<F> =>\n        F.Comap(f, fb);\n    \n    /// <summary>\n    /// The class of contravariant functors.\n    /// Whereas one can think of a `Functor` as containing or producing values, a contravariant functor is a functor that\n    /// can be thought of as consuming values.\n    /// \n    /// Contravariant functors are referred to colloquially as Cofunctor, even though the dual of a `Functor` is just\n    /// a `Functor`. \n    /// </summary>\n    public static K<F, A> Comap<F, A, B>(this Func<A, B> f, K<F, B> fb) \n        where F : Cofunctor<F> =>\n        F.Comap(f, fb);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Cofunctor/Cofunctor.Module.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\npublic static class Cofunctor\n{\n    /// <summary>\n    /// The class of contravariant functors.\n    /// Whereas one can think of a `Functor` as containing or producing values, a contravariant functor is a functor that\n    /// can be thought of as consuming values.\n    /// \n    /// Contravariant functors are referred to colloquially as Cofunctor, even though the dual of a `Functor` is just\n    /// a `Functor`. \n    /// </summary>\n    public static K<F, A> contraMap<F, A, B>(Func<A, B> f, K<F, B> fb) \n        where F : Cofunctor<F> =>\n        F.Comap(f, fb);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Cofunctor/Cofunctor.Prelude.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// The class of contravariant functors.\n    /// Whereas one can think of a `Functor` as containing or producing values, a contravariant functor is a functor that\n    /// can be thought of as consuming values.\n    /// \n    /// Contravariant functors are referred to colloquially as Cofunctor, even though the dual of a `Functor` is just\n    /// a `Functor`. \n    /// </summary>\n    public static K<F, A> contraMap<F, A, B>(Func<A, B> f, K<F, B> fb) \n        where F : Cofunctor<F> =>\n        F.Comap(f, fb);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Cofunctor/Cofunctor.Trait.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// The class of contravariant functors.\n/// Whereas one can think of a `Functor` as containing or producing values, a contravariant functor is a functor that\n/// can be thought of as consuming values.\n/// \n/// Contravariant functors are referred to colloquially as Cofunctor, even though the dual of a `Functor` is just\n/// a `Functor`. \n/// </summary>\n/// <typeparam name=\"F\">Self-referring type</typeparam>\npublic interface Cofunctor<F>\n{\n    public static abstract K<F, A> Comap<A, B>(Func<A, B> f, K<F, B> fb);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Const/Const.cs",
    "content": "﻿#nullable enable\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Constant value trait\n/// </summary>\n/// <typeparam name=\"TYPE\"></typeparam>\n[Trait(\"Const*\")]\npublic interface Const<out TYPE> : Trait\n{\n    public static abstract TYPE Value { get; }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Coproduct/Coproduct.Extensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Co-product trait (abstract version of `Either`)\n/// </summary>\n/// <typeparam name=\"F\">Self</typeparam>\npublic static class CoproductExtensions\n{\n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static C Match<F, A, B, C>(this K<F, A, B> fab, Func<A, C> Left, Func<B, C> Right) \n        where F : Coproduct<F> =>\n        F.Match(Left, Right, fab);\n        \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static C Match<F, A, B, C>(this K<F, A, B> fab, C Left, Func<B, C> Right) \n        where F : Coproduct<F> =>\n        F.Match(Left, Right, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static C Match<F, A, B, C>(this K<F, A, B> fab, Func<A, C> Left, C Right) \n        where F : Coproduct<F> =>\n        F.Match(Left, Right, fab);\n        \n    /// <summary>\n    /// Pattern-match the left value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the right value or the result of mapping the left with the function provided</returns>\n    public static B IfLeft<F, A, B>(this K<F, A, B> fab, Func<A, B> Left) \n        where F : Coproduct<F> =>\n        F.IfLeft(Left, fab);\n        \n    /// <summary>\n    /// Pattern-match the left value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Default value to use if the state is `Left`</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the right value or provided `Left` value</returns>\n    public static B IfLeft<F, A, B>(this K<F, A, B> fab, B Left) \n        where F : Coproduct<F> =>\n        F.IfLeft(Left, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the left value or the result of mapping the right value with the function provided</returns>\n    public static A IfRight<F, A, B>(this K<F, A, B> fab, Func<B, A> Right) \n        where F : Coproduct<F> =>\n        F.IfRight(Right, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Right\">Default value to use if the state is `Right`</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the left value or provided `Right` value</returns>\n    public static A IfRight<F, A, B>(this K<F, A, B> fab, A Right) \n        where F : Coproduct<F> =>\n        F.IfRight(Right, fab);\n\n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static (Seq<A> Lefts, Seq<B> Rights) Partition<FF, F, A, B>(this K<FF, K<F, A, B>> fabs)\n        where F : Coproduct<F>\n        where FF : Foldable<FF> =>\n        F.Partition(fabs);\n\n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static (Seq<A> Lefts, Seq<B> Rights) PartitionSequence<F, A, B>(this IEnumerable<K<F, A, B>> fabs)\n        where F : Coproduct<F> =>\n        F.Partition(fabs.AsIterable());    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Coproduct/Coproduct.Module.cs",
    "content": "using System.Collections.Generic;\n\nnamespace LanguageExt.Traits;\n\npublic static class Coproduct\n{\n    /// <summary>\n    /// Construct a coproduct structure in a 'Left' state\n    /// </summary>\n    /// <param name=\"value\">Left value</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Constructed coproduct structure</returns>\n    public static K<F, A, B> left<F, A, B>(A value)\n        where F : Coproduct<F> =>\n        F.Left<A, B>(value);\n    \n    /// <summary>\n    /// Construct a coproduct structure in a 'Left' state\n    /// </summary>\n    /// <param name=\"value\">Left value</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Constructed coproduct structure</returns>\n    public static K<F, A, B> right<F, A, B>(B value) \n        where F : Coproduct<F> =>\n        F.Right<A, B>(value);\n\n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static (Seq<A> Lefts, Seq<B> Rights) partition<FF, F, A, B>(K<FF, K<F, A, B>> fabs)\n        where F : Coproduct<F>\n        where FF : Foldable<FF> =>\n        F.Partition(fabs);\n\n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static (Seq<A> Lefts, Seq<B> Rights) partitionSequence<F, A, B>(IEnumerable<K<F, A, B>> fabs)\n        where F : Coproduct<F> =>\n        F.Partition(fabs.AsIterable());     \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Coproduct/Coproduct.Trait.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Co-product trait (abstract version of `Either`)\n/// </summary>\n/// <typeparam name=\"F\">Self</typeparam>\npublic interface Coproduct<F> : CoproductCons<F>\n    where F : Coproduct<F>\n{\n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static abstract C Match<A, B, C>(Func<A, C> Left, Func<B, C> Right, K<F, A, B> fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static virtual C Match<A, B, C>(C Left, Func<B, C> Right, K<F, A, B> fab) =>\n        F.Match(_ => Left, Right, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static virtual C Match<A, B, C>(Func<A, C> Left, C Right, K<F, A, B> fab) =>\n        F.Match(Left, _ => Right, fab);\n    \n    /// <summary>\n    /// Pattern-match the left value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the right value or the result of mapping the left with the function provided</returns>\n    public static virtual B IfLeft<A, B>(Func<A, B> Left, K<F, A, B> fab) =>\n        F.Match(Left, identity, fab);\n\n    /// <summary>\n    /// Pattern-match the left value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Default value to use if the state is `Left`</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the right value or provided `Left` value</returns>\n    public static virtual B IfLeft<A, B>(B Left, K<F, A, B> fab) =>\n        F.Match(_ => Left, identity, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the left value or the result of mapping the right value with the function provided</returns>\n    public static virtual A IfRight<A, B>(Func<B, A> Right,  K<F, A, B> fab) =>\n        F.Match(identity, Right, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Right\">Default value to use if the state is `Right`</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the left value or provided `Right` value</returns>\n    public static virtual A IfRight<A, B>(A Right, K<F, A, B> fab) => \n        F.Match(identity, _ => Right, fab);    \n    \n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static virtual (Seq<A> Lefts, Seq<B> Rights) Partition<FF, A, B>(K<FF, K<F, A, B>> fabs)\n        where FF : Foldable<FF> =>\n        fabs.Fold((Lefts: Seq<A>(), Rights: Seq<B>()), \n                  (s, fab) => fab.Match(Left: l => s with { Lefts = s.Lefts.Add(l) },\n                                        Right: r => s with { Rights = s.Rights.Add(r) }));\n    \n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences, then return the left sequence.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Left sequence</returns>\n    public static virtual Seq<A> Lefts<G, A, B>(K<G, K<F, A, B>> fabs)\n        where G : Foldable<G> =>\n        fabs.Fold(Seq<A>(), (s, fab) => fab.Match(Left: s.Add, Right: s));\n    \n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences, then return the right sequence.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Right sequence</returns>\n    public static virtual Seq<B> Rights<G, A, B>(K<G, K<F, A, B>> fabs)\n        where G : Foldable<G> =>\n        fabs.Fold(Seq<B>(), (s, fab) => fab.Match(Left: s, Right: s.Add));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/CoproductCons/CoproductCons.Module.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class CoproductCons\n{\n    /// <summary>\n    /// Construct a coproduct structure in a 'Left' state\n    /// </summary>\n    /// <param name=\"value\">Left value</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Constructed coproduct structure</returns>\n    public static K<F, A, B> left<F, A, B>(A value)\n        where F : CoproductCons<F> =>\n        F.Left<A, B>(value);\n    \n    /// <summary>\n    /// Construct a coproduct structure in a 'Left' state\n    /// </summary>\n    /// <param name=\"value\">Left value</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Constructed coproduct structure</returns>\n    public static K<F, A, B> right<F, A, B>(B value) \n        where F : CoproductCons<F> =>\n        F.Right<A, B>(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/CoproductCons/CoproductCons.Trait.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Co-product trait (abstract version of `Either`)\n/// </summary>\n/// <typeparam name=\"F\">Self</typeparam>\npublic interface CoproductCons<in F>\n    where F : CoproductCons<F>\n{\n    /// <summary>\n    /// Construct a coproduct structure in a 'Left' state\n    /// </summary>\n    /// <param name=\"value\">Left value</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Constructed coproduct structure</returns>\n    public static abstract K<F, A, B> Left<A, B>(A value);\n    \n    /// <summary>\n    /// Construct a coproduct structure in a 'Left' state\n    /// </summary>\n    /// <param name=\"value\">Left value</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Constructed coproduct structure</returns>\n    public static abstract K<F, A, B> Right<A, B>(B value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/CoproductK/CoproductK.Extensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Co-product trait (abstract version of `Either`)\n/// </summary>\n/// <typeparam name=\"F\">Self</typeparam>\npublic static class CoproductKExtensions\n{\n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static K<F, A, C> Match<F, A, B, C>(this K<F, A, B> fab, Func<A, C> Left, Func<B, C> Right) \n        where F : CoproductK<F> =>\n        F.Match(Left, Right, fab);\n\n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static K<F, A, (Seq<A> Left, Seq<B> Right)> Partition<FF, F, A, B>(this K<FF, K<F, A, B>> fabs)\n        where F : CoproductK<F>, Bimonad<F>\n        where FF : Foldable<FF> =>\n        CoproductK.partition(fabs);    \n\n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static K<F, A, (Seq<A> Left, Seq<B> Right)> PartitionSequence<F, A, B>(this IEnumerable<K<F, A, B>> fabs)\n        where F : CoproductK<F>, Bimonad<F> =>\n        CoproductK.partitionSequence(fabs);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/CoproductK/CoproductK.Module.cs",
    "content": "using static LanguageExt.Prelude;\nusing System.Collections.Generic;\n\nnamespace LanguageExt.Traits;\n\npublic static class CoproductK\n{\n    /// <summary>\n    /// Construct a coproduct structure in a 'Left' state\n    /// </summary>\n    /// <param name=\"value\">Left value</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Constructed coproduct structure</returns>\n    public static K<F, A, B> left<F, A, B>(A value)\n        where F : CoproductK<F> =>\n        F.Left<A, B>(value);\n    \n    /// <summary>\n    /// Construct a coproduct structure in a 'Left' state\n    /// </summary>\n    /// <param name=\"value\">Left value</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Constructed coproduct structure</returns>\n    public static K<F, A, B> right<F, A, B>(B value) \n        where F : CoproductK<F> =>\n        F.Right<A, B>(value);\n\n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static K<F, A, (Seq<A> Left, Seq<B> Right)> partition<FF, F, A, B>(K<FF, K<F, A, B>> fabs)\n        where F : CoproductK<F>, Bimonad<F>\n        where FF : Foldable<FF> =>\n        fabs.Fold(F.Right<A, (Seq<A> Left, Seq<B> Right)>((Left: Seq<A>(), Right: Seq<B>())),\n                  (fs, fab) =>\n                      fs.BindSecond(s => fab.Match(l => s with { Left = s.Left.Add(l) },\n                                                   r => s with { Right = s.Right.Add(r) })));\n\n    /// <summary>\n    /// Partition the foldable of coproducts into two left and right sequences.\n    /// </summary>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Two left and right sequences</returns>\n    public static K<F, A, (Seq<A> Left, Seq<B> Right)> partitionSequence<F, A, B>(IEnumerable<K<F, A, B>> fabs)\n        where F : CoproductK<F>, Bimonad<F> =>\n        partition(fabs.AsIterable());       \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/CoproductK/CoproductK.Trait.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Co-product trait (abstract version of `Either`)\n/// </summary>\n/// <typeparam name=\"F\">Self</typeparam>\npublic interface CoproductK<F> : CoproductCons<F>\n    where F : CoproductK<F>\n{\n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static abstract K<F, A, C> Match<A, B, C>(Func<A, C> Left, Func<B, C> Right, K<F, A, B> fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static virtual K<F, A, C> Match<A, B, C>(C Left, Func<B, C> Right, K<F, A, B> fab) =>\n        F.Match(_ => Left, Right, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <typeparam name=\"C\">Result type</typeparam>\n    /// <returns>Result of mapping either the left or right values with the functions provided</returns>\n    public static virtual K<F, A, C> Match<A, B, C>(Func<A, C> Left, C Right, K<F, A, B> fab) =>\n        F.Match(Left, _ => Right, fab);\n    \n    /// <summary>\n    /// Pattern-match the left value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Function to map the left value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the right value or the result of mapping the left with the function provided</returns>\n    public static virtual K<F, A, B> IfLeft<A, B>(Func<A, B> Left, K<F, A, B> fab) =>\n        F.Match(Left, identity, fab);\n\n    /// <summary>\n    /// Pattern-match the left value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Left\">Default value to use if the state is `Left`</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the right value or provided `Left` value</returns>\n    public static virtual K<F, A, B> IfLeft<A, B>(B Left, K<F, A, B> fab) =>\n        F.Match(_ => Left, identity, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Right\">Function to map the right value to a result</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the left value or the result of mapping the right value with the function provided</returns>\n    public static virtual K<F, A, A> IfRight<A, B>(Func<B, A> Right,  K<F, A, B> fab) =>\n        F.Match(identity, Right, fab);\n    \n    /// <summary>\n    /// Pattern-match either the left or right value in the coproduct \n    /// </summary>\n    /// <param name=\"fab\">Coproduct value</param>\n    /// <param name=\"Right\">Default value to use if the state is `Right`</param>\n    /// <typeparam name=\"F\">Coproduct trait type</typeparam>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Either the left value or provided `Right` value</returns>\n    public static virtual K<F, A, A> IfRight<A, B>(A Right, K<F, A, B> fab) => \n        F.Match(identity, _ => Right, fab);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Coreadable/Coreadable.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class CoreadableExtensions\n{\n    public static K<M, Env1, A> Local<M, Env, Env1, A>(this K<M, Env, A> ma, Func<Env, Env1> f)\n        where M : Coreadable<M> =>\n        M.Local(f, ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Coreadable/Coreadable.Module.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Traits;\n\npublic static class Coreadable\n{\n    public static K<M, Env, Env> ask<M, Env>()\n        where M : Coreadable<M> =>\n        M.Ask<Env>();\n\n    public static K<M, Env, A> asks<M, Env, A>(Func<Env, A> f)\n        where M : Coreadable<M> =>\n        M.Asks(f);\n\n    public static K<M, Env, A> asksM<M, Env, A>(Func<Env, K<M, Env, A>> f)\n        where M : Coreadable<M>, Bimonad<M> =>\n        M.FlattenSecond(M.Asks(f));\n\n    public static K<M, Env1, A> local<M, Env, Env1, A>(Func<Env, Env1> f, K<M, Env, A> ma)\n        where M : Coreadable<M> =>\n        M.Local(f, ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Coreadable/Coreadable.Trait.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Traits;\n\npublic interface Coreadable<M>\n    where M : Coreadable<M>\n{\n    public static abstract K<M, Env, A> Asks<Env, A>(Func<Env, A> f);\n\n    public static virtual K<M, Env, Env> Ask<Env>() =>\n        M.Asks<Env, Env>(Prelude.identity);\n\n    public static abstract K<M, Env1, A> Local<Env, Env1, A>(\n        Func<Env, Env1> f,\n        K<M, Env, A> ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Decidable/Decidable.Module.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// A `Divisible` contravariant functor is the contravariant analogue of `Applicative`.\n///\n/// Continuing the intuition that 'Contravariant' functors (`Cofunctor`) consume input, a 'Divisible'\n/// contravariant functor also has the ability to be composed \"beside\" another contravariant\n/// functor.\n/// </summary>\n/// <typeparam name=\"F\">Self referring type</typeparam>\npublic static class Decidable\n{\n    /// <summary>\n    /// Acts as identity to 'Choose'.\n    /// </summary>\n    public static K<F, A> lose<F, A>(Func<A, Void> f)\n        where F : Decidable<F> =>\n        F.Lose(f);\n\n    /// <summary>\n    /// Acts as identity to 'Choose'.\n    /// </summary>\n    /// <remarks>\n    ///     lost = lose(identity)\n    /// </remarks>\n    public static K<F, Void> lost<F>()\n        where F : Decidable<F> =>\n        lose<F, Void>(identity);\n\n    /// <summary>\n    /// Fan out the input \n    /// </summary>\n    public static K<F, A> route<F, A, B, C>(Func<A, Either<B, C>> f, K<F, B> fb, K<F, C> fc)\n        where F : Decidable<F> =>\n        F.Route(f, fb, fc);\n\n    /// <summary>\n    /// Fan out the input \n    /// </summary>\n    /// <remarks>\n    ///     route(fb, fc) = route(id, fb, fc)\n    /// </remarks>\n    public static K<F, Either<A, B>> route<F, A, B>(K<F, A> fa, K<F, B> fb)\n        where F : Decidable<F> =>\n        route<F, Either<A, B>, A, B>(identity, fa, fb);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Decidable/Decidable.Prelude.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A `Divisible` contravariant functor is the contravariant analogue of `Applicative`.\n///\n/// Continuing the intuition that 'Contravariant' functors (`Cofunctor`) consume input, a 'Divisible'\n/// contravariant functor also has the ability to be composed \"beside\" another contravariant\n/// functor.\n/// </summary>\n/// <typeparam name=\"F\">Self referring type</typeparam>\npublic static partial class Prelude\n{\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Decidable/Decidable.Trait.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// A `Decidable` contravariant functor is the contravariant analogue of `Alternative`.\n/// \n/// Noting the superclass constraint that `f` must also be `Divisible`, a `Decidable` functor has the ability to\n/// \"fan out\" input, under the intuition that contravariant functors consume input.\n/// </summary>\n/// <typeparam name=\"F\">Self-referring type</typeparam>\npublic interface Decidable<F> : Divisible<F>\n{\n    /// <summary>\n    /// Acts as identity to 'Choose'.\n    /// </summary>\n    public static abstract K<F, A> Lose<A>(Func<A, Void> f);\n    \n    /// <summary>\n    /// Fan out the input \n    /// </summary>\n    public static abstract K<F, A> Route<A, B, C>(Func<A, Either<B, C>> f, K<F, B> fb, K<F, C> fc);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Deriving/Deriving.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// `Deriving` is an alias for `NaturalIso` \n/// </summary>\n/// <remarks>\n/// It is aliased to be more declarative when used in trait-implementations.  The idea is that your\n/// `Supertype` is a wrapper around your `Subtype`.  Use of the `Deriving` trait, and the `Deriving.*` interfaces,\n/// makes trait-implementations much easier.\n/// </remarks>\n/// <typeparam name=\"Supertype\">Wrapper type that is a super-type wrapper of `Subtype`</typeparam>\n/// <typeparam name=\"Subtype\">`Subtype` of `Supertype`</typeparam>\npublic interface Deriving<Supertype, Subtype> : \n    NaturalIso<Supertype, Subtype>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Divisible/Divisible.Module.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// A `Divisible` contravariant functor is the contravariant analogue of `Applicative`.\n///\n/// Continuing the intuition that 'Contravariant' functors (`Cofunctor`) consume input, a 'Divisible'\n/// contravariant functor also has the ability to be composed \"beside\" another contravariant\n/// functor.\n/// </summary>\n/// <typeparam name=\"F\">Self referring type</typeparam>\npublic static class Divisible\n{\n    /// <summary>\n    /// If one can handle split `a` into `(b, c)`, as well as handle `b`s and `c`s, then one can handle `a`s\n    /// </summary>\n    public static K<F, A> divide<F, A, B, C>(Func<A, (B Left, C Right)> f, K<F, B> fb, K<F, C> fc) \n        where F : Divisible<F> =>\n        F.Divide(f, fb, fc);\n\n    /// <summary>\n    /// Conquer acts as an identity for combining `Divisible` functors.\n    /// </summary>\n    public static K<F, A> conquer<F, A>() \n        where F : Divisible<F> =>\n        F.Conquer<A>();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Divisible/Divisible.Prelude.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A `Divisible` contravariant functor is the contravariant analogue of `Applicative`.\n///\n/// Continuing the intuition that 'Contravariant' functors (`Cofunctor`) consume input, a 'Divisible'\n/// contravariant functor also has the ability to be composed \"beside\" another contravariant\n/// functor.\n/// </summary>\n/// <typeparam name=\"F\">Self referring type</typeparam>\npublic static partial class Prelude\n{\n    /// <summary>\n    /// If one can handle split `a` into `(b, c)`, as well as handle `b`s and `c`s, then one can handle `a`s\n    /// </summary>\n    public static K<F, A> divide<F, A, B, C>(Func<A, (B Left, C Right)> f, K<F, B> fb, K<F, C> fc) \n        where F : Divisible<F> =>\n        F.Divide(f, fb, fc);\n\n    /// <summary>\n    /// Conquer acts as an identity for combining `Divisible` functors.\n    /// </summary>\n    public static K<F, A> conquer<F, A>() \n        where F : Divisible<F> =>\n        F.Conquer<A>();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Divisible/Divisible.Trait.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// A `Divisible` contravariant functor is the contravariant analogue of `Applicative`.\n///\n/// Continuing the intuition that 'Contravariant' functors (`Cofunctor`) consume input, a 'Divisible'\n/// contravariant functor also has the ability to be composed \"beside\" another contravariant\n/// functor.\n/// </summary>\n/// <typeparam name=\"F\">Self referring type</typeparam>\npublic interface Divisible<F> : Cofunctor<F>\n{\n    /// <summary>\n    /// If one can handle split `a` into `(b, c)`, as well as handle `b`s and `c`s, then one can handle `a`s\n    /// </summary>\n    public static abstract K<F, A> Divide<A, B, C>(Func<A, (B Left, C Right)> f, K<F, B> fb, K<F, C> fc);\n    \n    /// <summary>\n    /// Conquer acts as an identity for combining `Divisible` functors.\n    /// </summary>\n    public static abstract K<F, A> Conquer<A>();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Domain/Amount.cs",
    "content": "using System;\nusing System.Numerics;\n\nnamespace LanguageExt.Traits.Domain;\n\n/// <summary>\n/// A typical use of domain types is representing quantities, such as the amount of money in USD in a bank account,\n/// or the file-size in bytes. Being able to compare, add, and subtract amounts is essential.\n/// \n/// Generally, we cannot multiply or divide two compatible amounts and expect to get the amount of the same type back. \n///\n/// Unless we’re modeling mathematical entities, such as probabilities or points on an elliptic curve.. Multiplying two\n/// dollars by two dollars gives four squared dollars. I don’t know about you, but I’m yet to find a practical use for\n/// squared dollars.\n/// \n/// Multiplying amounts by a dimensionless number, however, is meaningful. There is nothing wrong with a banking app\n/// increasing a dollar amount by ten percent or a disk utility dividing the total number of allocated bytes by the file\n/// count.\n/// \n/// The appropriate mathematical abstraction for amounts is vector spaces. Vector space is a set with additional\n/// operations defined on the elements of this set: addition, subtraction, and scalar multiplication, such that\n/// behaviors of these operations satisfy a few natural axioms.\n/// </summary>\n/// <remarks>This is the same as `VectorSpace` but with ordering</remarks>\n/// <typeparam name=\"SELF\">Type implementing this interface</typeparam>\n/// <typeparam name=\"SCALAR\">Scalar units</typeparam>\npublic interface Amount<SELF, SCALAR> :\n    VectorSpace<SELF, SCALAR>,\n    IComparable<SELF>,\n    IComparisonOperators<SELF, SELF, bool>\n    where SELF : Amount<SELF, SCALAR>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Domain/DomainType.cs",
    "content": "namespace LanguageExt.Traits.Domain;\n\n/// <summary>\n/// Fundamental base-trait for implementing domain-types.  This is the basis for `Identifier`, `Locus`, `VectorSpace`,\n/// and `Quantity`.  It allows the derived types to be safely instantiated from simpler values, like `int`, `float`, etc.\n/// And, to be converted back from the domain-type to the simpler representation.\n/// </summary>\n/// <typeparam name=\"SELF\">Type implementing this interface</typeparam>\npublic interface DomainType<SELF> \n    where SELF : DomainType<SELF>;\n    \n/// <summary>\n/// Fundamental base-trait for implementing domain-types.  This is the basis for `Identifier`, `Locus`, `VectorSpace`,\n/// and `Quantity`.  It allows the derived types to be safely instantiated from simpler values, like `int`, `float`, etc.\n/// And, to be converted back from the domain-type to the simpler representation.\n/// </summary>\n/// <typeparam name=\"SELF\">Type implementing this interface</typeparam>\n/// <typeparam name=\"REPR\">Underlying representation</typeparam>\npublic interface DomainType<SELF, REPR> : DomainType<SELF> \n    where SELF : DomainType<SELF, REPR> \n{\n    /// <summary>\n    /// Creates a domain value from its representation value \n    /// </summary>\n    /// <returns>\n    /// Either an `Error` or a validly constructed `SELF`.\n    /// </returns>\n    public static abstract Fin<SELF> From(REPR repr);\n\n    /// <summary>\n    /// Creates a domain value from its representation value \n    /// </summary>\n    /// <returns>\n    /// Either throws an exception or returns a validly constructed `SELF`.\n    /// </returns>\n    public static virtual SELF FromUnsafe(REPR repr) =>\n        SELF.From(repr).ThrowIfFail();                    \n    \n    /// <summary>\n    /// Extracts the representation value from its domain value  \n    /// </summary>\n    REPR To();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Domain/Identifier.cs",
    "content": "using System;\nusing System.Numerics;\n\nnamespace LanguageExt.Traits.Domain;\n\n/// <summary>\n/// One of the most common uses of domain types is a transparent handle for an entity or an asset in the real world,\n/// such as a customer identifier in an online store or an employee number in a payroll application. I call these types\n/// identifiers.\n/// \n/// Identifiers have no structure, i.e., we don’t care about their internal representation. The only fundamental\n/// requirement is the ability to compare values of those types for equality. This lack of structure suggests an\n/// appropriate mathematical model for such types: a set, a collection of distinct objects.\n/// </summary>\n/// <typeparam name=\"SELF\">Type implementing this interface</typeparam>\npublic interface Identifier<SELF> : \n    DomainType<SELF>,\n    IEquatable<SELF>,\n    IEqualityOperators<SELF, SELF, bool>\n    where SELF : Identifier<SELF>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Domain/Locus.cs",
    "content": "// TODO: Decide whether you want to develop this idea or not\n// https://mmapped.blog/posts/25-domain-types.html\n\nusing System;\nusing System.Numerics;\n\nnamespace LanguageExt.Traits.Domain;\n\n/// <summary>\n/// Working with space-like structures, such as time and space, poses an interesting challenge. Spaces have two types of\n/// values: absolute positions and relative distances.\n///\n/// Positions refer to points in space, such as timestamps or geographical coordinates. Distances represent a difference\n/// between two such points.\n///\n/// Some natural languages acknowledge the distinction and offer different words for these concepts, such as o’clock vs.\n/// hours.\n///\n/// While distances behave the same way as `Amount`, positions are trickier. We can compare, order, and subtract them to\n/// compute the distance between two points. For example, subtracting 5 am on Friday from 3 am on Saturday gives us\n/// twenty-two hours. Adding or multiplying these dates makes no sense, however. This semantic demands a new class of\n/// types, loci (plural of locus).\n///\n/// We can view each position as a distance from a fixed origin point. Changing the origin or the distance type calls\n/// for a new locus type.\n/// </summary>\n/// <typeparam name=\"SELF\">Type implementing this interface</typeparam>\n/// <typeparam name=\"DISTANCE\">Additive units</typeparam>\n/// <typeparam name=\"DISTANCE_SCALAR\">Distance scalar units</typeparam>\npublic interface Locus<SELF, DISTANCE, DISTANCE_SCALAR> :\n    Identifier<SELF>,\n    IComparable<SELF>,\n    IComparisonOperators<SELF, SELF, bool>,\n    IUnaryNegationOperators<SELF, SELF>,\n    IAdditiveIdentity<SELF, SELF>,\n    IAdditionOperators<SELF, DISTANCE, SELF>,\n    ISubtractionOperators<SELF, SELF, DISTANCE>\n    where SELF : Locus<SELF, DISTANCE, DISTANCE_SCALAR>\n    where DISTANCE : Amount<DISTANCE, DISTANCE_SCALAR>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Domain/README.md",
    "content": "\nInspired by: https://mmapped.blog/posts/25-domain-types.html"
  },
  {
    "path": "LanguageExt.Core/Traits/Domain/VectorSpace.cs",
    "content": "using System;\nusing System.Numerics;\n\nnamespace LanguageExt.Traits.Domain;\n\n/// <summary>\n/// A typical use of domain types is representing quantities, such as the amount of money in USD in a bank account,\n/// or the file-size in bytes. Being able to compare, add, and subtract amounts is essential.\n/// \n/// Generally, we cannot multiply or divide two compatible amounts and expect to get the amount of the same type back. \n///\n/// Unless we’re modeling mathematical entities, such as probabilities or points on an elliptic curve.. Multiplying two\n/// dollars by two dollars gives four squared dollars. I don’t know about you, but I’m yet to find a practical use for\n/// squared dollars.\n/// \n/// Multiplying amounts by a dimensionless number, however, is meaningful. There is nothing wrong with a banking app\n/// increasing a dollar amount by ten percent or a disk utility dividing the total number of allocated bytes by the file\n/// count.\n/// \n/// The appropriate mathematical abstraction for amounts is vector spaces. Vector space is a set with additional\n/// operations defined on the elements of this set: addition, subtraction, and scalar multiplication, such that\n/// behaviors of these operations satisfy a few natural axioms.\n/// </summary>\n/// <typeparam name=\"SELF\">Type implementing this interface</typeparam>\n/// <typeparam name=\"SCALAR\">Scalar units</typeparam>\npublic interface VectorSpace<SELF, SCALAR> :\n    Identifier<SELF>,\n    IUnaryNegationOperators<SELF, SELF>,\n    IAdditionOperators<SELF, SELF, SELF>,\n    ISubtractionOperators<SELF, SELF, SELF>,\n    IMultiplyOperators<SELF, SCALAR, SELF>,\n    IDivisionOperators<SELF, SCALAR, SELF>\n    where SELF : VectorSpace<SELF, SCALAR>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Eq/Eq.Extensions.cs",
    "content": "﻿using System.Collections.Generic;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class EqExtensions\n{\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals<EQ, A>(this A[] x, A[] y) where EQ : Eq<A> =>\n        EqArray<EQ, A>.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"mx\">The left hand side of the equality operation</param>\n    /// <param name=\"my\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals<EQ, A>(this A? mx, A? my)\n        where EQ : Eq<A>\n        where A : struct =>\n        (mx, my) switch\n        {\n            (null, null) => true,\n            (_, null)    => false,\n            (null, _)    => false,\n            var (x, y)   => EQ.Equals(x.Value, y.Value)\n        };\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool Equals<EQ, A>(this IEnumerable<A> x, IEnumerable<A> y) where EQ : Eq<A> =>\n        EqEnumerable<EQ, A>.Equals(x, y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Eq/Eq.Module.cs",
    "content": "﻿using System.Collections.Generic;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Eq\n{\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<A>(A x, A y) where A : Eq<A> =>\n        A.Equals(x, y);\n    \n    class EqEqualityComparer<EqA, A> : IEqualityComparer<A>\n        where EqA : Eq<A>\n    {\n        public bool Equals(A? x, A? y) =>\n            (x, y) switch\n            {\n                (null, null) => true,\n                (null, _)    => false,\n                (_, null)    => false,\n                var (nx, ny) => EqA.Equals(nx, ny)\n            };\n\n        public int GetHashCode(A obj) =>\n            EqA.GetHashCode(obj);\n    }\n\n    public static IEqualityComparer<A> Comparer<EqA, A>()\n        where EqA : Eq<A> =>\n        Cache<EqA, A>.Default;\n\n    static class Cache<EqA, A>\n        where EqA : Eq<A>\n    {\n        public static readonly IEqualityComparer<A> Default = new EqEqualityComparer<EqA, A>();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Eq/Eq.Prelude.cs",
    "content": "﻿using LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(A x, A y) where EQ : Eq<A> =>\n        EQ.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(Option<A> x, Option<A> y) where EQ : Eq<A> =>\n        x.Equals<EQ>(y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, L, R>(Either<L, R> x, Either<L, R> y) where EQ : Eq<R> =>\n        x.Equals<EQ>(y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQA, EQB, A, B>(Either<A, B> x, Either<A, B> y)\n        where EQA : Eq<A>\n        where EQB : Eq<B> =>\n        x.Equals<EQA, EQB>(y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"mx\">The left hand side of the equality operation</param>\n    /// <param name=\"my\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(A? mx, A? my)\n        where EQ : Eq<A>\n        where A : struct =>\n        (mx, my) switch\n        {\n            (null, null) => true,\n            (_, null)    => false,\n            (null, _)    => false,\n            var (x, y)   => EQ.Equals(x.Value, y.Value)\n        };\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(Lst<A> x, Lst<A> y) where EQ : Eq<A> =>\n        EqLst<EQ, A>.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(HashSet<A> x, HashSet<A> y) where EQ : Eq<A> =>\n        EqHashSet<EQ, A>.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(Que<A> x, Que<A> y) where EQ : Eq<A> =>\n        EqQue<EQ, A>.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(Set<A> x, Set<A> y) where EQ : Eq<A> =>\n        EqSet<EQ, A>.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(Arr<A> x, Arr<A> y) where EQ : Eq<A> =>\n        EqArr<EQ, A>.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(A[] x, A[] y) where EQ : Eq<A> =>\n        EqArray<EQ, A>.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(IEnumerable<A> x, IEnumerable<A> y) where EQ : Eq<A> =>\n        EqEnumerable<EQ, A>.Equals(x, y);\n\n    /// <summary>\n    /// Structural equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static bool equals<EQ, A>(Seq<A> x, Seq<A> y) where EQ : Eq<A> =>\n        EqSeq<EQ, A>.Equals(x, y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Eq/Eq.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Equality trait\n/// </summary>\n/// <typeparam name=\"A\">\n/// The type for which equality is defined\n/// </typeparam>\n[Trait(\"Eq*\")]\npublic interface Eq<in A> : Hashable<A>, Trait\n{\n    /// <summary>\n    /// Equality test\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the equality operation</param>\n    /// <param name=\"y\">The right hand side of the equality operation</param>\n    /// <returns>True if x and y are equal</returns>\n    [Pure]\n    public static abstract bool Equals(A x, A y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Extensions.Catch.E.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Extensions for higher-kinded structures that have a failure state `E`\n/// </summary>\n/// <typeparam name=\"F\">Higher-kinded structure</typeparam>\n/// <typeparam name=\"E\">Failure type</typeparam>\npublic static partial class FallibleExtensionsE\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Error catching by predicate\n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        Func<E, bool> Predicate,\n        Func<E, K<F, A>> Fail) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, Predicate, Fail);\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"ma\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<M, A> Catch<E, M, A>(\n        this K<M, A> ma,\n        Func<E, bool> Predicate,\n        Func<E, IO<A>> Fail) \n        where M : Fallible<E, M>, MonadIO<M> =>\n        M.Catch(ma, Predicate, e => M.LiftIO(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        Func<E, bool> Predicate,\n        Func<E, E> Fail) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, Predicate, e => F.Fail<A>(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        Func<E, bool> Predicate,\n        Func<E, A> Fail) \n        where F : Fallible<E, F>, Applicative<F> =>\n        F.Catch(fa, Predicate, e => F.Pure(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the catch structure and run its action if a match.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"@catch\">Catch structure created by the `@catch` functions.  Contains the\n    /// match predicate and action</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of running the catch structure's action if `fa` is in\n    /// a failed state and the</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        CatchM<E, F, A> @catch) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, @catch.Match, @catch.Action);\n        \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Error catching by equality\n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"ma\">`Fallible` structure</param>\n    /// <param name=\"Match\">Error to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<M, A> Catch<E, M, A>(\n        this K<M, A> ma,\n        E Match,\n        Func<E, IO<A>> Fail) \n        where M : Fallible<E, M>, MonadIO<M> =>\n        M.Catch(ma, e => Match?.Equals(e) ?? false, e => M.LiftIO(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Match\">Error to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        E Match,\n        Func<E, E> Fail) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, e => Match?.Equals(e) ?? false, e => F.Fail<A>(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Match\">Error to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        E Match,\n        Func<E, A> Fail) \n        where F : Fallible<E, F>, Applicative<F> =>\n        F.Catch(fa, e => Match?.Equals(e) ?? false, e => F.Pure(Fail(e)));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Catch all errors \n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        Func<E, K<F, A>> Fail) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, _ => true, Fail);\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"ma\">`Fallible` structure</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<M, A> Catch<E, M, A>(\n        this K<M, A> ma,\n        Func<E, IO<A>> Fail) \n        where M : Fallible<E, M>, MonadIO<M> =>\n        M.Catch(ma, _ => true, e => M.LiftIO(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        Func<E, E> Fail) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, _ => true, e => F.Fail<A>(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<E, F, A>(\n        this K<F, A> fa,\n        Func<E, A> Fail) \n        where F : Fallible<E, F>, Applicative<F> =>\n        F.Catch(fa, _ => true, e => F.Pure(Fail(e)));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Catch all errors and provide alternative values \n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with `fail`.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<E, F, A>(this K<F, A> fa, Fail<E> fail) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, _ => true, _ => F.Fail<A>(fail.Value));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with `fail`.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<E, F, A>(this K<F, A> fa, E fail) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, _ => true, _ => F.Fail<A>(fail));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with\n    /// the success value and cancelling the failure.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<E, F, A>(this K<F, A> fa, Pure<A> value) \n        where F : Fallible<E, F>, Applicative<F> =>\n        F.Catch(fa, _ => true, _ => F.Pure(value.Value));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with\n    /// the success value and cancelling the failure.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<E, F, A>(this K<F, A> fa, A value) \n        where F : Fallible<E, F>, Applicative<F> =>\n        F.Catch(fa, _ => true, _ => F.Pure(value));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with\n    /// the `alternative` computation, which may succeed or fail.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<E, F, A>(this K<F, A> fa, K<F, A> alternative) \n        where F : Fallible<E, F> =>\n        F.Catch(fa, _ => true, _ => alternative);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Extensions.Catch.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Extensions for higher-kinded structures that have a failure state `Error`\n/// </summary>\n/// <typeparam name=\"F\">Higher-kinded structure</typeparam>\npublic static partial class FallibleExtensions\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Error catching by predicate\n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Func<Error, bool> Predicate,\n        Func<Error, K<F, A>> Fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, Predicate, Fail);\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"ma\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<M, A> CatchIO<M, A>(\n        this K<M, A> ma,\n        Func<Error, bool> Predicate,\n        Func<Error, K<IO, A>> Fail) \n        where M : Fallible<M>, MonadIO<M> =>\n        M.Catch(ma, Predicate, e => M.LiftIO(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Func<Error, bool> Predicate,\n        Func<Error, Error> Fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, Predicate, e => F.Fail<A>(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Func<Error, bool> Predicate,\n        Func<Error, A> Fail) \n        where F : Fallible<F>, Applicative<F> =>\n        F.Catch(fa, Predicate, e => F.Pure(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the catch structure and run its action if a match.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"@catch\">Catch structure created by the `@catch` functions.  Contains the\n    /// match predicate and action</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of running the catch structure's action if `fa` is in\n    /// a failed state and the</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        CatchM<Error, F, A> @catch) \n        where F : Fallible<F> =>\n        F.Catch(fa, @catch.Match, @catch.Action);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Error catching by equality\n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Match\">Error to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Error Match,\n        Func<Error, K<F, A>> Fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, Match.Is, Fail);\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"ma\">`Fallible` structure</param>\n    /// <param name=\"Match\">Error to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<M, A> CatchIO<M, A>(\n        this K<M, A> ma,\n        Error Match,\n        Func<Error, K<IO, A>> Fail) \n        where M : Fallible<M>, MonadIO<M> =>\n        M.Catch(ma, Match.Is, e => M.LiftIO(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Match\">Error to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Error Match,\n        Func<Error, Error> Fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, Match.Is, e => F.Fail<A>(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Match\">Error to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Error Match,\n        Func<Error, A> Fail) \n        where F : Fallible<F>, Applicative<F> =>\n        F.Catch(fa, Match.Is, e => F.Pure(Fail(e)));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Error catching by error code equality\n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Code\">Error code to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        int Code,\n        Func<Error, K<F, A>> Fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, e => Code == e.Code || e.HasCode(Code), Fail);\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"ma\">`Fallible` structure</param>\n    /// <param name=\"Code\">Error code to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<M, A> CatchIO<M, A>(\n        this K<M, A> ma,\n        int Code,\n        Func<Error, K<IO, A>> Fail) \n        where M : Fallible<M>, MonadIO<M> =>\n        M.Catch(ma, e => Code == e.Code || e.HasCode(Code), e => M.LiftIO(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Code\">Error code to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        int Code,\n        Func<Error, Error> Fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, e => Code == e.Code || e.HasCode(Code), e => F.Fail<A>(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Code\">Error code to match to</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        int Code,\n        Func<Error, A> Fail) \n        where F : Fallible<F>, Applicative<F> =>\n        F.Catch(fa, e => Code == e.Code || e.HasCode(Code), e => F.Pure(Fail(e)));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Catch all errors \n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Func<Error, K<F, A>> Fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, _ => true, Fail);\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"ma\">`Fallible` structure</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<M, A> CatchIO<M, A>(\n        this K<M, A> ma,\n        Func<Error, K<IO, A>> Fail) \n        where M : Fallible<M>, MonadIO<M> =>\n        M.Catch(ma, _ => true, e => M.LiftIO(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Func<Error, Error> Fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, _ => true, e => F.Fail<A>(Fail(e)));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If, it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static K<F, A> Catch<F, A>(\n        this K<F, A> fa,\n        Func<Error, A> Fail) \n        where F : Fallible<F>, Applicative<F> =>\n        F.Catch(fa, _ => true, e => F.Pure(Fail(e)));\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Catch all errors and provide alternative values \n    //\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with `fail`.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<F, A>(this K<F, A> fa, Fail<Error> fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, _ => true, _ => F.Fail<A>(fail.Value));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with `fail`.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<F, A>(this K<F, A> fa, Error fail) \n        where F : Fallible<F> =>\n        F.Catch(fa, _ => true, _ => F.Fail<A>(fail));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with\n    /// the success value and cancelling the failure.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<F, A>(this K<F, A> fa, Pure<A> value) \n        where F : Fallible<F>, Applicative<F> =>\n        F.Catch(fa, _ => true, _ => F.Pure(value.Value));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with\n    /// the success value and cancelling the failure.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<F, A>(this K<F, A> fa, A value) \n        where F : Fallible<F>, Applicative<F> =>\n        F.Catch(fa, _ => true, _ => F.Pure(value));\n    \n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, replace the failure value with\n    /// the `alternative` computation, which may succeed or fail.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    public static K<F, A> Catch<F, A>(this K<F, A> fa, K<F, A> alternative) \n        where F : Fallible<F> =>\n        F.Catch(fa, _ => true, _ => alternative);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Extensions.Fails.E.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FallibleExtensionsE\n{\n    /// <summary>\n    /// Partitions a foldable of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> Fails<E, F, M, A>(\n        this K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure(Seq.empty<E>()),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(_ => M.Pure(s))\n                                  .Catch((E e) => M.Pure(s.Add(e)))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> Fails<E, M, A>(\n        this Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, Seq, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> Fails<E, M, A>(\n        this Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, Iterable, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> Fails<E, M, A>(\n        this Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, Lst, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> Fails<E, M, A>(\n        this HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, HashSet, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> Fails<E, M, A>(\n        this Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, Set, M, A>();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Extensions.Fails.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FallibleExtensions\n{\n    /// <summary>\n    /// Partitions a foldable of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> Fails<F, M, A>(\n        this K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure(Seq.empty<Error>()),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(_ => M.Pure(s))\n                                  .Catch(e => M.Pure(s.Add(e)))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> Fails<M, A>(\n        this Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> Fails<M, A>(\n        this Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> Fails<M, A>(\n        this Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> Fails<M, A>(\n        this HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> Fails<M, A>(\n        this Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Extensions.Partition.E.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FallibleExtensionsE\n{\n    /// <summary>\n    /// Partitions a foldable of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> PartitionFallible<E, F, M, A>(\n        this K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure((Fails: Seq.empty<E>(), Succs: Seq.empty<A>())),\n                 ma => ms => ms.Bind(\n                           s => ma.Map(a => (s.Fails, s.Succs.Add(a)))\n                                  .Catch((E e) => M.Pure((s.Fails.Add(e), s.Succs)))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> PartitionFallible<E, M, A>(\n        this Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, Seq, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> PartitionFallible<E, M, A>(\n        this Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, Iterable, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> PartitionFallible<E, M, A>(\n        this Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, Lst, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> PartitionFallible<E, M, A>(\n        this IEnumerable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        Iterable.createRange(fma).PartitionFallible<E, Iterable, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> PartitionFallible<E, M, A>(\n        this HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, HashSet, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> PartitionFallible<E, M, A>(\n        this Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, Set, M, A>(); \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Extensions.Partition.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FallibleExtensions\n{\n    /// <summary>\n    /// Partitions a foldable of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> PartitionFallible<F, M, A>(\n        this K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure((Fails: Seq.empty<Error>(), Succs: Seq.empty<A>())),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(a => M.Pure((s.Fails, s.Succs.Add(a))))\n                                  .Catch(e => M.Pure((s.Fails.Add(e), s.Succs)))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> PartitionFallible<M, A>(\n        this Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> PartitionFallible<M, A>(\n        this Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> PartitionFallible<M, A>(\n        this Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> PartitionFallible<M, A>(\n        this IEnumerable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        Iterable.createRange(fma).PartitionFallible();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> PartitionFallible<M, A>(\n        this HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> PartitionFallible<M, A>(\n        this Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Extensions.Succs.E.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FallibleExtensionsE\n{\n    /// <summary>\n    /// Partitions a foldable of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<E, F, M, A>(\n        this K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure(Seq.empty<A>()),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(a => M.Pure(s.Add(a)))\n                                  .Catch((E _) => M.Pure(s))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<E, M, A>(\n        this Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, Seq, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<E, M, A>(\n        this Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, Iterable, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<E, M, A>(\n        this Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, Lst, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<E, M, A>(\n        this HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, HashSet, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<E, M, A>(\n        this Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, Set, M, A>();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Extensions.Succs.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FallibleExtensions\n{\n    /// <summary>\n    /// Partitions a foldable of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<F, M, A>(\n        this K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure(Seq.empty<A>()),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(a => M.Pure(s.Add(a)))\n                                  .Catch(_ => M.Pure(s))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<M, A>(\n        this Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<M, A>(\n        this Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<M, A>(\n        this Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<M, A>(\n        this HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> Succs<M, A>(\n        this Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Guard.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class FallibleGuardExtensions\n{\n    /// <summary>\n    /// Monadic binding support for `Fallible`\n    /// </summary>\n    public static K<F, B> Bind<F, B>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, K<F, B>> f) \n        where F : Fallible<F> =>\n        guard.Flag \n            ? f(unit) \n            : error<F, B>(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `Fallible`\n    /// </summary>\n    public static K<F, C> SelectMany<F, B, C>(\n        this Guard<Error, Unit> guard,\n        Func<Unit, K<F, B>> bind, \n        Func<Unit, B, C> project) \n        where F : Fallible<F>, Functor<F> =>\n        guard.Flag\n            ? bind(default).Map(b => project(default, b))\n            : error<F, C>(guard.OnFalse());    \n    \n    /// <summary>\n    /// Monadic binding support for `Fallible`\n    /// </summary>\n    public static K<F, B> Bind<E, F, B>(\n        this Guard<E, Unit> guard,\n        Func<Unit, K<F, B>> f) \n        where F : Fallible<E, F> =>\n        guard.Flag \n            ? f(unit) \n            : fail<E, F, B>(guard.OnFalse());\n       \n    /// <summary>\n    /// Monadic binding support for `Fallible`\n    /// </summary>\n    public static K<F, C> SelectMany<E, F, B, C>(\n        this Guard<E, Unit> guard,\n        Func<Unit, K<F, B>> bind, \n        Func<Unit, B, C> project) \n        where F : Fallible<E, F>, Functor<F> =>\n        guard.Flag\n            ? bind(default).Map(b => project(default, b))\n            : fail<E, F, C>(guard.OnFalse());    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Interface.cs",
    "content": "/*\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Derive your concrete types from this interface to acquire to common set of\n/// operators that will make working with the generic `Fallible` trait more elegant.\n/// \n/// It isn't a requirement to implement this interface for `Fallible` to work, but\n/// it guides the implementor. It is optional!\n/// </summary>\n/// <remarks>\n/// Primarily makes `@catch` work nicely, but is generally beneficial.  \n/// </remarks>\n/// <typeparam name=\"FA\">'Self' type, for example `Either〈L, R〉`</typeparam>\n/// <typeparam name=\"F\">Trait implementation, for example `Either〈L〉`</typeparam>\n/// <typeparam name=\"E\">Failure type, for example `L`</typeparam>\n/// <typeparam name=\"A\">Bound value type, for example `R`</typeparam>\npublic interface Fallible<FA, F, E, A> : \n    K<F, A>\n    where FA : \n        Fallible<FA, F, E, A>\n    where F :\n        Fallible<E, F>, \n        Applicative<F>\n{\n    [Pure]\n    public static abstract implicit operator FA(Fail<E> fail);\n    \n    [Pure]\n    public static abstract implicit operator FA(Pure<A> fail);\n\n    [Pure]\n    public static abstract FA operator |(FA lhs, FA rhs);\n\n    [Pure]\n    public static abstract FA operator |(K<F, A> lhs, FA rhs);\n\n    [Pure]\n    public static abstract FA operator |(FA lhs, K<F, A> rhs);\n\n    [Pure]\n    public static abstract FA operator |(FA lhs, Pure<A> rhs);\n\n    [Pure]\n    public static abstract FA operator |(FA lhs, Fail<E> rhs);\n\n    [Pure]\n    public static abstract FA operator |(FA lhs, CatchM<E, F, A> rhs);\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Module.cs",
    "content": "using LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Module for higher-kinded structures that have a failure state `E`\n/// </summary>\n/// <typeparam name=\"F\">Higher-kinded structure</typeparam>\n/// <typeparam name=\"E\">Failure type</typeparam>\npublic static class Fallible\n{\n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F` \n    /// </summary>\n    /// <param name=\"error\">Error to raise</param>\n    /// <typeparam name=\"F\">Fallible trait</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static K<F, A> fail<E, F, A>(E error)\n        where F : Fallible<E, F> =>\n        F.Fail<A>(error);\n    \n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F` \n    /// </summary>\n    /// <param name=\"error\">Error to raise</param>\n    /// <typeparam name=\"F\">Fallible trait</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static K<F, A> error<F, A>(Error error)\n        where F : Fallible<Error, F> =>\n        F.Fail<A>(error);\n    \n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F` \n    /// </summary>\n    /// <param name=\"error\">Error to raise</param>\n    /// <typeparam name=\"F\">Fallible trait</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static K<F, Unit> fail<E, F>(E error)\n        where F : Fallible<E, F> =>\n        F.Fail<Unit>(error);    \n    \n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F` \n    /// </summary>\n    /// <param name=\"error\">Error to raise</param>\n    /// <typeparam name=\"F\">Fallible trait</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static K<F, Unit> error<F>(Error error)\n        where F : Fallible<Error, F> =>\n        F.Fail<Unit>(error);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Operators.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FallibleExtensions\n{\n    extension<E, F, A>(K<F, A> _)\n        where F : Fallible<E, F>\n    {\n        /// <summary>\n        /// Catch operator.  Catch an error if the predicate in the structure matches. \n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        public static K<F, A> operator |(K<F, A> lhs, CatchM<E, F, A> rhs) =>\n            lhs.Catch(rhs);\n        \n        /// <summary>\n        /// Catch operator.  Catch an error if the predicate in the structure matches. \n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        public static K<F, A> operator |(K<F, A> lhs, Fail<E> rhs) =>\n            lhs.Catch(rhs);\n    }\n    \n    extension<F, A>(K<F, A> _)\n        where F : Fallible<F>\n    {\n        /// <summary>\n        /// Catch operator.  Catch an error if the predicate in the structure matches. \n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        public static K<F, A> operator |(K<F, A> lhs, Error rhs) =>\n            lhs.Catch(rhs);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.Catch.E.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Catch an error if the predicate matches\n    /// </summary>\n    internal static CatchM<E, M, A> matchError<E, M, A>(Func<E, bool> predicate, Func<E, K<M, A>> Fail) \n        where M : Fallible<E, M> =>\n        new (predicate, Fail);\n    \n    /// <summary>\n    /// Catch an error if the predicate matches\n    /// </summary>\n    internal static CatchM<E, M, A> matchError<E, M, A>(Func<E, bool> predicate, Func<E, K<IO, A>> Fail) \n        where M : Fallible<E, M>, Monad<M> =>\n        new (predicate, e => MonadIO.liftIO<M, A>(Fail(e)));\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<E, M, A> @catch<E, M, A>(E error, Func<E, K<M, A>> Fail) \n        where M : Fallible<E, M> =>\n        matchError(e => error?.Equals(e) ?? false, Fail);\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<E, M, A> @catch<E, M, A>(E error, K<M, A> Fail)\n        where M : Fallible<E, M> =>\n        matchError(e => error?.Equals(e) ?? false, (E _) => Fail);\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<E, M, A> @catch<E, M, A>(Func<E, bool> predicate, Func<E, K<M, A>> Fail)\n        where M : Fallible<E, M> =>\n        matchError(predicate, Fail);\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<E, M, A> @catch<E, M, A>(Func<E, bool> predicate, K<M, A> Fail) \n        where M : Fallible<E, M> =>\n        matchError(predicate, _ => Fail);\n    \n    /// <summary>\n    /// Catch all errors and return Fail \n    /// </summary>\n    public static CatchM<E, M, A> @catch<E, M, A>(Func<E, K<M, A>> Fail) \n        where M : Fallible<E, M> =>\n        matchError(static _ => true, Fail);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.Catch.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Error specific\n    //\n\n    /// <summary>\n    /// Catch all `Error` errors of subtype `E` and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> catchOf<E, M, A>(Func<E, K<M, A>> Fail)\n        where E : Error\n        where M : Fallible<Error, M>, Monad<M> =>\n        matchError<Error, M, A>(e => e is E || e.IsType<E>(),\n                                es => es is E e \n                                          ? Fail(e) \n                                          : es.Filter<E>().ForAllM(e => Fail((E)e))); \n\n    /// <summary>\n    /// Catch all `Error` errors of subtype `E` and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> catchOfFold<E, M, A>(Func<E, K<M, A>> Fail)\n        where E : Error\n        where M : Fallible<Error, M>, MonoidK<M> =>\n        matchError<Error, M, A>(e => e is E || e.IsType<E>(),\n                                es => es is E e \n                                          ? Fail(e) \n                                          : es.Filter<E>().FoldM(e => Fail((E)e))); \n\n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<Error, M, A> @catch<M, A>(Error error, Func<Error, K<M, A>> Fail) \n        where M : Fallible<Error, M> =>\n        matchError(error.Is, Fail);\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<Error, M, A> @catch<M, A>(Error error, K<M, A> Fail)\n        where M : Fallible<Error, M> =>\n        matchError(error.Is, (Error _) => Fail);\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<Error, M, A> @catch<M, A>(int errorCode, Func<Error, K<M, A>> Fail)\n        where M : Fallible<Error, M> =>\n        matchError(e => e.Code == errorCode || e.HasCode(errorCode), Fail);\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<Error, M, A> @catch<M, A>(int errorCode, K<M, A> Fail)\n        where M : Fallible<Error, M> =>\n        matchError(e => e.Code == errorCode || e.HasCode(errorCode), (Error _) => Fail);\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<Error, M, A> @catch<M, A>(Func<Error, bool> predicate, Func<Error, K<M, A>> Fail)\n        where M : Fallible<Error, M> =>\n        matchError(predicate, Fail);\n    \n    /// <summary>\n    /// Catch an error if the error matches the argument provided \n    /// </summary>\n    public static CatchM<Error, M, A> @catch<M, A>(Func<Error, bool> predicate, K<M, A> Fail) \n        where M : Fallible<Error, M> =>\n        matchError(predicate, _ => Fail);\n    \n    /// <summary>\n    /// Catch all errors and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> @catch<M, A>(Func<Error, K<M, A>> Fail) \n        where M : Fallible<Error, M> =>\n        matchError(static _ => true, Fail);\n    \n    /// <summary>\n    /// Catch all errors and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> @catch<M, A>(K<M, A> Fail) \n        where M : Fallible<Error, M> =>\n        matchError(static _ => true, (Error _) => Fail);\n    \n    \n    /// <summary>\n    /// Catch all `Expected` errors and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> expected<M, A>(Func<Expected, K<M, A>> Fail) \n        where M : Fallible<Error, M>, Monad<M> =>\n        catchOf(Fail);\n    \n    /// <summary>\n    /// Catch all `Expected` errors of subtype `E` and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> expectedOf<E, M, A>(Func<E, K<M, A>> Fail)\n        where E : Expected \n        where M : Fallible<Error, M>, Monad<M> =>\n        catchOf(Fail);\n    \n    /// <summary>\n    /// Catch all `Exceptional` errors and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> exceptional<M, A>(Func<Exceptional, K<M, A>> Fail) \n        where M : Fallible<Error, M>, Monad<M> =>\n        catchOf(Fail);\n    \n    /// <summary>\n    /// Catch all errors and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> exceptionalOf<E, M, A>(Func<E, K<M, A>> Fail) \n        where E : Exceptional \n        where M : Fallible<Error, M>, Monad<M> =>\n        catchOf(Fail);\n    \n    /// <summary>\n    /// Catch all `Expected` errors and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> expectedFold<M, A>(Func<Expected, K<M, A>> Fail) \n        where M : Fallible<Error, M>, MonoidK<M> =>\n        catchOfFold(Fail);\n    \n    /// <summary>\n    /// Catch all `Expected` errors of subtype `E` and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> expectedOfFold<E, M, A>(Func<E, K<M, A>> Fail)\n        where E : Expected \n        where M : Fallible<Error, M>, MonoidK<M> =>\n        catchOfFold(Fail);\n    \n    /// <summary>\n    /// Catch all `Exceptional` errors and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> exceptionalFold<M, A>(Func<Exceptional, K<M, A>> Fail) \n        where M : Fallible<Error, M>, MonoidK<M> =>\n        catchOfFold(Fail);\n    \n    /// <summary>\n    /// Catch all errors and return Fail \n    /// </summary>\n    public static CatchM<Error, M, A> exceptionalOfFold<E, M, A>(Func<E, K<M, A>> Fail) \n        where E : Exceptional \n        where M : Fallible<Error, M>, MonoidK<M> =>\n        catchOfFold(Fail);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.Fails.E.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class FallibleExtensions\n{\n    /// <summary>\n    /// Partitions a foldable of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> fails<E, F, M, A>(\n        K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure(Seq.empty<E>()),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(_ => M.Pure(s))\n                                  .Catch((E e) => M.Pure(s.Add(e)))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> fails<E, M, A>(\n        Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, Seq, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> fails<E, M, A>(\n        Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, Iterable, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> fails<E, M, A>(\n        Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, Lst, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> fails<E, M, A>(\n        IEnumerable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        Iterable.createRange(fma).Fails<E, Iterable, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> fails<E, M, A>(\n        HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, HashSet, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `E` values</returns>\n    public static K<M, Seq<E>> fails<E, M, A>(\n        Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Fails<E, Set, M, A>();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.Fails.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Partitions a foldable of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> fails<F, M, A>(\n        K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure(LanguageExt.Seq.empty<Error>()),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(_ => M.Pure(s))\n                                  .Catch(e => M.Pure(s.Add(e)))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> fails<M, A>(\n        Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> fails<M, A>(\n        Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> fails<M, A>(\n        Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> fails<M, A>(\n        IEnumerable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        LanguageExt.Iterable.createRange(fma).Fails();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> fails<M, A>(\n        HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<Error>> fails<M, A>(\n        Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Fails();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.Partition.E.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Partitions a foldable of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> partitionFallible<E, F, M, A>(\n        K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure((Fails: LanguageExt.Seq.empty<E>(), Succs: LanguageExt.Seq.empty<A>())),\n                 ma => ms => from s in ms \n                             from r in ma.Map(a => (s.Fails, s.Succs.Add(a)))\n                                         .Catch((E e) => M.Pure((s.Fails.Add(e), s.Succs)))\n                             select r);\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> partitionFallible<E, M, A>(\n        Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, Seq, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> partitionFallible<E, M, A>(\n        Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, Iterable, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> partitionFallible<E, M, A>(\n        Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, Lst, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> partitionFallible<E, M, A>(\n        IEnumerable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        LanguageExt.Iterable.createRange(fma).PartitionFallible<E, Iterable, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> partitionFallible<E, M, A>(\n        HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, HashSet, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<E> Fails, Seq<A> Succs)> partitionFallible<E, M, A>(\n        Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().PartitionFallible<E, Set, M, A>();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.Partition.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Partitions a foldable of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> partitionFallible<F, M, A>(\n        K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure((Fails: LanguageExt.Seq.empty<Error>(), Succs: LanguageExt.Seq.empty<A>())),\n                 ma => ms => from s in ms \n                             from r in ma.Map(a => (s.Fails, s.Succs.Add(a)))\n                                         .Catch(e => M.Pure((s.Fails.Add(e), s.Succs)))\n                             select r);\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> partitionFallible<M, A>(\n        Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> partitionFallible<M, A>(\n        Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> partitionFallible<M, A>(\n        Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> partitionFallible<M, A>(\n        IEnumerable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        LanguageExt.Iterable.createRange(fma).PartitionFallible();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> partitionFallible<M, A>(\n        HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();\n    \n    /// <summary>\n    /// Partitions a collection of effects into two lists.\n    /// All the `Fail` elements are extracted, in order, to the first\n    /// component of the output.  Similarly, the `Succ` elements are extracted\n    /// to the second component of the output.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A tuple containing an `Error` sequence and a `Succ` sequence</returns>\n    public static K<M, (Seq<Error> Fails, Seq<A> Succs)> partitionFallible<M, A>(\n        Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().PartitionFallible();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.Succs.E.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class FallibleExtensionsE\n{\n    /// <summary>\n    /// Partitions a foldable of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<E, F, M, A>(\n        K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure(Seq.empty<A>()),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(a => M.Pure(s.Add(a)))\n                                  .Catch((E _) => M.Pure(s))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<E, M, A>(\n        Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, Seq, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<E, M, A>(\n        Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, Iterable, M, A>();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<E, M, A>(\n        Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, Lst, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<E, M, A>(\n        IEnumerable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        Iterable.createRange(fma).Succs<E, Iterable, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<E, M, A>(\n        HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, HashSet, M, A>();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<E, M, A>(\n        Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<E, M> =>\n        fma.Kind().Succs<E, Set, M, A>();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.Succs.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Partitions a foldable of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable type</typeparam>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Foldable of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<F, M, A>(\n        K<F, K<M, A>> fma)\n        where M : Monad<M>, Fallible<M>\n        where F : Foldable<F> =>\n        fma.Fold(M.Pure(LanguageExt.Seq.empty<A>()),\n                 ma => ms => ms.Bind(\n                           s => ma.Bind(a => M.Pure(s.Add(a)))\n                                  .Catch(_ => M.Pure(s))));\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<M, A>(\n        Seq<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<M, A>(\n        Iterable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();    \n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<M, A>(\n        Lst<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<M, A>(\n        IEnumerable<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        LanguageExt.Iterable.createRange(fma).Succs();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<M, A>(\n        HashSet<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();\n    \n    /// <summary>\n    /// Partitions a collection of effects into successes and failures,\n    /// and returns only the failures.\n    /// </summary>\n    /// <typeparam name=\"M\">Fallible monadic type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <param name=\"fma\">Collection of fallible monadic values</param>\n    /// <returns>A collection of `Error` values</returns>\n    public static K<M, Seq<A>> succs<M, A>(\n        Set<K<M, A>> fma)\n        where M : Monad<M>, Fallible<M> =>\n        fma.Kind().Succs();    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Prelude.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Module for higher-kinded structures that have a failure state `E`\n/// </summary>\n/// <typeparam name=\"F\">Higher-kinded structure</typeparam>\n/// <typeparam name=\"E\">Failure type</typeparam>\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F` \n    /// </summary>\n    /// <param name=\"error\">Error to raise</param>\n    /// <typeparam name=\"F\">Fallible trait</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static K<F, A> fail<E, F, A>(E error)\n        where F : Fallible<E, F> =>\n        F.Fail<A>(error);\n    \n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F` \n    /// </summary>\n    /// <param name=\"error\">Error to raise</param>\n    /// <typeparam name=\"F\">Fallible trait</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static K<F, A> error<F, A>(Error error)\n        where F : Fallible<Error, F> =>\n        F.Fail<A>(error);\n    \n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F` \n    /// </summary>\n    /// <param name=\"error\">Error to raise</param>\n    /// <typeparam name=\"F\">Fallible trait</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static K<F, Unit> fail<E, F>(E error)\n        where F : Fallible<E, F> =>\n        F.Fail<Unit>(error);    \n    \n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F` \n    /// </summary>\n    /// <param name=\"error\">Error to raise</param>\n    /// <typeparam name=\"F\">Fallible trait</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static K<F, Unit> error<F>(Error error)\n        where F : Fallible<Error, F> =>\n        F.Fail<Unit>(error);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fallible/Fallible.Trait.cs",
    "content": "using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Trait for higher-kinded structures that have a failure state `E`\n/// </summary>\n/// <typeparam name=\"E\">Failure type</typeparam>\n/// <typeparam name=\"F\">Higher-kinded structure</typeparam>\npublic interface Fallible<E, F>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Abstract members\n    //\n    \n    /// <summary>\n    /// Raise a failure state in the `Fallible` structure `F`\n    /// </summary>\n    /// <param name=\"error\">Error value</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static abstract K<F, A> Fail<A>(E error);\n\n    /// <summary>\n    /// Run the `Fallible` structure.  If in a failed state, test the failure value\n    /// against the predicate.  If it returns `true`, run the `Fail` function with\n    /// the failure value.\n    /// </summary>\n    /// <param name=\"fa\">`Fallible` structure</param>\n    /// <param name=\"Predicate\">Predicate to test any failure values</param>\n    /// <param name=\"Fail\">Handler when in failed state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Either `fa` or the result of `Fail` if `fa` is in a failed state and the\n    /// predicate returns true for the failure value</returns>\n    public static abstract K<F, A> Catch<A>(\n        K<F, A> fa,\n        Func<E, bool> Predicate, \n        Func<E, K<F, A>> Fail);\n}\n\n/// <summary>\n/// Trait for higher-kinded structures that have a failure state `Error`\n/// </summary>\n/// <typeparam name=\"F\">Higher-kinded structure</typeparam>\npublic interface Fallible<F> : Fallible<Error, F>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Final/Final.Extensions.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class FinalExtensions\n{\n    /// <summary>\n    /// Run a `finally` operation after the `ma` operation regardless of whether `ma` succeeds or not.\n    /// </summary>\n    /// <param name=\"ma\">Primary operation</param>\n    /// <param name=\"finally\">Finally operation</param>\n    /// <returns>Result of primary operation</returns>\n    public static K<F, A> Finally<X, F, A>(this K<F, A> ma, K<F, X> @finally)\n        where F : Final<F> =>\n        F.Finally(ma, @finally);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Final/Final.Module.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class Final\n{\n    /// <summary>\n    /// Create a `finally` operation that can be used as the right-hand side of a `|` operator to\n    /// cause a final operation to be run regardless of whether the primary operation succeeds or not.\n    /// </summary>\n    /// <param name=\"finally\">Finally operation</param>\n    /// <returns>Result of primary operation</returns>\n    public static Finally<F, X> final<F, X>(K<F, X> @finally)\n        where F : Final<F> =>\n        new(@finally);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Final/Final.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class FinalExtensions\n{\n    extension<X, F, A>(K<F, A> _)\n        where F : Final<F>\n    {\n        /// <summary>\n        /// Run a `finally` operation after the main operation regardless of whether it succeeds or not.\n        /// </summary>\n        /// <param name=\"lhs\">Primary operation</param>\n        /// <param name=\"rhs\">Finally operation</param>\n        /// <returns>Result of primary operation</returns>\n        public static K<F, A> operator |(K<F, A> lhs, Finally<F, X> rhs) =>\n            lhs.Finally(rhs.Operation);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Final/Final.Prelude.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Create a `finally` operation that can be used as the right-hand side of a `|` operator to\n    /// cause a final operation to be run regardless of whether the primary operation succeeds or not.\n    /// </summary>\n    /// <param name=\"finally\">Finally operation</param>\n    /// <returns>Result of primary operation</returns>\n    public static Finally<F, X> final<F, X>(K<F, X> @finally)\n        where F : Final<F> =>\n        new (@finally);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Final/Final.Trait.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Mimics `finally` in a `try/finally` operation\n/// </summary>\npublic interface Final<F>\n    where F : Final<F>\n{\n    /// <summary>\n    /// Run a `finally` operation after the `fa` operation regardless of whether `fa` succeeds or not.\n    /// </summary>\n    /// <param name=\"fa\">Primary operation</param>\n    /// <param name=\"finally\">Finally operation</param>\n    /// <returns>Result of primary operation</returns>\n    public static abstract K<F, A> Finally<X, A>(K<F, A> fa, K<F, X> @finally);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Final/Finally.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Create a `finally` operation that can be used as the right-hand side of a `|` operator to\n/// cause a final operation to be run regardless of whether the primary operation succeeds or not.\n/// </summary>\n/// <param name=\"finally\"></param>\n/// <typeparam name=\"F\"></typeparam>\npublic readonly record struct Finally<F, X>(K<F, X> Operation)\n    where F : Final<F>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Floating/Floating.Prelude.cs",
    "content": "﻿#nullable enable\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Trait\n{\n    /// <summary>\n    /// Ratio constructor\n    /// </summary>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <param name=\"num\">Numerator</param>\n    /// <param name=\"den\">Denominator</param>\n    /// <returns>Ratio struct</returns>\n    [Pure]\n    public static Ratio<A> Ratio<A>(A num, A den) =>\n        new (num, den);\n\n    /// <summary>\n    /// Returns an approximation of pi.\n    /// </summary>\n    /// <returns>A reasonable approximation of pi in this type</returns>\n    [Pure]\n    public static A pi<FLOAT, A>() where FLOAT : Floating<A> =>\n        FLOAT.Pi();\n\n    /// <summary>\n    /// The exponential function.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the exponential</param>\n    /// <returns>The value of <c>e^x</c></returns>\n    [Pure]\n    public static A exp<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Exp(x);\n\n    /// <summary>\n    /// Calculates the square root of a value.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the square root.</param>\n    /// <returns>The value of <c>sqrt(x)</c>.</returns>\n    [Pure]\n    public static A sqrt<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Sqrt(x);\n\n    /// <summary>\n    /// Calculates the natural logarithm of a value.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which we are calculating the natural logarithm.\n    /// </param>\n    /// <returns>The value of <c>ln(x)</c>.</returns>\n    [Pure]\n    public static A log<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Log(x);\n\n    /// <summary>Raises x to the power y\n    /// </summary>\n    /// <param name=\"x\">The base to be raised to y</param>\n    /// <param name=\"y\">The exponent to which we are raising x</param>\n    /// <returns>The value of <c>x^y</c>.</returns>\n    [Pure]\n    public static A pow<FLOAT, A>(A x, A y) where FLOAT : Floating<A> =>\n        FLOAT.Pow(x, y);\n\n    /// <summary>\n    /// Calculates the logarithm of a value with respect to an arbitrary base.\n    /// </summary>\n    /// <param name=\"b\">The base to use for the logarithm of x</param>\n    /// <param name=\"x\">The value for which we are calculating the logarithm.</param>\n    /// <returns>The value of <c>log b (x)</c>.</returns>\n    [Pure]\n    public static A logBase<FLOAT, A>(A x, A y) where FLOAT : Floating<A> =>\n        FLOAT.LogBase(x, y);\n\n    /// <summary>\n    /// Calculates the sine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>sin(x)</c></returns>\n    [Pure]\n    public static A sin<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Sin(x);\n\n    /// <summary>\n    /// Calculates the cosine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>cos(x)</c></returns>\n    [Pure]\n    public static A cos<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Cos(x);\n\n    /// <summary>\n    ///     Calculates the tangent of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>tan(x)</c></returns>\n    [Pure]\n    public static A tan<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Tan(x);\n\n    /// <summary>\n    /// Calculates an arcsine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arcsine is to be calculated.</param>\n    /// <returns>The value of <c>asin(x)</c>, in radians.</returns>\n    [Pure]\n    public static A asin<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Asin(x);\n\n    /// <summary>\n    /// Calculates an arc-cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-cosine is to be calculated</param>\n    /// <returns>The value of <c>acos(x)</c>, in radians</returns>\n    [Pure]\n    public static A acos<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Acos(x);\n\n    /// <summary>\n    /// Calculates an arc-tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-tangent is to be calculated</param>\n    /// <returns>The value of <c>atan(x)</c>, in radians</returns>\n    [Pure]\n    public static A atan<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Atan(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic sine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic sine is to be calculated</param>\n    /// <returns>The value of <c>sinh(x)</c></returns>\n    [Pure]\n    public static A sinh<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Sinh(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic cosine is to be calculated</param>\n    /// <returns>The value of <c>cosh(x)</c></returns>\n    [Pure]\n    public static A cosh<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Cosh(x);\n\n    /// <summary>\n    /// Calculates a hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which a hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>tanh(x)</c></returns>\n    [Pure]\n    public static A tanh<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Tanh(x);\n\n    /// <summary>Calculates an area hyperbolic sine</summary>\n    /// <param name=\"x\">The value for which an area hyperbolic sine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>asinh(x)</c>.</returns>\n    [Pure]\n    public static A asinh<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Asinh(x);\n\n    /// <summary>\n    /// Calculates an area hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic cosine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>acosh(x)</c>.</returns>\n    [Pure]\n    public static A acosh<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Acosh(x);\n\n    /// <summary>\n    /// Calculates an area hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>atanh(x)</c></returns>\n    [Pure]\n    public static A atanh<FLOAT, A>(A x) where FLOAT : Floating<A> =>\n        FLOAT.Atanh(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Floating/Floating.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Floating point number trait\n/// </summary>\n/// <typeparam name=\"A\">The floating point value type</typeparam>\n[Trait(\"Float*\")]\npublic interface Floating<A> : Fraction<A>\n{\n    /// <summary>\n    /// Returns an approximation of pi.\n    /// </summary>\n    /// <returns>A reasonable approximation of pi in this type</returns>\n    [Pure]\n    public static abstract A Pi();\n\n    /// <summary>\n    /// The exponential function.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the exponential</param>\n    /// <returns>The value of <c>e^x</c></returns>\n    [Pure]\n    public static abstract A Exp(A x);\n\n    /// <summary>\n    /// Calculates the square root of a value.\n    /// </summary>\n    /// <param name=\"x\">The value for which we are calculating the square root.</param>\n    /// <returns>The value of <c>sqrt(x)</c>.</returns>\n    [Pure]\n    public static abstract A Sqrt(A x);\n\n    /// <summary>\n    /// Calculates the natural logarithm of a value.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which we are calculating the natural logarithm.\n    /// </param>\n    /// <returns>The value of <c>ln(x)</c>.</returns>\n    [Pure]\n    public static abstract A Log(A x);\n\n    /// <summary>Raises x to the power y\n    /// </summary>\n    /// <param name=\"x\">The base to be raised to y</param>\n    /// <param name=\"y\">The exponent to which we are raising x</param>\n    /// <returns>The value of <c>x^y</c>.</returns>\n    [Pure]\n    public static abstract A Pow(A x, A y);\n\n    /// <summary>\n    /// Calculates the logarithm of a value with respect to an arbitrary base.\n    /// </summary>\n    /// <param name=\"x\">The base to use for the logarithm of t</param>\n    /// <param name=\"y\">The value for which we are calculating the logarithm.</param>\n    /// <returns>The value of <c>log x (y)</c>.</returns>\n    [Pure]\n    public static abstract A LogBase(A x, A y);\n\n    /// <summary>\n    /// Calculates the sine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>sin(x)</c></returns>\n    [Pure]\n    public static abstract A Sin(A x);\n\n    /// <summary>\n    /// Calculates the cosine of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>cos(x)</c></returns>\n    [Pure]\n    public static abstract A Cos(A x);\n\n    /// <summary>\n    ///     Calculates the tangent of an angle.\n    /// </summary>\n    /// <param name=\"x\">An angle, in radians</param>\n    /// <returns>The value of <c>tan(x)</c></returns>\n    [Pure]\n    public static abstract A Tan(A x);\n\n    /// <summary>\n    /// Calculates an arcsine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arcsine is to be calculated.</param>\n    /// <returns>The value of <c>asin(x)</c>, in radians.</returns>\n    [Pure]\n    public static abstract A Asin(A x);\n\n    /// <summary>\n    /// Calculates an arc-cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-cosine is to be calculated</param>\n    /// <returns>The value of <c>acos(x)</c>, in radians</returns>\n    [Pure]\n    public static abstract A Acos(A x);\n\n    /// <summary>\n    /// Calculates an arc-tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an arc-tangent is to be calculated</param>\n    /// <returns>The value of <c>atan(x)</c>, in radians</returns>\n    [Pure]\n    public static abstract A Atan(A x);\n\n    /// <summary>\n    /// Calculates a hyperbolic sine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic sine is to be calculated</param>\n    /// <returns>The value of <c>sinh(x)</c></returns>\n    [Pure]\n    public static abstract A Sinh(A x);\n\n    /// <summary>\n    /// Calculates a hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which a hyperbolic cosine is to be calculated</param>\n    /// <returns>The value of <c>cosh(x)</c></returns>\n    [Pure]\n    public static abstract A Cosh(A x);\n\n    /// <summary>\n    /// Calculates a hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">\n    /// The value for which a hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>tanh(x)</c></returns>\n    [Pure]\n    public static abstract A Tanh(A x);\n\n    /// <summary>Calculates an area hyperbolic sine</summary>\n    /// <param name=\"x\">The value for which an area hyperbolic sine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>asinh(x)</c>.</returns>\n    [Pure]\n    public static abstract A Asinh(A x);\n\n    /// <summary>\n    /// Calculates an area hyperbolic cosine.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic cosine is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>acosh(x)</c>.</returns>\n    [Pure]\n    public static abstract A Acosh(A x);\n\n    /// <summary>\n    /// Calculates an area hyperbolic tangent.\n    /// </summary>\n    /// <param name=\"x\">The value for which an area hyperbolic tangent is to be calculated.\n    /// </param>\n    /// <returns>The value of <c>atanh(x)</c></returns>\n    [Pure]\n    public static abstract A Atanh(A x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Foldable/Fold.Module.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Fold continuation module\n/// </summary>\npublic record Fold\n{\n    /// <summary>\n    /// Indicates the fold operation has completed\n    /// </summary>\n    /// <param name=\"state\">State</param>\n    public static Fold<A, S> Done<A, S>(S state) => \n        new Fold<A, S>.Done(state);\n\n    /// <summary>\n    /// Indicates the fold operation should continue\n    /// </summary>\n    /// <param name=\"state\">Current state</param>\n    /// <param name=\"value\">Current value</param>\n    /// <param name=\"next\">Continuation function, pass your updated state to this</param>\n    public static Fold<A, S> Loop<A, S>(S state, A value, Func<S, Fold<A, S>> next) =>\n        new Fold<A, S>.Loop(state, value, next);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Foldable/Fold.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A continuation of a fold operation \n/// </summary>\n/// <remarks>\n/// Returned from `Foldable.FoldStep` and `Foldable.FoldStepBack`, it enables consumption of a foldable structure\n/// one element at a time. Which in turn means we can avoid recursion and stack overflows.\n/// </remarks>\n/// <param name=\"State\">Current state</param>\n/// <typeparam name=\"A\">Value type</typeparam>\n/// <typeparam name=\"S\">State type</typeparam>\npublic abstract record Fold<A, S>(S State)\n{\n    /// <summary>\n    /// Indicates the fold operation has completed\n    /// </summary>\n    /// <param name=\"State\">State</param>\n    public sealed record Done(S State) : Fold<A, S>(State);\n    \n    /// <summary>\n    /// Indicates the fold operation should continue\n    /// </summary>\n    /// <param name=\"State\">Current state</param>\n    /// <param name=\"Value\">Current value</param>\n    /// <param name=\"Next\">Continuation function, pass your updated state to this</param>\n    public sealed record Loop(S State, A Value, Func<S, Fold<A, S>> Next) : Fold<A, S>(State);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Foldable/Foldable.Extensions.cs",
    "content": "using System;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FoldableExtensions\n{\n    /// <param name=\"f\">Mapping operation</param>\n    /// <typeparam name=\"T\">Foldable</typeparam>\n    /// <typeparam name=\"F\">Applicative</typeparam>\n    /// <typeparam name=\"A\">Input bound value</typeparam>\n    /// <typeparam name=\"B\">Mapping bound value</typeparam>\n    extension<T, F, A, B>(Func<A, K<F, B>> f) \n        where T : Foldable<T> where F : Applicative<F>\n    {\n        /// <summary>\n        /// Fold the structure: `ta` and pass each element that it yields to `f`, resulting in an `F` applicative-value.\n        /// The fold operator is applicative `Action`, which causes each applicative-value to be sequenced.      \n        /// </summary>\n        /// <param name=\"ta\">Foldable structure</param>\n        /// <returns></returns>\n        public K<F, Unit> ForM(K<T, A> ta) =>\n            ta.Fold(pure<F, Unit>(unit), x => f(x).Action);\n    }\n\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"T\">Foldable</typeparam>\n    /// <typeparam name=\"F\">Applicative</typeparam>\n    /// <typeparam name=\"A\">Input bound value</typeparam>\n    /// <typeparam name=\"B\">Mapping bound value</typeparam>\n    extension<T, F, A, B>(K<T, A> ta) \n        where T : Foldable<T> \n        where F : Applicative<F>\n    {\n        /// <summary>\n        /// Fold the structure: `ta` and pass each element that it yields to `f`, resulting in an `F` applicative-value.\n        /// The fold operator is applicative `Action`, which causes each applicative-value to be sequenced.      \n        /// </summary>\n        /// <param name=\"f\">Mapping operation</param>\n        /// <returns></returns>\n        public K<F, Unit> ForM(Func<A, K<F, B>> f) =>\n            ta.Fold(pure<F, Unit>(unit), x => f(x).Action);\n    }\n\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    extension<T, A>(K<T, A> ta) \n        where T : Foldable<T>\n    {\n        /// <summary>\n        /// Runs a single step of the folding operation. The return value indicates whether the folding\n        /// operation should continue, and if so, what the next step should be.\n        /// </summary>\n        /// <remarks>\n        /// It is up to the consumer of this method to implement the actual state-aggregation (the folding)\n        /// before passing it to the continuation function.  \n        /// </remarks>\n        /// <param name=\"ta\">Foldable structure</param>\n        /// <param name=\"initialState\">Initial state value</param>\n        /// <typeparam name=\"A\">Value type</typeparam>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <returns>A discriminated union that can be either `Done` or `Loop`.</returns>\n        public Fold<A, S> FoldStep<S>(S initialState) =>\n            T.FoldStep(ta, initialState);\n        \n        /// <summary>\n        /// Runs a single step of the folding operation. The return value indicates whether the folding\n        /// operation should continue, and if so, what the next step should be.\n        /// </summary>\n        /// <remarks>\n        /// It is up to the consumer of this method to implement the actual state-aggregation (the folding)\n        /// before passing it to the continuation function.  \n        /// </remarks>\n        /// <param name=\"ta\">Foldable structure</param>\n        /// <param name=\"initialState\">Initial state value</param>\n        /// <typeparam name=\"A\">Value type</typeparam>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <returns>A discriminated union that can be either `Done` or `Loop`.</returns>\n        public Fold<A, S> FoldStepBack<S>(S initialState) => \n            T.FoldStep(ta, initialState);\n        \n        /// <summary>\n        /// Fold until the `Option` returns `None`\n        /// </summary>\n        /// <param name=\"f\">Fold function</param>\n        /// <param name=\"initialState\">Initial state for the fold</param>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <returns>Aggregated value</returns>\n        public S FoldMaybe<S>(S initialState, Func<S, Func<A, Option<S>>> f) =>\n            T.FoldMaybe(f, initialState, ta);\n\n        /// <summary>\n        /// Fold until the `Option` returns `None`\n        /// </summary>\n        /// <param name=\"f\">Fold function</param>\n        /// <param name=\"initialState\">Initial state for the fold</param>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <returns>Aggregated value</returns>\n        public S FoldMaybe<S>(\n            S initialState,\n            Func<S, A, Option<S>> f) =>\n            T.FoldMaybe(s => a => f(s, a), initialState, ta);\n\n        /// <summary>\n        /// Fold until the `Option` returns `None`\n        /// </summary>\n        /// <param name=\"f\">Fold function</param>\n        /// <param name=\"initialState\">Initial state for the fold</param>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <returns>Aggregated value</returns>\n        public S FoldBackMaybe<S>(\n            S initialState,\n            Func<A, Func<S, Option<S>>> f) =>\n            T.FoldBackMaybe(f, initialState, ta);\n\n        /// <summary>\n        /// Fold until the `Option` returns `None`\n        /// </summary>\n        /// <param name=\"f\">Fold function</param>\n        /// <param name=\"initialState\">Initial state for the fold</param>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <returns>Aggregated value</returns>\n        public S FoldBackMaybe<S>(\n            S initialState,\n            Func<S, A, Option<S>> f) =>\n            T.FoldBackMaybe(a => s => f(s, a), initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `Fold` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair \n        /// </summary>\n        public S FoldWhile<S>(\n            S initialState,\n            Func<A, Func<S, S>> f, \n            Func<(S State, A Value), bool> predicate) =>\n            T.FoldWhile(f, predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `Fold` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair \n        /// </summary>\n        public S FoldWhile<S>(\n            S initialState,\n            Func<S, A, S> f, \n            Func<(S State, A Value), bool> predicate) =>\n            T.FoldWhile(a => s => f(s, a), predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair \n        /// </summary>\n        public S FoldBackWhile<S>(\n            S initialState,\n            Func<S, Func<A, S>> f, \n            Func<(S State, A Value), bool> predicate) =>\n            T.FoldBackWhile(f, predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair \n        /// </summary>\n        public S FoldBackWhile<S>(\n            S initialState,\n            Func<S, A, S> f, \n            Func<(S State, A Value), bool> predicate) =>\n            T.FoldBackWhile(curry(f), predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        public K<M, S> FoldWhileM<M, S>(\n            S initialState,\n            Func<A, Func<S, K<M, S>>> f, \n            Func<(S State, A Value), bool> predicate) where M : Monad<M> =>\n            T.FoldWhileM(f, predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        public K<M, S> FoldWhileM<M, S>(\n            S initialState,\n            Func<S, A, K<M, S>> f, \n            Func<(S State, A Value), bool> predicate) where M : Monad<M> =>\n            T.FoldWhileM<A, M, S>(a => s => f(s, a), predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        public K<M, S> FoldBackWhileM<M, S>(\n            S initialState,\n            Func<S, Func<A, K<M, S>>> f, \n            Func<(S State, A Value), bool> predicate) where M : Monad<M> =>\n            T.FoldBackWhileM(f, predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        public K<M, S> FoldBackWhileM<M, S>(\n            S initialState,\n            Func<S, A, K<M, S>> f, \n            Func<(S State, A Value), bool> predicate) where M : Monad<M> =>\n            T.FoldBackWhileM(curry(f), predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `Fold` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair\n        /// </summary>\n        public S FoldUntil<S>(\n            S initialState,\n            Func<A, Func<S, S>> f,\n            Func<(S State, A Value), bool> predicate) =>\n            T.FoldUntil(f, predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `Fold` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair\n        /// </summary>\n        public S FoldUntil<S>(\n            S initialState,\n            Func<S, A, S> f,\n            Func<(S State, A Value), bool> predicate) =>\n            T.FoldUntil(a => s => f(s, a), predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        public K<M, S> FoldUntilM<M, S>(\n            S initialState,\n            Func<A, Func<S, K<M, S>>> f, \n            Func<(S State, A Value), bool> predicate) \n            where M : Monad<M> => \n            T.FoldUntilM(f, predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        public K<M, S> FoldUntilM<M, S>(\n            S initialState,\n            Func<S, A, K<M, S>> f, \n            Func<(S State, A Value), bool> predicate) \n            where M : Monad<M> => \n            T.FoldUntilM<A, M, S>(a => s => f(s, a), predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair\n        /// </summary>\n        public S FoldBackUntil<S>(\n            S initialState,\n            Func<S, Func<A, S>> f, \n            Func<(S State, A Value), bool> predicate) =>\n            T.FoldBackUntil(f, predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but allows early exit of the operation once\n        /// the predicate function becomes `false` for the state/value pair\n        /// </summary>\n        public S FoldBackUntil<S>(\n            S initialState,\n            Func<S, A, S> f, \n            Func<(S State, A Value), bool> predicate) =>\n            T.FoldBackUntil(curry(f), predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        public K<M, S> FoldBackUntilM<M, S>(\n            S initialState,\n            Func<S, Func<A, K<M, S>>> f, \n            Func<(S State, A Value), bool> predicate) \n            where M : Monad<M> =>\n            T.FoldBackUntilM(f, predicate, initialState, ta);\n\n        /// <summary>\n        /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n        /// early exit of the operation once the predicate function becomes `false` for the\n        /// state/value pair \n        /// </summary>\n        public K<M, S> FoldBackUntilM<M, S>(\n            S initialState,\n            Func<S, A, K<M, S>> f, \n            Func<(S State, A Value), bool> predicate) \n            where M : Monad<M> =>\n            T.FoldBackUntilM(curry(f), predicate, initialState, ta);\n\n        /// <summary>\n        /// Right-associative fold of a structure, lazy in the accumulator.\n        ///\n        /// In the case of lists, 'Fold', when applied to a binary operator, a\n        /// starting value (typically the right-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from right to left.\n        /// </summary>\n        public S Fold<S>(S initialState, Func<A, Func<S, S>> f) =>\n            T.Fold(f, initialState, ta);\n\n        /// <summary>\n        /// Right-associative fold of a structure, lazy in the accumulator.\n        ///\n        /// In the case of lists, 'Fold', when applied to a binary operator, a\n        /// starting value (typically the right-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from right to left.\n        /// </summary>\n        public S Fold<S>(S initialState, Func<S, A, S> f) =>\n            T.Fold(a => s => f(s, a), initialState, ta);\n\n        /// <summary>\n        /// Right-associative fold of a structure, lazy in the accumulator.\n        ///\n        /// In the case of lists, 'Fold', when applied to a binary operator, a\n        /// starting value (typically the right-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from right to left.\n        /// </summary>\n        public K<M, S> FoldM<M, S>(S initialState, Func<A, Func<S, K<M, S>>> f) \n            where M : Monad<M> =>\n            T.FoldM(f, initialState, ta);\n\n        /// <summary>\n        /// Right-associative fold of a structure, lazy in the accumulator.\n        ///\n        /// In the case of lists, 'Fold', when applied to a binary operator, a\n        /// starting value (typically the right-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from right to left.\n        /// </summary>\n        public K<M, S> FoldM<M, S>(S initialState, Func<S, A, K<M, S>> f) \n            where M : Monad<M> =>\n            T.FoldM<A, M, S>(a => s => f(s, a), initialState, ta);\n\n        /// <summary>\n        /// Left-associative fold of a structure, lazy in the accumulator.  This\n        /// is rarely what you want, but can work well for structures with efficient\n        /// right-to-left sequencing and an operator that is lazy in its left\n        /// argument.\n        /// \n        /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n        /// starting value (typically the left-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from left to right\n        /// </summary>\n        /// <remarks>\n        /// Note that to produce the outermost application of the operator the\n        /// entire input list must be traversed.  Like all left-associative folds,\n        /// `FoldBack` will diverge if given an infinite list.\n        /// </remarks>\n        public S FoldBack<S>(S initialState, Func<S, Func<A, S>> f) =>\n            T.FoldBack(f, initialState, ta);\n\n        /// <summary>\n        /// Left-associative fold of a structure, lazy in the accumulator.  This\n        /// is rarely what you want, but can work well for structures with efficient\n        /// right-to-left sequencing and an operator that is lazy in its left\n        /// argument.\n        /// \n        /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n        /// starting value (typically the left-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from left to right\n        /// </summary>\n        /// <remarks>\n        /// Note that to produce the outermost application of the operator the\n        /// entire input list must be traversed.  Like all left-associative folds,\n        /// `FoldBack` will diverge if given an infinite list.\n        /// </remarks>\n        public S FoldBack<S>(S initialState, Func<S, A, S> f) =>\n            T.FoldBack(curry(f), initialState, ta);\n\n        /// <summary>\n        /// Left-associative fold of a structure, lazy in the accumulator.  This\n        /// is rarely what you want, but can work well for structures with efficient\n        /// right-to-left sequencing and an operator that is lazy in its left\n        /// argument.\n        /// \n        /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n        /// starting value (typically the left-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from left to right\n        /// </summary>\n        /// <remarks>\n        /// Note that to produce the outermost application of the operator the\n        /// entire input list must be traversed.  Like all left-associative folds,\n        /// `FoldBack` will diverge if given an infinite list.\n        /// </remarks>\n        public K<M, S> FoldBackM<M, S>(\n            S initialState,\n            Func<S, Func<A, K<M, S>>> f) \n            where M : Monad<M> =>\n            T.FoldBackM(f, initialState, ta);\n\n        /// <summary>\n        /// Left-associative fold of a structure, lazy in the accumulator.  This\n        /// is rarely what you want, but can work well for structures with efficient\n        /// right-to-left sequencing and an operator that is lazy in its left\n        /// argument.\n        /// \n        /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n        /// starting value (typically the left-identity of the operator), and a\n        /// list, reduces the list using the binary operator, from left to right\n        /// </summary>\n        /// <remarks>\n        /// Note that to produce the outermost application of the operator the\n        /// entire input list must be traversed.  Like all left-associative folds,\n        /// `FoldBack` will diverge if given an infinite list.\n        /// </remarks>\n        public K<M, S> FoldBackM<M, S>(\n            S initialState,\n            Func<S, A, K<M, S>> f) \n            where M : Monad<M> =>\n            T.FoldBackM(curry(f), initialState, ta);\n    }\n\n    extension<T, A>(K<T, A> tm) where T : Foldable<T> where A : Monoid<A>\n    {\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use `FoldMap` instead, with `identity` as the map.\n        /// </summary>\n        public A Fold() =>\n            T.Fold(tm);\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use `FoldMap` instead, with `identity` as the map.\n        /// </summary>\n        public A FoldWhile(Func<(A State, A Value), bool> predicate) =>\n            T.FoldWhile(predicate, tm);\n\n        /// <summary>\n        /// Given a structure with elements whose type is a `Monoid`, combine them\n        /// via the monoid's `Append` operator.  This fold is right-associative and\n        /// lazy in the accumulator.  When you need a strict left-associative fold,\n        /// use `FoldMap` instead, with `identity` as the map.\n        /// </summary>\n        public A FoldUntil(Func<(A State, A Value), bool> predicate) =>\n            T.FoldUntil(predicate, tm);\n    }\n\n    extension<T, A>(K<T, A> ta) where T : Foldable<T>\n    {\n        /// <summary>\n        /// Map each element of the structure into a monoid, and combine the\n        /// results with `Append`.  This fold is right-associative and lazy in the\n        /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n        /// instead.\n        /// </summary>\n        public B FoldMap<B>(Func<A, B> f) where B : Monoid<B> =>\n            T.FoldMap(f, ta);\n\n        /// <summary>\n        /// Map each element of the structure into a monoid, and combine the\n        /// results with `Append`.  This fold is right-associative and lazy in the\n        /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n        /// instead.\n        /// </summary>\n        public B FoldMapWhile<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate) where B : Monoid<B> =>\n            T.FoldMapWhile(f, predicate, ta);\n\n        /// <summary>\n        /// Map each element of the structure into a monoid, and combine the\n        /// results with `Append`.  This fold is right-associative and lazy in the\n        /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n        /// instead.\n        /// </summary>\n        public B FoldMapUntil<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate) where B : Monoid<B> =>\n            T.FoldMapUntil(f, predicate, ta);\n\n        /// <summary>\n        /// A left-associative variant of 'FoldMap' that is strict in the\n        /// accumulator.  Use this method for strict reduction when partial\n        /// results are merged via `Append`.\n        /// </summary>\n        public B FoldMapBack<B>(Func<A, B> f) where B : Monoid<B> =>\n            T.FoldMapBack(f, ta);\n\n        /// <summary>\n        /// A left-associative variant of 'FoldMap' that is strict in the\n        /// accumulator.  Use this method for strict reduction when partial\n        /// results are merged via `Append`.\n        /// </summary>\n        public B FoldMapBackWhile<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate) where B : Monoid<B> =>\n            T.FoldMapWhileBack(f, predicate, ta);\n\n        /// <summary>\n        /// A left-associative variant of 'FoldMap' that is strict in the\n        /// accumulator.  Use this method for strict reduction when partial\n        /// results are merged via `Append`.\n        /// </summary>\n        public B FoldMapBackUntil<B>(Func<A, B> f, Func<(B State, A Value), bool> predicate) where B : Monoid<B> =>\n            T.FoldMapUntilBack(f, predicate, ta);\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        public Seq<A> ToSeq() =>\n            T.ToSeq(ta);\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        public Lst<A> ToLst() =>\n            T.ToLst(ta);\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        public Arr<A> ToArr() =>\n            T.ToArr(ta);\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        public Iterable<A> ToIterable() =>\n            T.ToIterable(ta);\n\n        /// <summary>\n        /// List of elements of a structure, from left to right\n        /// </summary>\n        public bool IsEmpty =>\n            T.IsEmpty(ta);\n\n        /// <summary>\n        /// Returns the size/length of a finite structure as an `int`.  The\n        /// default implementation just counts elements starting with the leftmost.\n        /// \n        /// Instances for structures that can compute the element count faster\n        /// than via element-by-element counting, should provide a specialised\n        /// implementation.\n        /// </summary>\n        public int Count =>\n            T.Count(ta);\n\n        /// <summary>\n        /// Does an element that fits the predicate occur in the structure?\n        /// </summary>\n        public bool Exists(Func<A, bool> predicate) =>\n            T.Exists(predicate, ta);\n\n        /// <summary>\n        /// Does the predicate hold for all elements in the structure?\n        /// </summary>\n        public bool ForAll(Func<A, bool> predicate) =>\n            T.ForAll(predicate, ta);\n    }\n\n    extension<EqA, T, A>(K<T, A> ta) where EqA : Eq<A> where T : Foldable<T>\n    {\n        /// <summary>\n        /// Does the element exist in the structure?\n        /// </summary>\n        public bool Contains(A value) =>\n            T.Contains<EqA, A>(value, ta);\n    }\n\n    extension<T, A>(K<T, A> ta) where T : Foldable<T>\n    {\n        /// <summary>\n        /// Does the element exist in the structure?\n        /// </summary>\n        public bool Contains(A value) =>\n            T.Contains(value, ta);\n\n        /// <summary>\n        /// Find the first element that match the predicate\n        /// </summary>\n        public Option<A> Find(Func<A, bool> predicate) =>\n            T.Find(predicate, ta);\n\n        /// <summary>\n        /// Find the last element that match the predicate\n        /// </summary>\n        public Option<A> FindBack(Func<A, bool> predicate) =>\n            T.FindBack(predicate, ta);\n\n        /// <summary>\n        /// Find the elements that match the predicate\n        /// </summary>\n        public Iterable<A> FindAll(Func<A, bool> predicate) =>\n            T.FindAll(predicate, ta);\n\n        /// <summary>\n        /// Find the elements that match the predicate\n        /// </summary>\n        public Iterable<A> FindAllBack(Func<A, bool> predicate) =>\n            T.FindAllBack(predicate, ta);\n    }\n\n    extension<T, A>(K<T, A> ta) \n        where T : Foldable<T> \n        where A : IAdditionOperators<A, A, A>, IAdditiveIdentity<A, A>\n    {\n        /// <summary>\n        /// Computes the sum of the numbers of a structure.\n        /// </summary>\n        public A Sum() =>\n            T.Sum(ta);\n    }\n\n    extension<T, A>(K<T, A> ta) \n        where T : Foldable<T> \n        where A : IMultiplyOperators<A, A, A>, IMultiplicativeIdentity<A, A>\n    {\n        /// <summary>\n        /// Computes the product of the numbers of a structure.\n        /// </summary>\n        public A Product() =>\n            T.Product(ta);\n    }\n\n    extension<T, A>(K<T, A> ta) \n        where T : Foldable<T>\n    {\n        /// <summary>\n        /// Get the head item in the foldable or `None`\n        /// </summary>\n        public Option<A> Head =>\n            T.Head(ta);\n\n        /// <summary>\n        /// Get the head item in the foldable or `None`\n        /// </summary>\n        public Option<A> Last =>\n            T.Last(ta);\n\n        /// <summary>\n        /// Map each element of a structure to an 'Applicative' action, evaluate these\n        /// actions from left to right, and ignore the results.  For a version that\n        /// doesn't ignore the results see `Traversable.traverse`.\n        /// </summary>\n        public K<F, Unit> Iter<F, B>(Func<A, K<F, B>> f) \n            where F : Monad<F> =>\n            T.Iter(f, ta);\n\n        /// <summary>\n        /// Map each element of a structure to an action, evaluate these\n        /// actions from left to right, and ignore the results.  For a version that\n        /// doesn't ignore the results see `Traversable.traverse`.\n        /// </summary>\n        public Unit Iter(Action<A> f) =>\n            T.Iter(f, ta);\n\n        /// <summary>\n        /// Map each element of a structure to an action, evaluate these\n        /// actions from left to right, and ignore the results.  For a version that\n        /// doesn't ignore the results see `Traversable.traverse`.\n        /// </summary>\n        public Unit Iter(Action<int, A> f) =>\n            T.Iter(f, ta);\n    }\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static Option<A> Min<OrdA, T, A>(this K<T, A> ta)\n        where T : Foldable<T>\n        where OrdA : Ord<A> =>\n        T.Min<OrdA, A>(ta);\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static Option<A> Min<T, A>(this K<T, A> ta)\n        where T : Foldable<T>\n        where A : IComparable<A> =>\n        T.Min(ta);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static Option<A> Max<OrdA, T, A>(this K<T, A> ta)\n        where T : Foldable<T>\n        where OrdA : Ord<A> =>\n        T.Max<OrdA, A>(ta);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static Option<A> Max<T, A>(this K<T, A> ta)\n        where T : Foldable<T>\n        where A : IComparable<A> =>\n        T.Max(ta);\n    \n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static A Min<OrdA, T, A>(this K<T, A> ta, A initialMin)\n        where T : Foldable<T>\n        where OrdA : Ord<A> =>\n        T.Min<OrdA, A>(ta, initialMin);\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static A Min<T, A>(this K<T, A> ta, A initialMin)\n        where T : Foldable<T>\n        where A : IComparable<A> =>\n        T.Min(ta, initialMin);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static A Max<OrdA, T, A>(this K<T, A> ta, A initialMax)\n        where T : Foldable<T>\n        where OrdA : Ord<A> =>\n        T.Max<OrdA, A>(ta, initialMax);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static A Max<T, A>(this K<T, A> ta, A initialMax)\n        where T : Foldable<T>\n        where A : IComparable<A> =>\n        T.Max(ta, initialMax);    \n\n    /// <summary>\n    /// Find the average of all the values in the structure\n    /// </summary>\n    public static A Average<T, A>(this K<T, A> ta)\n        where T : Foldable<T>\n        where A : INumber<A> =>\n        T.Average(ta);\n\n    /// <summary>\n    /// Find the average of all the values in the structure\n    /// </summary>\n    public static B Average<T, A, B>(this K<T, A> ta, Func<A, B> f)\n        where T : Foldable<T>\n        where B : INumber<B> =>\n        T.Average(f, ta);\n\n    /// <summary>\n    /// Find the element at the specified index or `None` if out of range\n    /// </summary>\n    public static Option<A> At<T, A>(this K<T, A> ta, Index index)\n        where T : Foldable<T> =>\n        T.At(ta, index);\n\n    /// <summary>\n    /// Partition a foldable into two sequences based on a predicate\n    /// </summary>\n    /// <param name=\"f\">Predicate function</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Partitioned structure</returns>\n    public static (Seq<A> True, Seq<A> False) Partition<T, A>(this K<T, A> ta, Func<A, bool> f)\n        where T : Foldable<T> =>\n        T.Partition(f, ta);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Foldable/Foldable.ExtensionsT.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Numerics;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FoldableExtensions\n{\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S FoldWhileT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate)\n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => Foldable.foldWhile(f, predicate, s1, ua), initialState, tua);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S FoldWhileT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate)\n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => Foldable.foldWhile(f, predicate, s1, ua), initialState, tua);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S FoldBackWhileT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBackWhile(f, predicate, s1, ua), initialState, tua);\n    \n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S FoldBackWhileT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBackWhile(f, predicate, s1, ua), initialState, tua);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S FoldUntilT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => Foldable.foldUntil(f, predicate, s1, ua), initialState, tua);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S FoldUntilT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => Foldable.foldUntil(f, predicate, s1, ua), initialState, tua);\n    \n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S FoldBackUntilT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBackUntil(f, predicate, s1, ua), initialState, tua);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S FoldBackUntilT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBackUntil(f, predicate, s1, ua), initialState, tua);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static S FoldT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<A, Func<S, S>> f) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => Foldable.fold(f, s1, ua), initialState, tua);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static S FoldT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, A, S> f) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => Foldable.fold(f, s1, ua), initialState, tua);\n    \n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static S FoldBackT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, Func<A, S>> f) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBack(f, s1, ua), initialState, tua);\n    \n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static S FoldBackT<T, U, A, S>(\n        this K<T, K<U, A>> tua,\n        S initialState,\n        Func<S, A, S> f) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBack(f, s1, ua), initialState, tua);\n    \n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A FoldT<T, U, A>(this K<T, K<U, A>> tua) \n        where T : Foldable<T> \n        where U : Foldable<U>\n        where A : Monoid<A> =>\n        Foldable.fold(ua => s1 => Foldable.fold(a => s => s + a, s1, ua), A.Empty, tua);\n\n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A FoldWhileT<T, U, A>(this K<T, K<U, A>> tua, Func<(A State, A Value), bool> predicate) \n        where T : Foldable<T> \n        where U : Foldable<U>\n        where A : Monoid<A> =>\n        Foldable.fold(ua => s1 => Foldable.foldWhile(a => s => s + a, predicate, s1, ua), A.Empty, tua);\n\n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A FoldUntilT<T, U, A>(this K<T, K<U, A>> tua, Func<(A State, A Value), bool> predicate) \n        where T : Foldable<T> \n        where U : Foldable<U>\n        where A : Monoid<A> =>\n        Foldable.fold(ua => s1 => Foldable.foldUntil(a => s => s + a, predicate, s1, ua), A.Empty, tua);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B FoldMapT<T, U, A, B>(this K<T, K<U, A>> tua, Func<A, B> f)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where B : Monoid<B> =>\n        Foldable.fold(ua => s1 => Foldable.fold(a => s => s + f(a), s1, ua), B.Empty, tua);  \n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B FoldMapWhileT<T, U, A, B>(this K<T, K<U, A>> tua, Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where B : Monoid<B> =>\n        Foldable.fold(ua => s1 => Foldable.foldWhile(a => s => s + f(a), predicate, s1, ua), B.Empty, tua);  \n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B FoldMapUntilT<T, U, A, B>(this K<T, K<U, A>> tua, Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where B : Monoid<B> =>\n        Foldable.fold(ua => s1 => Foldable.foldUntil(a => s => s + f(a), predicate, s1, ua), B.Empty, tua);  \n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B FoldMapBackT<T, U, A, B>(this K<T, K<U, A>> tua, Func<A, B> f)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where B : Monoid<B> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBack(s => a => s + f(a), s1, ua), B.Empty, tua);  \n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B FoldMapBackWhileT<T, U, A, B>(this K<T, K<U, A>> tua, Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where B : Monoid<B> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBackWhile(s => a => s + f(a), predicate, s1, ua), B.Empty, tua);  \n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B FoldMapBackUntilT<T, U, A, B>(this K<T, K<U, A>> tua, Func<A, B> f, Func<(B State, A Value), bool> predicate)\n        where T : Foldable<T> \n        where U : Foldable<U>\n        where B : Monoid<B> =>\n        Foldable.foldBack(s1 => ua => Foldable.foldBackUntil(s => a => s + f(a), predicate, s1, ua), B.Empty, tua);\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static Seq<A> ToSeqT<T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => Foldable.fold(a => s => s.Add(a), s1, ua), Seq<A>.Empty, tua);\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static Lst<A> ToLstT<T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => Foldable.fold(a => s => s.Add(a), s1, ua), Lst<A>.Empty, tua);\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static Arr<A> ToArrT<T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U>\n    {\n        return new(Go().ToArray());\n        IEnumerable<A> Go()\n        {\n            foreach(var ua in tua.ToIterable())\n            {\n                foreach (var a in ua.ToIterable())\n                {\n                    yield return a;\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static Iterable<A> ToEnumerableT<T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(\n            ua => s1 => Foldable.fold(\n                      a => s =>\n                           {\n                               s.Add(a);\n                               return s;\n                           },\n                      s1,\n                      ua),\n            new List<A>(),\n            tua).AsIterable();\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static bool IsEmptyT<T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(ua => s => s && ua.IsEmpty, true, tua);\n    \n    /// <summary>\n    /// Returns the size/length of a finite structure as an `int`.  The\n    /// default implementation just counts elements starting with the leftmost.\n    /// \n    /// Instances for structures that can compute the element count faster\n    /// than via element-by-element counting, should provide a specialised\n    /// implementation.\n    /// </summary>\n    public static int CountT<T, U, A>(this K<T, K<U, A>> tua) \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(ua => s => s + ua.Count, 0, tua);\n\n    /// <summary>\n    /// Does an element that fits the predicate occur in the structure?\n    /// </summary>\n    public static bool ExistsT<T, U, A>(this K<T, K<U, A>> tua, Func<A, bool> predicate) \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(ua => s => s || ua.Exists(predicate), false, tua);\n\n    /// <summary>\n    /// Does the predicate hold for all elements in the structure?\n    /// </summary>\n    public static bool ForAllT<T, U, A>(this K<T, K<U, A>> tua, Func<A, bool> predicate) \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(ua => s => s && ua.ForAll(predicate), true, tua);\n    \n    /// <summary>\n    /// Does the element exist in the structure?\n    /// </summary>\n    public static bool ContainsT<EqA, T, U, A>(this K<T, K<U, A>> tua, A value) \n        where EqA : Eq<A> \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.exists(ua => Foldable.contains<EqA, U, A>(value, ua), tua);\n    \n    /// <summary>\n    /// Does the element exist in the structure?\n    /// </summary>\n    public static bool ContainsT<T, U, A>(this K<T, K<U, A>> tua, A value) \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.exists(ua => Foldable.contains(value, ua), tua);\n    \n    /// <summary>\n    /// Find the first element that match the predicate\n    /// </summary>\n    public static Option<A> FindT<T, U, A>(this K<T, K<U, A>> tua, Func<A, bool> predicate)\n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.foldWhile(ua => s1 => s1 || Foldable.find(predicate, ua), s => s.State.IsNone, Option<A>.None, tua);\n\n    /// <summary>\n    /// Find the last element that match the predicate\n    /// </summary>\n    public static Option<A> FindBackT<T, U, A>(this K<T, K<U, A>> tua, Func<A, bool> predicate) \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.foldBackWhile(s1 => ua => s1 || Foldable.find(predicate, ua), s => s.State.IsNone, Option<A>.None, tua);\n\n    /// <summary>\n    /// Find the the elements that match the predicate\n    /// </summary>\n    public static Iterable<A> FindAllT<T, U, A>(this K<T, K<U, A>> tua, Func<A, bool> predicate)\n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(ua => s1 => s1 + Foldable.findAll(predicate, ua), Iterable<A>.Empty, tua);\n\n    /// <summary>\n    /// Find the the elements that match the predicate\n    /// </summary>\n    public static Iterable<A> FindAllBackT<T, U, A>(this K<T, K<U, A>> tua, Func<A, bool> predicate) \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.foldBack(s1 => ua => s1 + Foldable.findAllBack(predicate, ua), Iterable<A>.Empty, tua);\n    \n    /// <summary>\n    /// Computes the sum of the numbers of a structure.\n    /// </summary>\n    public static A SumT<T, U, A>(this K<T, K<U, A>> tua) \n        where T : Foldable<T>\n        where U : Foldable<U>\n        where A : IAdditionOperators<A, A, A>, IAdditiveIdentity<A, A> =>\n        Foldable.fold(ua => s => s + Foldable.sum(ua), A.AdditiveIdentity, tua);\n\n    /// <summary>\n    /// Computes the product of the numbers of a structure.\n    /// </summary>\n    public static A ProductT<T, U, A>(this K<T, K<U, A>> tua) \n        where T : Foldable<T>\n        where U : Foldable<U>\n        where A : IMultiplyOperators<A, A, A>, IMultiplicativeIdentity<A, A> =>\n        Foldable.fold(ua => s => s * Foldable.product(ua), A.MultiplicativeIdentity, tua);\n\n    /// <summary>\n    /// Get the head item in the foldable or `None`\n    /// </summary>\n    public static Option<A> HeadT<T, U, A>(this K<T, K<U, A>> tua) \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.foldWhile(\n                     ua => s => s || Foldable.head(ua), \n                     s => s.State.IsNone, \n                     Option<A>.None, \n                     tua);\n\n    /// <summary>\n    /// Get the head item in the foldable or `None`\n    /// </summary>\n    public static Option<A> LastT<T, U, A>(this K<T, K<U, A>> tua) \n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.foldBackWhile(\n                     s => ua => s || Foldable.last(ua), \n                     s => s.State.IsNone, \n                     Option<A>.None, \n                     tua);\n\n    /// <summary>\n    /// Map each element of a structure to an 'Applicative' action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static K<F, Unit> IterT<T, U, A, F, B>(this K<T, K<U, A>> tua, Func<A, K<F, B>> f)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where F : Monad<F> =>\n        Foldable.iter(ua => Foldable.iter(f, ua), tua);\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static Unit IterT<T, U, A>(this K<T, K<U, A>> tua, Action<int, A> f) \n        where T : Foldable<T> \n        where U : Foldable<U> =>\n        ignore(Foldable.fold(ua => ix1 => Foldable.fold(a => ix2 => { f(ix2, a); return ix2 + 1; }, ix1, ua), 0, tua));\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static Unit IterT<T, U, A>(this K<T, K<U, A>> tua, Action<A> f)\n        where T : Foldable<T>\n        where U : Foldable<U> =>\n        Foldable.fold(ua => _ => Foldable.iter(f, ua), unit, tua);\n    \n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static Option<A> MinT<OrdA, T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where OrdA : Ord<A> =>\n        Foldable.fold(\n            ua => s => s switch\n                       {\n                           { IsSome: true, Value: A value } => Foldable.min<OrdA, U, A>(ua, value),\n                           _                                => Foldable.min<OrdA, U, A>(ua)\n                       },\n            Option<A>.None,\n            tua);\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static Option<A> MinT<T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where A : IComparable<A> =>\n        Foldable.fold(\n            ua => s => s switch\n                       {\n                           { IsSome: true, Value: A value } => Foldable.min(ua, value),\n                           _                                => Foldable.min(ua)\n                       },\n            Option<A>.None,\n            tua);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static Option<A> MaxT<OrdA, T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where OrdA : Ord<A> =>\n        Foldable.fold(\n            ua => s => s switch\n                       {\n                           { IsSome: true, Value: A value } => Foldable.max<OrdA, U, A>(ua, value),\n                           _                                => Foldable.max<OrdA, U, A>(ua)\n                       },\n            Option<A>.None,\n            tua);\n    \n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static Option<A> MaxT<T, U, A>(this K<T, K<U, A>> tua)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where A : IComparable<A> =>\n        Foldable.fold(\n            ua => s => s switch\n                       {\n                           { IsSome: true, Value: A value } => Foldable.max(ua, value),\n                           _                                => Foldable.max(ua)\n                       },\n            Option<A>.None,\n            tua);\n        \n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static A MinT<OrdA, T, U, A>(this K<T, K<U, A>> tua, A initialMin)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where OrdA : Ord<A> =>\n        Foldable.fold(ua => s => Foldable.min<OrdA, U, A>(ua, s), initialMin, tua);\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static A MinT<T, U, A>(this K<T, K<U, A>> tua, A initialMin)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where A : IComparable<A> =>\n        Foldable.fold(ua => s => Foldable.min(ua, s), initialMin, tua);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static A MaxT<OrdA, T, U, A>(this K<T, K<U, A>> tua, A initialMax)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where OrdA : Ord<A> =>\n        Foldable.fold(ua => s => Foldable.max<OrdA, U, A>(ua, s), initialMax, tua);\n    \n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static A MaxT<T, U, A>(this K<T, K<U, A>> tua, A initialMax)\n        where T : Foldable<T>\n        where U : Foldable<U>\n        where A : IComparable<A> =>\n        Foldable.fold(ua => s => Foldable.max(ua, s), initialMax, tua);\n\n    /// <summary>\n    /// Find the average of all the values in the structure\n    /// </summary>\n    public static A AverageT<T, A>(this K<T, A> ta)\n        where T : Foldable<T>\n        where A : INumber<A> =>\n        T.Average(ta);\n\n    /// <summary>\n    /// Find the average of all the values in the structure\n    /// </summary>\n    public static B AverageT<T, A, B>(this K<T, A> ta, Func<A, B> f)\n        where T : Foldable<T>\n        where B : INumber<B> =>\n        T.Average(f, ta);\n\n    /// <summary>\n    /// Find the element at the specified index or `None` if out of range\n    /// </summary>\n    public static Option<A> AtT<T, A>(this K<T, A> ta, Index index)\n        where T : Foldable<T> =>\n        T.At(ta, index);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Foldable/Foldable.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Numerics;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic static class Foldable\n{\n    /// <summary>\n    /// Fold the structure: `ta` and pass each element that it yields to `f`, resulting in an `F` applicative-value.\n    /// The fold operator is applicative `Action`, which causes each applicative-value to be sequenced.      \n    /// </summary>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <param name=\"f\">Mapping operation</param>\n    /// <typeparam name=\"T\">Foldable</typeparam>\n    /// <typeparam name=\"F\">Applicative</typeparam>\n    /// <typeparam name=\"A\">Input bound value</typeparam>\n    /// <typeparam name=\"B\">Mapping bound value</typeparam>\n    /// <returns></returns>\n    public static K<F, Unit> forM<T, F, A, B>(K<T, A> ta, Func<A, K<F, B>> f)\n        where F : Applicative<F>\n        where T : Foldable<T> =>\n        ta.Fold(pure<F, Unit>(unit), x => f(x).Action);\n    \n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S foldWhile<T, A, S>(\n        Func<A, Func<S, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState,\n        K<T, A> ta)\n        where T : Foldable<T> =>\n        T.FoldWhile(f, predicate, initialState, ta);\n    \n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S foldWhile<T, A, S>(\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState,\n        K<T, A> ta)\n        where T : Foldable<T> =>\n        T.FoldWhile(a => s => f(s, a), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S foldBackWhile<T, A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBackWhile(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S foldBackWhile<T, A, S>(\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBackWhile(curry(f), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldWhileM<T, A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldWhileM(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldWhileM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldWhileM<A, M, S>(a => s => f(s, a), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldBackWhileM<T, A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T> \n        where M : Monad<M> =>\n        T.FoldBackWhileM(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldBackWhileM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T> \n        where M : Monad<M> =>\n        T.FoldBackWhileM(curry(f), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S foldUntil<T, A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldUntil(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S foldUntil<T, A, S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldUntil(a => s => f(s, a), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldUntilM<T, A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where M : Monad<M>\n        where T : Foldable<T> => \n        T.FoldUntilM(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldUntilM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where M : Monad<M>\n        where T : Foldable<T> => \n        T.FoldUntilM<A, M, S>(a => s => f(s, a), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S foldBackUntil<T, A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBackUntil(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S foldBackUntil<T, A, S>(\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBackUntil(curry(f), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldBackUntilM<T, A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T> \n        where M : Monad<M> =>\n        T.FoldBackUntilM(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldBackUntilM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T> \n        where M : Monad<M> =>\n        T.FoldBackUntilM(curry(f), predicate, initialState, ta);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static S fold<T, A, S>(Func<A, Func<S, S>> f, S initialState, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Fold(f, initialState, ta);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static S fold<T, A, S>(Func<S, A, S> f, S initialState, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Fold(a => s => f(s, a), initialState, ta);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static K<M, S> foldM<T, A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldM(f, initialState, ta);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static K<M, S> foldM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldM<A, M, S>(a => s => f(s, a), initialState, ta);\n    \n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static S foldBack<T, A, S>(Func<S, Func<A, S>> f, S initialState, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBack(f, initialState, ta);\n    \n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static S foldBack<T, A, S>(Func<S, A, S> f, S initialState, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBack(curry(f), initialState, ta);\n\n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static K<M, S> foldBackM<T, A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldBackM(f, initialState, ta);\n\n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static K<M, S> foldBackM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldBackM(curry(f), initialState, ta);\n    \n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A fold<T, A>(K<T, A> tm) \n        where T : Foldable<T>\n        where A : Monoid<A> =>\n        T.FoldMap(identity, tm) ;\n\n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A foldWhile<T, A>(Func<(A State, A Value), bool> predicate, K<T, A> tm) \n        where T : Foldable<T>\n        where A : Monoid<A> =>\n        T.FoldMapWhile(identity, predicate, tm) ;\n\n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A foldUntil<T, A>(Func<(A State, A Value), bool> predicate, K<T, A> tm) \n        where T : Foldable<T>\n        where A : Monoid<A> =>\n        T.FoldMapUntil(identity, predicate, tm) ;\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B foldMap<T, A, B>(Func<A, B> f, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMap(f, ta);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B foldMapWhile<T, A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMapWhile(f, predicate, ta);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B foldMapUntil<T, A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMapUntil(f, predicate, ta);\n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B foldMapBack<T, A, B>(Func<A, B> f, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMapBack(f, ta);\n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B foldMapBackWhile<T, A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMapWhileBack(f, predicate, ta);\n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B foldMapBackUntil<T, A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where T : Foldable<T> \n        where B : Monoid<B> =>\n        T.FoldMapUntilBack(f, predicate, ta);\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static Seq<A> toSeq<T, A>(K<T, A> ta) \n        where T : Foldable<T> =>\n        T.ToSeq(ta);\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static Lst<A> toLst<T, A>(K<T, A> ta) \n        where T : Foldable<T> =>\n        T.ToLst(ta);\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static Arr<A> toArr<T, A>(K<T, A> ta)\n        where T : Foldable<T> =>\n        T.ToArr(ta);\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static Iterable<A> toIterable<T, A>(K<T, A> ta) \n        where T : Foldable<T> =>\n        T.ToIterable(ta);\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static bool isEmpty<T, A>(K<T, A> ta)\n        where T : Foldable<T> =>\n        T.IsEmpty(ta);\n\n    /// <summary>\n    /// Returns the size/length of a finite structure as an `int`.  The\n    /// default implementation just counts elements starting with the leftmost.\n    /// \n    /// Instances for structures that can compute the element count faster\n    /// than via element-by-element counting, should provide a specialised\n    /// implementation.\n    /// </summary>\n    public static int count<T, A>(K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Count(ta);\n\n    /// <summary>\n    /// Does an element that fits the predicate occur in the structure?\n    /// </summary>\n    public static bool exists<T, A>(Func<A, bool> predicate, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Exists(predicate, ta);\n\n    /// <summary>\n    /// Does the predicate hold for all elements in the structure?\n    /// </summary>\n    public static bool forAll<T, A>(Func<A, bool> predicate, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.ForAll(predicate, ta);\n\n    /// <summary>\n    /// Does the element exist in the structure?\n    /// </summary>\n    public static bool contains<EqA, T, A>(A value, K<T, A> ta) \n        where EqA : Eq<A> \n        where T : Foldable<T> =>\n        T.Contains<EqA, A>(value, ta);\n\n    /// <summary>\n    /// Does the element exist in the structure?\n    /// </summary>\n    public static bool contains<T, A>(A value, K<T, A> ta)\n        where T : Foldable<T> =>\n        T.Contains(value, ta);\n\n    /// <summary>\n    /// Find the first element that match the predicate\n    /// </summary>\n    public static Option<A> find<T, A>(Func<A, bool> predicate, K<T, A> ta)\n        where T : Foldable<T> =>\n        T.Find(predicate, ta);\n\n    /// <summary>\n    /// Find the last element that match the predicate\n    /// </summary>\n    public static Option<A> findBack<T, A>(Func<A, bool> predicate, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FindBack(predicate, ta);\n\n    /// <summary>\n    /// Find the elements that match the predicate\n    /// </summary>\n    public static Iterable<A> findAll<T, A>(Func<A, bool> predicate, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FindAll(predicate, ta);\n\n    /// <summary>\n    /// Find the elements that match the predicate\n    /// </summary>\n    public static Iterable<A> findAllBack<T, A>(Func<A, bool> predicate, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FindAllBack(predicate, ta);\n\n    /// <summary>\n    /// Computes the sum of the numbers of a structure.\n    /// </summary>\n    public static A sum<T, A>(K<T, A> ta) \n        where T : Foldable<T> \n        where A : IAdditionOperators<A, A, A>, IAdditiveIdentity<A, A> =>\n        T.Sum(ta);\n\n    /// <summary>\n    /// Computes the product of the numbers of a structure.\n    /// </summary>\n    public static A product<T, A>(K<T, A> ta) \n        where T : Foldable<T> \n        where A : IMultiplyOperators<A, A, A>, IMultiplicativeIdentity<A, A> =>\n        T.Product(ta);\n\n    /// <summary>\n    /// Get the head item in the foldable or `None`\n    /// </summary>\n    public static Option<A> head<T, A>(K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Head(ta);\n\n    /// <summary>\n    /// Get the head item in the foldable or `None`\n    /// </summary>\n    public static Option<A> last<T, A>(K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Last(ta);\n\n    /// <summary>\n    /// Map each element of a structure to an 'Applicative' action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static K<F, Unit> iter<T, A, F, B>(Func<A, K<F, B>> f, K<T, A> ta)\n        where T : Foldable<T>\n        where F : Monad<F> =>\n        T.Iter(f, ta);\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static Unit iter<T, A>(Action<int, A> f, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Iter(f, ta);\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static Unit iter<T, A>(Action<A> f, K<T, A> ta)\n        where T : Foldable<T> =>\n        T.Iter(f, ta);\n    \n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static Option<A> min<OrdA, T, A>(K<T, A> ta)\n        where T : Foldable<T>\n        where OrdA : Ord<A> =>\n        T.Min<OrdA, A>(ta);\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static Option<A> min<T, A>(K<T, A> ta)\n        where T : Foldable<T>\n        where A : IComparable<A> =>\n        T.Min(ta);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static Option<A> max<OrdA, T, A>(K<T, A> ta)\n        where T : Foldable<T>\n        where OrdA : Ord<A> =>\n        T.Max<OrdA, A>(ta);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static Option<A> max<T, A>(K<T, A> ta)\n        where T : Foldable<T>\n        where A : IComparable<A> =>\n        T.Max(ta);\n    \n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static A min<OrdA, T, A>(K<T, A> ta, A initialMin)\n        where T : Foldable<T>\n        where OrdA : Ord<A> =>\n        T.Min<OrdA, A>(ta, initialMin);\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static A min<T, A>(K<T, A> ta, A initialMin)\n        where T : Foldable<T>\n        where A : IComparable<A> =>\n        T.Min(ta, initialMin);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static A max<OrdA, T, A>(K<T, A> ta, A initialMax)\n        where T : Foldable<T>\n        where OrdA : Ord<A> =>\n        T.Max<OrdA, A>(ta, initialMax);\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static A max<T, A>(K<T, A> ta, A initialMax)\n        where T : Foldable<T>\n        where A : IComparable<A> =>\n        T.Max(ta, initialMax);\n\n    /// <summary>\n    /// Find the average of all the values in the structure\n    /// </summary>\n    public static A average<T, A>(K<T, A> ta)\n        where T : Foldable<T>\n        where A : INumber<A> =>\n        T.Average(ta);\n\n    /// <summary>\n    /// Find the average of all the values in the structure\n    /// </summary>\n    public static B average<T, A, B>(Func<A, B> f, K<T, A> ta)\n        where T : Foldable<T>\n        where B : INumber<B> =>\n        T.Average(f, ta);\n\n    /// <summary>\n    /// Find the element at the specified index or `None` if out of range\n    /// </summary>\n    public static Option<A> at<T, A>(K<T, A> ta, Index index)\n        where T : Foldable<T> =>\n        T.At(ta, index);\n\n    /// <summary>\n    /// Partition a foldable into two sequences based on a predicate\n    /// </summary>\n    /// <param name=\"f\">Predicate function</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Partitioned structure</returns>\n    public static (Seq<A> True, Seq<A> False) partition<T, A>(Func<A, bool> f, K<T, A> ta)\n        where T : Foldable<T> =>\n        T.Partition(f, ta);\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Foldable/Foldable.Prelude.cs",
    "content": "using System;\nusing System.Numerics;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S foldWhile<T, A, S>(\n        Func<A, Func<S, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState,\n        K<T, A> ta)\n        where T : Foldable<T> =>\n        T.FoldWhile(f, predicate, initialState, ta);\n    \n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S foldWhile<T, A, S>(\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState,\n        K<T, A> ta)\n        where T : Foldable<T> =>\n        T.FoldWhile(a => s => f(s, a), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S foldBackWhile<T, A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBackWhile(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static S foldBackWhile<T, A, S>(\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBackWhile(curry(f), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldWhileM<T, A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldWhileM(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldWhileM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldWhileM<A, M, S>(a => s => f(s, a), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldBackWhileM<T, A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T> \n        where M : Monad<M> =>\n        T.FoldBackWhileM(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldBackWhileM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T> \n        where M : Monad<M> =>\n        T.FoldBackWhileM(curry(f), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S foldUntil<T, A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldUntil(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S foldUntil<T, A, S>(\n        Func<S, A, S> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldUntil(a => s => f(s, a), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldUntilM<T, A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where M : Monad<M>\n        where T : Foldable<T> => \n        T.FoldUntilM(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldUntilM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where M : Monad<M>\n        where T : Foldable<T> => \n        T.FoldUntilM<A, M, S>(a => s => f(s, a), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S foldBackUntil<T, A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBackUntil(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static S foldBackUntil<T, A, S>(\n        Func<S, A, S> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBackUntil(curry(f), predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldBackUntilM<T, A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T> \n        where M : Monad<M> =>\n        T.FoldBackUntilM(f, predicate, initialState, ta);\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static K<M, S> foldBackUntilM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T> \n        where M : Monad<M> =>\n        T.FoldBackUntilM(curry(f), predicate, initialState, ta);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static S fold<T, A, S>(Func<A, Func<S, S>> f, S initialState, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Fold(f, initialState, ta);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static S fold<T, A, S>(Func<S, A, S> f, S initialState, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Fold(a => s => f(s, a), initialState, ta);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static K<M, S> foldM<T, A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldM(f, initialState, ta);\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static K<M, S> foldM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        S initialState, \n        K<T, A> ta) \n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldM<A, M, S>(a => s => f(s, a), initialState, ta);\n    \n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static S foldBack<T, A, S>(Func<S, Func<A, S>> f, S initialState, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBack(f, initialState, ta);\n    \n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static S foldBack<T, A, S>(Func<S, A, S> f, S initialState, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.FoldBack(curry(f), initialState, ta);\n\n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static K<M, S> foldBackM<T, A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldBackM(f, initialState, ta);\n\n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack' will diverge if given an infinite list.\n    /// </remarks>\n    public static K<M, S> foldBackM<T, A, M, S>(\n        Func<S, A, K<M, S>> f, \n        S initialState, \n        K<T, A> ta)\n        where T : Foldable<T>\n        where M : Monad<M> =>\n        T.FoldBackM(curry(f), initialState, ta);\n    \n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A fold<T, A>(K<T, A> tm) \n        where T : Foldable<T>\n        where A : Monoid<A> =>\n        T.FoldMap(identity, tm) ;\n\n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A foldWhile<T, A>(Func<(A State, A Value), bool> predicate, K<T, A> tm) \n        where T : Foldable<T>\n        where A : Monoid<A> =>\n        T.FoldMapWhile(identity, predicate, tm) ;\n\n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Append` operator.  This fold is right-associative and\n    /// lazy in the accumulator.  When you need a strict left-associative fold,\n    /// use 'foldMap'' instead, with 'id' as the map.\n    /// </summary>\n    public static A foldUntil<T, A>(Func<(A State, A Value), bool> predicate, K<T, A> tm) \n        where T : Foldable<T>\n        where A : Monoid<A> =>\n        T.FoldMapUntil(identity, predicate, tm) ;\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B foldMap<T, A, B>(Func<A, B> f, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMap(f, ta);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B foldMapWhile<T, A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMapWhile(f, predicate, ta);\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static B foldMapUntil<T, A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMapUntil(f, predicate, ta);\n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B foldMapBack<T, A, B>(Func<A, B> f, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMapBack(f, ta);\n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B foldMapWhileBack<T, A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where T : Foldable<T>\n        where B : Monoid<B> =>\n        T.FoldMapWhileBack(f, predicate, ta);\n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static B foldMapUntilBack<T, A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where T : Foldable<T> \n        where B : Monoid<B> =>\n        T.FoldMapUntilBack(f, predicate, ta);\n\n    /// <summary>\n    /// Map each element of a structure to an 'Applicative' action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static K<F, Unit> iter<T, A, F, B>(Func<A, K<F, B>> f, K<T, A> ta)\n        where T : Foldable<T>\n        where F : Monad<F> =>\n        T.Iter(f, ta);\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static Unit iter<T, A>(Action<int, A> f, K<T, A> ta) \n        where T : Foldable<T> =>\n        T.Iter(f, ta);\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static Unit iter<T, A>(Action<A> f, K<T, A> ta)\n        where T : Foldable<T> =>\n        T.Iter(f, ta);\n\n    /// <summary>\n    /// Partition a foldable into two sequences based on a predicate\n    /// </summary>\n    /// <param name=\"f\">Predicate function</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Partitioned structure</returns>\n    public static (Seq<A> True, Seq<A> False) partition<T, A>(Func<A, bool> f, K<T, A> ta)\n        where T : Foldable<T> =>\n        T.Partition(f, ta);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Foldable/Foldable.Trait.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Numerics;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic interface Foldable<out T> where T : Foldable<T>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Abstract members\n    //\n\n    /// <summary>\n    /// Runs a single step of the folding operation. The return value indicates whether the folding\n    /// operation should continue, and if so, what the next step should be.\n    /// </summary>\n    /// <remarks>\n    /// It is up to the consumer of\n    /// this method to implement the actual state-aggregation (the folding) before passing it to the\n    /// continuation function.  \n    /// </remarks>\n    /// <remarks>\n    /// This differs from `FoldStepBack` in that it is a right-associative fold, whereas `FoldStepBack` is a\n    /// left-associative fold.  If that's confusing, think that this works on a list in reverse.\n    /// </remarks>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>A discriminated union that can be either `Done` or `Loop`.</returns>\n    public static abstract Fold<A, S> FoldStep<A, S>(K<T, A> ta, S initialState);\n    \n    /// <summary>\n    /// Runs a single step of the folding operation. The return value indicates whether the folding\n    /// operation should continue, and if so, what the next step should be.\n    /// </summary>\n    /// <remarks>\n    /// It is up to the consumer of\n    /// this method to implement the actual state-aggregation (the folding) before passing it to the\n    /// continuation function.  \n    /// </remarks>\n    /// <remarks>\n    /// This differs from `FoldStep` in that it is a left-associative fold, whereas `FoldStepBack` is a\n    /// right-associative fold.  If that's confusing, think that this works on a list in reverse.\n    /// </remarks>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <param name=\"initialState\">Initial state value</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>A discriminated union that can be either `Done` or `Loop`.</returns>\n    public static abstract Fold<A, S> FoldStepBack<A, S>(K<T, A> ta, S initialState);\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Default implementations\n    //\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static virtual S FoldWhile<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState,\n        K<T, A> ta)\n    {\n        var step = T.FoldStep(ta, initialState);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return state;\n                \n                case Fold<A, S>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        step = next(f(value)(state));\n                    }\n                    else\n                    {\n                        return state;\n                    }                    \n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair \n    /// </summary>\n    public static virtual S FoldBackWhile<A, S>(\n        Func<S, Func<A, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState,\n        K<T, A> ta)\n    {\n        var step = T.FoldStepBack(ta, initialState);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return state;\n                \n                case Fold<A, S>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        step = next(f(state)(value));\n                    }\n                    else\n                    {\n                        return state;\n                    }                    \n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public static virtual S FoldMaybe<A, S>(\n        Func<S, Func<A, Option<S>>> f,\n        S initialState,\n        K<T, A> ta)\n    {\n        var step = T.FoldStep(ta, initialState);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return state;\n                \n                case Fold<A, S>.Loop(var state, var value, var next):\n                    switch(f(state)(value))\n                    {\n                        case { IsSome: true, Case: S state1}:\n                            step = next(state1);\n                            break;\n                        \n                        default:\n                            return state;\n                    }\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Fold until the `Option` returns `None`\n    /// </summary>\n    /// <param name=\"f\">Fold function</param>\n    /// <param name=\"initialState\">Initial state for the fold</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Aggregated value</returns>\n    public static virtual S FoldBackMaybe<A, S>(\n        Func<A, Func<S, Option<S>>> f,\n        S initialState,\n        K<T, A> ta)\n    {\n        var step = T.FoldStepBack(ta, initialState);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return state;\n                \n                case Fold<A, S>.Loop(var state, var value, var next):\n                    switch(f(value)(state))\n                    {\n                        case { IsSome: true, Case: S state1}:\n                            step = next(state1);\n                            break;\n                        \n                        default:\n                            return state;\n                    }\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static virtual K<M, S> FoldWhileM<A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where M : Monad<M>\n    {\n        var step = T.FoldStep(ta, initialState);\n        return Monad.recur(step, go); \n\n        K<M, Next<Fold<A, S>, S>> go(Fold<A, S> step)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return M.Pure(Next.Done<Fold<A, S>, S>(state));\n\n                case Fold<A, S>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return f(value)(state).Map(s => Next.Loop<Fold<A, S>, S>(next(s)));\n                    }\n                    else\n                    {\n                        return M.Pure(Next.Done<Fold<A, S>, S>(state));\n                    }\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static virtual K<M, S> FoldBackWhileM<A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where M : Monad<M>\n    {\n        var step = T.FoldStepBack(ta, initialState);\n        return Monad.recur(step, go); \n\n        K<M, Next<Fold<A, S>, S>> go(Fold<A, S> step)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return M.Pure(Next.Done<Fold<A, S>, S>(state));\n\n                case Fold<A, S>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return f(state)(value).Map(s => Next.Loop<Fold<A, S>, S>(next(s)));\n                    }\n                    else\n                    {\n                        return M.Pure(Next.Done<Fold<A, S>, S>(state));\n                    }\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Same behaviour as `Fold` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static virtual S FoldUntil<A, S>(\n        Func<A, Func<S, S>> f,\n        Func<(S State, A Value), bool> predicate,\n        S initialState,\n        K<T, A> ta)\n    {\n        var step = T.FoldStep(ta, initialState);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return state;\n                \n                case Fold<A, S>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return state;\n                    }\n                    else\n                    {\n                        step = next(f(value)(state));\n                    }                    \n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Same behaviour as `Fold` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static virtual K<M, S> FoldUntilM<A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta) \n        where M : Monad<M>\n    {\n        var step = T.FoldStep(ta, initialState);\n        return Monad.recur(step, go); \n\n        K<M, Next<Fold<A, S>, S>> go(Fold<A, S> step)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return M.Pure(Next.Done<Fold<A, S>, S>(state));\n\n                case Fold<A, S>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return M.Pure(Next.Done<Fold<A, S>, S>(state));\n                    }\n                    else\n                    {\n                        return f(value)(state).Map(s => Next.Loop<Fold<A, S>, S>(next(s)));\n                    }\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Same behaviour as `FoldBack` but allows early exit of the operation once\n    /// the predicate function becomes `false` for the state/value pair\n    /// </summary>\n    public static virtual S FoldBackUntil<A, S>(\n        Func<S, Func<A, S>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n    {\n        var step = T.FoldStepBack(ta, initialState);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return state;\n                \n                case Fold<A, S>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return state;\n                    }\n                    else\n                    {\n                        step = next(f(state)(value));\n                    }                    \n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Same behaviour as `FoldBack` but the fold operation returns a monadic type and allows\n    /// early exit of the operation once the predicate function becomes `false` for the\n    /// state/value pair \n    /// </summary>\n    public static virtual K<M, S> FoldBackUntilM<A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        Func<(S State, A Value), bool> predicate, \n        S initialState, \n        K<T, A> ta)\n        where M : Monad<M>\n    {\n        var step = T.FoldStepBack(ta, initialState);\n        return Monad.recur(step, go); \n\n        K<M, Next<Fold<A, S>, S>> go(Fold<A, S> step)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return M.Pure(Next.Done<Fold<A, S>, S>(state));\n\n                case Fold<A, S>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return M.Pure(Next.Done<Fold<A, S>, S>(state));\n                    }\n                    else\n                    {\n                        return f(state)(value).Map(s => Next.Loop<Fold<A, S>, S>(next(s)));\n                    }\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static virtual S Fold<A, S>(Func<A, Func<S, S>> f, S initialState, K<T, A> ta)\n    {\n        var step = T.FoldStep(ta, initialState);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return state;\n                \n                case Fold<A, S>.Loop(var state, var value, var next):\n                    step = next(f(value)(state));\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Right-associative fold of a structure, lazy in the accumulator.\n    ///\n    /// In the case of lists, 'Fold', when applied to a binary operator, a\n    /// starting value (typically the right-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from right to left.\n    /// </summary>\n    public static virtual K<M, S> FoldM<A, M, S>(\n        Func<A, Func<S, K<M, S>>> f, \n        S initialState, \n        K<T, A> ta) \n        where M : Monad<M>\n    {\n        var step = T.FoldStep(ta, initialState);\n        return Monad.recur(step, go); \n\n        K<M, Next<Fold<A, S>, S>> go(Fold<A, S> step)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return M.Pure(Next.Done<Fold<A, S>, S>(state));\n\n                case Fold<A, S>.Loop(var state, var value, var next):\n                    return f(value)(state).Map(s => Next.Loop<Fold<A, S>, S>(next(s)));\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack` will diverge if given an infinite list.\n    /// </remarks>\n    public static virtual S FoldBack<A, S>(Func<S, Func<A, S>> f, S initialState, K<T, A> ta)\n    {\n        var step = T.FoldStepBack(ta, initialState);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return state;\n                \n                case Fold<A, S>.Loop(var state, var value, var next):\n                    step = next(f(state)(value));\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Left-associative fold of a structure, lazy in the accumulator.  This\n    /// is rarely what you want, but can work well for structures with efficient\n    /// right-to-left sequencing and an operator that is lazy in its left\n    /// argument.\n    /// \n    /// In the case of lists, 'FoldLeft', when applied to a binary operator, a\n    /// starting value (typically the left-identity of the operator), and a\n    /// list, reduces the list using the binary operator, from left to right\n    /// </summary>\n    /// <remarks>\n    /// Note that to produce the outermost application of the operator the\n    /// entire input list must be traversed.  Like all left-associative folds,\n    /// `FoldBack` will diverge if given an infinite list.\n    /// </remarks>\n    public static virtual K<M, S> FoldBackM<A, M, S>(\n        Func<S, Func<A, K<M, S>>> f, \n        S initialState, \n        K<T, A> ta)\n        where M : Monad<M>\n    {\n        var step = T.FoldStepBack(ta, initialState);\n        return Monad.recur(step, go); \n\n        K<M, Next<Fold<A, S>, S>> go(Fold<A, S> step)\n        {\n            switch (step)\n            {\n                case Fold<A, S>.Done(var state):\n                    return M.Pure(Next.Done<Fold<A, S>, S>(state));\n\n                case Fold<A, S>.Loop(var state, var value, var next):\n                    return f(state)(value).Map(s => Next.Loop<Fold<A, S>, S>(next(s)));\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Combine` operator\n    /// </summary>\n    public static virtual A Fold<A>(K<T, A> ta) \n        where A : Monoid<A>\n    {\n        var step = T.FoldStep(ta, A.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, A>.Done(var state):\n                    return state;\n                \n                case Fold<A, A>.Loop(var state, var value, var next):\n                    step = next(state + value);\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Combine` operator.\n    /// </summary>\n    public static virtual A FoldWhile<A>(Func<(A State, A Value), bool> predicate, K<T, A> ta) \n        where A : Monoid<A>\n    {\n        var step = T.FoldStep(ta, A.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, A>.Done(var state):\n                    return state;\n                \n                case Fold<A, A>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        step = next(state + value);\n                    }\n                    else\n                    {\n                        return state;\n                    }\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Given a structure with elements whose type is a `Monoid`, combine them\n    /// via the monoid's `Combine` operator.\n    /// </summary>\n    public static virtual A FoldUntil<A>(Func<(A State, A Value), bool> predicate, K<T, A> ta) \n        where A : Monoid<A> \n    {\n        var step = T.FoldStep(ta, A.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, A>.Done(var state):\n                    return state;\n                \n                case Fold<A, A>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return state;\n                    }\n                    else\n                    {\n                        step = next(state + value);\n                    }\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Monoid.Combine`.  \n    /// </summary>\n    public static virtual B FoldMap<A, B>(Func<A, B> f, K<T, A> ta)\n        where B : Monoid<B> \n    {\n        var step = T.FoldStep(ta, B.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, B>.Done(var state):\n                    return state;\n                \n                case Fold<A, B>.Loop(var state, var value, var next):\n                    step = next(state + f(value));\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Combine`.  \n    /// </summary>\n    public static virtual B FoldMapWhile<A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where B : Monoid<B> \n    {\n        var step = T.FoldStep(ta, B.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, B>.Done(var state):\n                    return state;\n                \n                case Fold<A, B>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        step = next(state + f(value));\n                    }\n                    else\n                    {\n                        return state;\n                    }\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Map each element of the structure into a monoid, and combine the\n    /// results with `Append`.  This fold is right-associative and lazy in the\n    /// accumulator.  For strict left-associative folds consider `FoldMapBack`\n    /// instead.\n    /// </summary>\n    public static virtual B FoldMapUntil<A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where B : Monoid<B>\n    {\n        var step = T.FoldStep(ta, B.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, B>.Done(var state):\n                    return state;\n                \n                case Fold<A, B>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return state;\n                    }\n                    else\n                    {\n                        step = next(state + f(value));\n                    }\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static virtual B FoldMapBack<A, B>(Func<A, B> f, K<T, A> ta)\n        where B : Monoid<B> \n    {\n        var step = T.FoldStepBack(ta, B.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, B>.Done(var state):\n                    return state;\n                \n                case Fold<A, B>.Loop(var state, var value, var next):\n                    step = next(state + f(value));\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static virtual B FoldMapWhileBack<A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where B : Monoid<B> \n    {\n        var step = T.FoldStepBack(ta, B.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, B>.Done(var state):\n                    return state;\n                \n                case Fold<A, B>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        step = next(state + f(value));\n                    }\n                    else\n                    {\n                        return state;\n                    }\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// A left-associative variant of 'FoldMap' that is strict in the\n    /// accumulator.  Use this method for strict reduction when partial\n    /// results are merged via `Append`.\n    /// </summary>\n    public static virtual B FoldMapUntilBack<A, B>(Func<A, B> f, Func<(B State, A Value), bool> predicate, K<T, A> ta)\n        where B : Monoid<B>\n    {\n        var step = T.FoldStepBack(ta, B.Empty);\n        while(true)\n        {\n            switch (step)\n            {\n                case Fold<A, B>.Done(var state):\n                    return state;\n                \n                case Fold<A, B>.Loop(var state, var value, var next):\n                    if (predicate((state, value)))\n                    {\n                        return state;\n                    }\n                    else\n                    {\n                        step = next(state + f(value));\n                    }\n                    break;\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static virtual Seq<A> ToSeq<A>(K<T, A> ta)\n    {\n        return new Seq<A>(go());\n\n        IEnumerable<A> go()\n        {\n            var step = T.FoldStep(ta, unit);\n            while (true)\n            {\n                switch (step)\n                {\n                    case Fold<A, Unit>.Done(_):\n                        yield break;\n\n                    case Fold<A, Unit>.Loop(_, var value, var next):\n                        yield return value;\n                        step = next(default);\n                        break;\n\n                    default:\n                        throw new NotSupportedException();\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static virtual Lst<A> ToLst<A>(K<T, A> ta)\n    {\n        return new Lst<A>(go());\n\n        IEnumerable<A> go()\n        {\n            var step = T.FoldStep(ta, unit);\n            while (true)\n            {\n                switch (step)\n                {\n                    case Fold<A, Unit>.Done(_):\n                        yield break;\n\n                    case Fold<A, Unit>.Loop(_, var value, var next):\n                        yield return value;\n                        step = next(default);\n                        break;\n\n                    default:\n                        throw new NotSupportedException();\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static virtual Arr<A> ToArr<A>(K<T, A> ta)\n    {\n        return new Arr<A>(go());\n\n        IEnumerable<A> go()\n        {\n            var step = T.FoldStep(ta, unit);\n            while (true)\n            {\n                switch (step)\n                {\n                    case Fold<A, Unit>.Done(_):\n                        yield break;\n\n                    case Fold<A, Unit>.Loop(_, var value, var next):\n                        yield return value;\n                        step = next(default);\n                        break;\n\n                    default:\n                        throw new NotSupportedException();\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static virtual Iterable<A> ToIterable<A>(K<T, A> ta)\n    {\n        return go().AsIterable();\n\n        IEnumerable<A> go()\n        {\n            var step = T.FoldStep(ta, unit);\n            while (true)\n            {\n                switch (step)\n                {\n                    case Fold<A, Unit>.Done(_):\n                        yield break;\n\n                    case Fold<A, Unit>.Loop(_, var value, var next):\n                        yield return value;\n                        step = next(default);\n                        break;\n\n                    default:\n                        throw new NotSupportedException();\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// List of elements of a structure, from left to right\n    /// </summary>\n    public static virtual bool IsEmpty<A>(K<T, A> ta)\n    {\n        var step = T.FoldStep(ta, unit);\n        switch (step)\n        {\n            case Fold<A, Unit>.Loop(_, _, _):\n                return false;\n\n            default:\n                return true;\n        }\n    }\n\n    /// <summary>\n    /// Returns the size/length of a finite structure as an `int`.  The\n    /// default implementation just counts elements starting with the leftmost.\n    /// \n    /// Instances for structures that can compute the element count faster\n    /// than via element-by-element counting, should provide a specialised\n    /// implementation.\n    /// </summary>\n    public static virtual int Count<A>(K<T, A> ta)\n    {\n        var step  = T.FoldStep(ta, unit);\n        var count = 0;\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return count;\n\n                case Fold<A, Unit>.Loop(_, _, var next):\n                    count++;\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Does an element that fits the predicate occur in the structure?\n    /// </summary>\n    public static virtual bool Exists<A>(Func<A, bool> predicate, K<T, A> ta)\n    {\n        var step  = T.FoldStep(ta, unit);\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return false;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if(predicate(value)) return true;\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Does the predicate hold for all elements in the structure?\n    /// </summary>\n    public static virtual bool ForAll<A>(Func<A, bool> predicate, K<T, A> ta)\n    {\n        var step  = T.FoldStep(ta, unit);\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return true;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if(!predicate(value)) return false;\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Does the element exist in the structure?\n    /// </summary>\n    public static virtual bool Contains<EqA, A>(A value, K<T, A> ta) where EqA : Eq<A>\n    {\n        var step  = T.FoldStep(ta, unit);\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return false;\n\n                case Fold<A, Unit>.Loop(_, var x, var next):\n                    if(EqA.Equals(value, x)) return true;\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Does the element exist in the structure?\n    /// </summary>\n    public static virtual bool Contains<A>(A value, K<T, A> ta) \n    {\n        var step  = T.FoldStep(ta, unit);\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return false;\n\n                case Fold<A, Unit>.Loop(_, var x, var next):\n                    if(EqDefault<A>.Equals(value, x)) return true;\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the first element that match the predicate\n    /// </summary>\n    public static virtual Option<A> Find<A>(Func<A, bool> predicate, K<T, A> ta)\n    {\n        var step  = T.FoldStep(ta, unit);\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return default;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if(predicate(value)) return Some(value);\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the last element that match the predicate\n    /// </summary>\n    public static virtual Option<A> FindBack<A>(Func<A, bool> predicate, K<T, A> ta)\n    {\n        var step  = T.FoldStepBack(ta, unit);\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return default;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if(predicate(value)) return Some(value);\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the elements that match the predicate\n    /// </summary>\n    public static virtual Iterable<A> FindAll<A>(Func<A, bool> predicate, K<T, A> ta)\n    {\n        return go().AsIterable();\n        IEnumerable<A> go()\n        {\n            var step = T.FoldStep(ta, unit);\n            while (true)\n            {\n                switch (step)\n                {\n                    case Fold<A, Unit>.Done(_):\n                        yield break;\n\n                    case Fold<A, Unit>.Loop(_, var value, var next):\n                        if (predicate(value))\n                        {\n                            yield return value;\n                        }\n                        step = next(default);\n                        break;\n\n                    default:\n                        throw new NotSupportedException();\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the elements that match the predicate\n    /// </summary>\n    public static virtual Iterable<A> FindAllBack<A>(Func<A, bool> predicate, K<T, A> ta)\n    {\n        return go().AsIterable();\n        IEnumerable<A> go()\n        {\n            var step = T.FoldStepBack(ta, unit);\n            while (true)\n            {\n                switch (step)\n                {\n                    case Fold<A, Unit>.Done(_):\n                        yield break;\n\n                    case Fold<A, Unit>.Loop(_, var value, var next):\n                        if (predicate(value))\n                        {\n                            yield return value;\n                        }\n                        step = next(default);\n                        break;\n\n                    default:\n                        throw new NotSupportedException();\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Computes the sum of the numbers of a structure.\n    /// </summary>\n    public static virtual A Sum<A>(K<T, A> ta) \n        where A : IAdditionOperators<A, A, A>, IAdditiveIdentity<A, A>\n    {\n        var step = T.FoldStep(ta, A.AdditiveIdentity);\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, A>.Done(var state):\n                    return state;\n\n                case Fold<A, A>.Loop(var state, var value, var next):\n                   step = next(state + value);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Computes the product of the numbers of a structure.\n    /// </summary>\n    public static virtual A Product<A>(K<T, A> ta) \n        where A : IMultiplyOperators<A, A, A>, IMultiplicativeIdentity<A, A>\n    {\n        var step = T.FoldStep(ta, A.MultiplicativeIdentity);\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, A>.Done(var state):\n                    return state;\n\n                case Fold<A, A>.Loop(var state, var value, var next):\n                    step = next(state * value);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Get the head item in the foldable or `None`\n    /// </summary>\n    public static virtual Option<A> Head<A>(K<T, A> ta)\n    {\n        var step = T.FoldStep(ta, unit);\n        switch (step)\n        {\n            case Fold<A, Unit>.Done(_):\n                return default;\n\n            case Fold<A, Unit>.Loop(_, var value, _):\n                return value;\n\n            default:\n                throw new NotSupportedException();\n        }\n    }\n\n    /// <summary>\n    /// Get the last item in the foldable or `None`\n    /// </summary>\n    public static virtual Option<A> Last<A>(K<T, A> ta)\n    {\n        var step = T.FoldStepBack(ta, unit);\n        switch (step)\n        {\n            case Fold<A, Unit>.Done(_):\n                return default;\n\n            case Fold<A, Unit>.Loop(_, var value, _):\n                return value;\n\n            default:\n                throw new NotSupportedException();\n        }\n    }\n    \n    /// <summary>\n    /// Map each element of a structure to a monadic action, evaluate these\n    /// actions from left to right, and ignore the results. \n    /// </summary>\n    public static virtual K<M, Unit> Iter<M, A, B>(Func<A, K<M, B>> f, K<T, A> ta) \n        where M : Monad<M>\n    {\n        var step = T.FoldStep(ta, unit);\n        return Monad.recur(step, go); \n\n        K<M, Next<Fold<A, Unit>, Unit>> go(Fold<A, Unit> step)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return M.Pure(Next.Done<Fold<A, Unit>, Unit>(default));\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    return f(value).Map(_ => Next.Loop<Fold<A, Unit>, Unit>(next(default)));\n\n                default: \n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static virtual Unit Iter<A>(Action<A> f, K<T, A> ta)\n    {\n        var step = T.FoldStep(ta, unit);\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return default;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    f(value);\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these\n    /// actions from left to right, and ignore the results.  For a version that\n    /// doesn't ignore the results see `Traversable.traverse`.\n    /// </summary>\n    public static virtual Unit Iter<A>(Action<int, A> f, K<T, A> ta)\n    {\n        var step = T.FoldStep(ta, unit);\n        var ix   = 0;\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return default;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    f(ix, value);\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static virtual Option<A> Min<OrdA, A>(K<T, A> ta)\n        where OrdA : Ord<A>\n    {\n        var step = T.FoldStep(ta, unit);\n        A current;\n        \n        switch (step)\n        {\n            case Fold<A, Unit>.Done(_):\n                return default;\n\n            case Fold<A, Unit>.Loop(_, var value, var next):\n                current = value;\n                step = next(default);\n                break;\n\n            default:\n                throw new NotSupportedException();\n        }\n\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return current;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (OrdA.Compare(value, current) < 0)\n                    {\n                        current = value;\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static virtual Option<A> Min<A>(K<T, A> ta)\n        where A : IComparable<A> \n    {\n        var step = T.FoldStep(ta, unit);\n        A   current;\n        \n        switch (step)\n        {\n            case Fold<A, Unit>.Done(_):\n                return default;\n\n            case Fold<A, Unit>.Loop(_, var value, var next):\n                current = value;\n                step = next(default);\n                break;\n\n            default:\n                throw new NotSupportedException();\n        }\n\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return current;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (value.CompareTo(current) < 0)\n                    {\n                        current = value;\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static virtual Option<A> Max<OrdA, A>(K<T, A> ta)\n        where OrdA : Ord<A> \n    {\n        var step = T.FoldStep(ta, unit);\n        A   current;\n        \n        switch (step)\n        {\n            case Fold<A, Unit>.Done(_):\n                return default;\n\n            case Fold<A, Unit>.Loop(_, var value, var next):\n                current = value;\n                step = next(default);\n                break;\n\n            default:\n                throw new NotSupportedException();\n        }\n\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return current;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (OrdA.Compare(value, current) > 0)\n                    {\n                        current = value;\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static virtual Option<A> Max<A>(K<T, A> ta)\n        where A : IComparable<A> \n    {\n        var step = T.FoldStep(ta, unit);\n        A   current;\n        \n        switch (step)\n        {\n            case Fold<A, Unit>.Done(_):\n                return default;\n\n            case Fold<A, Unit>.Loop(_, var value, var next):\n                current = value;\n                step = next(default);\n                break;\n\n            default:\n                throw new NotSupportedException();\n        }\n\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return current;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (value.CompareTo(current) > 0)\n                    {\n                        current = value;\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static virtual A Min<OrdA, A>(K<T, A> ta, A initialMin)\n        where OrdA : Ord<A>\n    {\n        var step    = T.FoldStep(ta, unit);\n        var current = initialMin;\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return current;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (OrdA.Compare(value, current) < 0)\n                    {\n                        current = value;\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the minimum value in the structure\n    /// </summary>\n    public static virtual A Min<A>(K<T, A> ta, A initialMin)\n        where A : IComparable<A> \n    {\n        var step    = T.FoldStep(ta, unit);\n        var current = initialMin;\n\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return current;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (value.CompareTo(current) < 0)\n                    {\n                        current = value;\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static virtual A Max<OrdA, A>(K<T, A> ta, A initialMax)\n        where OrdA : Ord<A> \n    {\n        var step    = T.FoldStep(ta, unit);\n        var current = initialMax;\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return current;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (OrdA.Compare(value, current) > 0)\n                    {\n                        current = value;\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the maximum value in the structure\n    /// </summary>\n    public static virtual A Max<A>(K<T, A> ta, A initialMax)\n        where A : IComparable<A> \n    {\n        var step    = T.FoldStep(ta, unit);\n        var current = initialMax;\n\n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return current;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (value.CompareTo(current) > 0)\n                    {\n                        current = value;\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the average of all the values in the structure\n    /// </summary>\n    public static virtual A Average<A>(K<T, A> ta)\n        where A : INumber<A>\n    {\n        var step  = T.FoldStep(ta, unit);\n        var taken = A.Zero;\n        var total = A.Zero;\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return taken == A.Zero\n                                ? A.Zero\n                                : total / taken;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    taken += A.One;\n                    total += value;\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the average of all the values in the structure\n    /// </summary>\n    public static virtual B Average<A, B>(Func<A, B> f, K<T, A> ta)\n        where B : INumber<B>\n    {\n        var step  = T.FoldStep(ta, unit);\n        var taken = B.Zero;\n        var total = B.Zero;\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return taken == B.Zero\n                               ? B.Zero\n                               : total / taken;\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    taken += B.One;\n                    total += f(value);\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Find the element at the specified index or `None` if out of range\n    /// </summary>\n    public static virtual Option<A> At<A>(K<T, A> ta, Index index)\n    {\n        var step = index.IsFromEnd\n                       ? T.FoldStepBack(ta, unit)\n                       : T.FoldStep(ta, unit);\n\n        var ix = 0;\n        \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return default;\n\n                case Fold<A, Unit>.Loop(_, var value, _) when ix == index.Value:\n                    return value;\n\n                case Fold<A, Unit>.Loop(_, _, var next):\n                    ix++;\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Partition a foldable into two sequences based on a predicate\n    /// </summary>\n    /// <param name=\"f\">Predicate function</param>\n    /// <param name=\"ta\">Foldable structure</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Partitioned structure</returns>\n    public static virtual (Seq<A> True, Seq<A> False) Partition<A>(Func<A, bool> f, K<T, A> ta)\n    {\n        var step   = T.FoldStep(ta, unit);\n        var @true  = Seq<A>();\n        var @false = Seq<A>();\n    \n        while (true)\n        {\n            switch (step)\n            {\n                case Fold<A, Unit>.Done(_):\n                    return (@true, @false);\n\n                case Fold<A, Unit>.Loop(_, var value, var next):\n                    if (f(value))\n                    {\n                        @true = @true.Add(value);\n                    }\n                    else\n                    {\n                        @false = @false.Add(value);\n                    }\n                    step = next(default);\n                    break;\n\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fraction/Fraction.Prelude.cs",
    "content": "﻿#nullable enable\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Trait\n{\n    /// <summary>\n    /// Generates a fractional value from an integer ratio.\n    /// </summary>\n    /// <param name=\"x\">The ratio to convert</param>\n    /// <returns>The equivalent of x in the implementing type.</returns>\n    [Pure]\n    public static A fromRational<FRACTION, A>(Ratio<int> x) where FRACTION : Fraction<A> =>\n        FRACTION.FromRational(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Fraction/Fraction.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Fractional number trait\n/// </summary>\n/// <typeparam name=\"A\">The type for which fractional \n/// operations are being defined.</typeparam>\n[Trait(\"Fraction*\")]\npublic interface Fraction<A> : Num<A>\n{\n    /// <summary>\n    /// Generates a fractional value from an integer ratio.\n    /// </summary>\n    /// <param name=\"x\">The ratio to convert</param>\n    /// <returns>The equivalent of x in the implementing type.</returns>\n    [Pure]\n    public static abstract A FromRational(Ratio<int> x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Extensions/Functor.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FunctorExtensions\n{\n    extension<E>(Guard<E, Unit> ma)\n    {\n        /// <summary>\n        /// Monad bind operation\n        /// </summary>\n        /// <param name=\"bind\">Monadic bind function</param>\n        /// <param name=\"project\">Projection function</param>\n        /// <typeparam name=\"F\">Functor trait</typeparam>\n        /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n        /// <typeparam name=\"C\">Target bound value type</typeparam>\n        /// <returns>M〈C〉</returns>\n        public K<F, C> SelectMany<F, B, C>(Func<Unit, K<F, B>> bind, Func<Unit, B, C> project)\n            where F : Functor<F>, Fallible<E, F> =>\n            ma switch\n            {\n                { Flag: true } => F.Map(b => project(default, b), bind(default)),\n                var guard      => F.Fail<C>(guard.OnFalse())\n            };\n    }\n\n    extension<E>(Guard<Fail<E>, Unit> ma)\n    {\n        /// <summary>\n        /// Monad bind operation\n        /// </summary>\n        /// <param name=\"bind\">Monadic bind function</param>\n        /// <param name=\"project\">Projection function</param>\n        /// <typeparam name=\"F\">Functor trait</typeparam>\n        /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n        /// <typeparam name=\"C\">Target bound value type</typeparam>\n        /// <returns>M〈C〉</returns>\n        public K<F, C> SelectMany<F, B, C>(Func<Unit, K<F, B>> bind, Func<Unit, B, C> project)\n            where F : Functor<F>, Fallible<E, F> =>\n            ma switch\n            {\n                { Flag: true } => F.Map(b => project(default, b), bind(default)),\n                var guard      => F.Fail<C>(guard.OnFalse().Value)\n            };\n    }\n\n    extension<Fnctr, A>(K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Ignores the bound value result and instead maps it to `Unit`\n        /// </summary>\n        /// <returns>Functor with unit bound value</returns>\n        public K<Fnctr, Unit> IgnoreF() =>\n            ma.Map(_ => default(Unit));\n        \n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <param name=\"f\">Mapping function</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, B> Map<B>(Func<A, B> f) =>\n            Fnctr.Map(f, ma);\n\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Invokes the functor, extracting its bound value, which it then ignores and\n        /// then maps to the default `value` provided.  This is useful for side-effecting\n        /// monads that have an effect on the world, which the result value can be ignored,\n        /// to then return a default.\n        /// </remarks>\n        /// <param name=\"value\">Ignore the bound value and map to this</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, B> ConstMap<B>(B value) =>\n            Fnctr.ConstMap(value, ma);\n\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <param name=\"f\">Mapping function</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, B> Select<B>(Func<A, B> f) =>\n            Fnctr.Map(f, ma);\n    }\n\n    extension<Fnctr, A, B>(Func<A, B> f) where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, B> Map(K<Fnctr, A> ma) =>\n            Fnctr.Map(f, ma);\n    }\n\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    extension<Fnctr, A, B, C>(Func<A, B, C> f) where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, C>> Map(K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n\n    extension<Fnctr, A, B, C, D>(Func<A, B, C, D> f) where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, Func<C, D>>> Map(K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n\n    extension<Fnctr, A, B, C, D, E>(Func<A, B, C, D, E> f) \n        where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, Func<C, Func<D, E>>>> Map(K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    extension<Fnctr, A, B, C, D, E, F>(Func<A, B, C, D, E, F> f) \n        where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, Func<C, Func<D, Func<E, F>>>>> Map(\n            K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n\n    extension<Fnctr, A, B, C, D, E, F, G>(Func<A, B, C, D, E, F, G> f) \n        where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> Map(\n            K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n\n    extension<Fnctr, A, B, C, D, E, F, G, H>(Func<A, B, C, D, E, F, G, H> f) \n        where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> Map(\n            K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n\n    extension<Fnctr, A, B, C, D, E, F, G, H, I>(Func<A, B, C, D, E, F, G, H, I> f) \n        where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> Map(\n            K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n\n    extension<Fnctr, A, B, C, D, E, F, G, H, I, J>(Func<A, B, C, D, E, F, G, H, I, J> f) \n        where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> Map(\n            K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n\n    extension<Fnctr, A, B, C, D, E, F, G, H, I, J, K>(Func<A, B, C, D, E, F, G, H, I, J, K> f) \n        where Fnctr : Functor<Fnctr>\n    {\n        /// <summary>\n        /// Functor map operation\n        /// </summary>\n        /// <remarks>\n        /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n        /// then takes the mapped value and wraps it back up into a new functor.\n        /// </remarks>\n        /// <remarks>\n        /// This variant takes the passed function and partially applies it, so the result is a\n        /// functor within the value being the partially applied function.  If `Fnctr` is also an\n        /// `Applicative`, which is often the case, you can provide further arguments to the\n        /// partially applied function by calling `.Apply()` on the resulting functor.\n        /// \n        /// You can continue this until all arguments have been provided and then you'll have\n        /// a functor within the result of the function wrapped up inside.\n        /// </remarks>\n        /// <param name=\"ma\">Functor to map</param>\n        /// <returns>Mapped functor</returns>\n        public K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> Map(\n            K<Fnctr, A> ma) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Extensions/Functor.ExtensionsT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FunctorExtensions\n{\n    /// <summary>\n    /// Runs a functor map operation on the nested functors \n    /// </summary>\n    /// <remarks>\n    /// If you're working with an inner functor that is concrete then you will first need to\n    /// call `KindT` to cast the functor to a more general `K` version.  This enables the\n    /// `T` variant extensions (like `BindT`, `MapT, etc.) to work without providing\n    /// excessive generic arguments all the way down the chain.\n    /// </remarks>\n    /// <example>\n    ///\n    ///    var mx = Seq〈Option〈int〉〉(Some(1), Some(2), Some(3));\n    ///    var ma = mx.MapT(a => a + 1);\n    ///\n    /// </example>\n    /// <param name=\"mna\">Nested functor value</param>\n    /// <param name=\"f\">Bind function</param>\n    /// <typeparam name=\"NA\">`N〈A〉`</typeparam>\n    /// <typeparam name=\"M\">Outer functor trait</typeparam>\n    /// <typeparam name=\"N\">Inner functor trait</typeparam>\n    /// <typeparam name=\"A\">Input bound value</typeparam>\n    /// <typeparam name=\"B\">Output bound value</typeparam>\n    /// <returns>Mapped value</returns>\n    public static K<M, K<N, B>> MapT<M, N, A, B>(this K<M, K<N, A>> mna, Func<A, B> f)\n        where M : Functor<M>\n        where N : Functor<N> =>\n        M.Map(na => N.Map(f, na), mna);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Extensions/Functor.MemoExtensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FunctorExtensions\n{\n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, B> Map<B>(Func<A, B> f) =>\n            FF.Map(f, self);\n    }\n\n    extension<FF, A, B>(Func<A, B> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, B> Map(Memo<FF, A> fa) =>\n            FF.Map(self, fa);\n    }\n\n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, C>> Map<B, C>(Func<A, B, C> f) =>\n            FF.Map(curry(f), self);\n    }\n\n    extension<FF, A, B, C>(Func<A, B, C> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, C>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }\n    \n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, D>>> Map<B, C, D>(Func<A, B, C, D> f) =>\n            FF.Map(curry(f), self);\n    }\n    \n    extension<FF, A, B, C, D>(Func<A, B, C, D> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, D>>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }\n    \n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, E>>>> Map<B, C, D, E>(Func<A, B, C, D, E> f) =>\n            FF.Map(curry(f), self);\n    }\n    \n    extension<FF, A, B, C, D, E>(Func<A, B, C, D, E> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, E>>>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }\n    \n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, F>>>>> Map<B, C, D, E, F>(Func<A, B, C, D, E, F> f) =>\n            FF.Map(curry(f), self);\n    }\n    \n    extension<FF, A, B, C, D, E, F>(Func<A, B, C, D, E, F> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, F>>>>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }\n    \n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> Map<B, C, D, E, F, G>(Func<A, B, C, D, E, F, G> f) =>\n            FF.Map(curry(f), self);\n    }\n    \n    extension<FF, A, B, C, D, E, F, G>(Func<A, B, C, D, E, F, G> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }\n    \n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> Map<B, C, D, E, F, G, H>(Func<A, B, C, D, E, F, G, H> f) =>\n            FF.Map(curry(f), self);\n    }\n    \n    extension<FF, A, B, C, D, E, F, G, H>(Func<A, B, C, D, E, F, G, H> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }\n    \n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> Map<B, C, D, E, F, G, H, I>(Func<A, B, C, D, E, F, G, H, I> f) =>\n            FF.Map(curry(f), self);\n    }\n    \n    extension<FF, A, B, C, D, E, F, G, H, I>(Func<A, B, C, D, E, F, G, H, I> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }\n    \n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> Map<B, C, D, E, F, G, H, I, J>(Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            FF.Map(curry(f), self);\n    }\n    \n    extension<FF, A, B, C, D, E, F, G, H, I, J>(Func<A, B, C, D, E, F, G, H, I, J> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }    \n        \n    extension<FF, A>(Memo<FF, A> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> Map<B, C, D, E, F, G, H, I, J, K>(Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            FF.Map(curry(f), self);\n    }\n    \n    extension<FF, A, B, C, D, E, F, G, H, I, J, K>(Func<A, B, C, D, E, F, G, H, I, J, K> self)\n        where FF : Functor<FF>\n    {\n        public K<FF, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> Map(Memo<FF, A> fa) =>\n            FF.Map(curry(self), fa);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Functor.Laws.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functions that test that functor-laws hold for the `F` functor provided.\n/// </summary>\n/// <remarks>\n/// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n/// can be proven to be true.  If your functor doesn't have `Equals` then you must provide\n/// the optional `equals` parameter so that the equality of outcomes can be tested.\n/// </remarks>\n/// <typeparam name=\"F\">Functor type</typeparam>\npublic static class FunctorLaw<F>\n    where F : Functor<F>\n{\n    /// <summary>\n    /// Assert that the functor laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Unit assert(K<F, int> fa, Func<K<F, int>, K<F, int>, bool>? equals = null) =>\n        validate(fa, equals)\n           .IfFail(errors => errors.Throw());\n\n    /// <summary>\n    /// Validate that the functor laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> validate(K<F, int> fa, Func<K<F, int>, K<F, int>, bool>? equals = null)\n    {\n        equals ??= (fa, fb) => fa.Equals(fb);\n        return identityLaw(fa, equals) >> \n               compositionLaw(fa, f, g, equals);\n    }\n\n    /// <summary>\n    /// Validate the identity law\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> identityLaw(K<F, int> lhs, Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var rhs = lhs.Map(identity);\n        return equals(lhs, rhs) \n                   ? unit\n                   : Error.New($\"Functor identity-law does not hold for {typeof(F).Name}\");\n    }\n\n    /// <summary>\n    /// Validate the composition law\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your functor doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> compositionLaw(\n        K<F, int> fa, \n        Func<int, int> f,\n        Func<int, int> g, \n        Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var lhs = fa.Map(a => g(f(a)));\n        var rhs = fa.Map(f).Map(g);\n        return equals(lhs, rhs)\n                   ? unit\n                   : Error.New($\"Functor composition-law does not hold for {typeof(F).Name}\");\n    }\n    \n    static int f(int x) =>\n        x + 1;\n    \n    static int g(int x) =>\n        x * 2;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Functor.Module.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functor module\n/// </summary>\npublic static class Functor\n{\n    /// <summary>\n    /// Functor map.  Maps all contained values of `A` to values of `B`\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <param name=\"fa\">Functor structure</param>\n    /// <typeparam name=\"F\">Functor trait</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"B\">Resulting bound value type</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<F, B> map<F, A, B>(Func<A, B> f, K<F, A> fa) \n        where F : Functor<F> =>\n        F.Map(f, fa);\n    \n    /// <summary>\n    /// Ignores the bound value result and instead maps it to `Unit`\n    /// </summary>\n    /// <param name=\"fa\">Functor that returns a bound value that should be ignored</param>\n    /// <typeparam name=\"F\">Functor trait</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Functor with unit bound value</returns>\n    public static K<F, Unit> ignore<F, A>(K<F, A> fa)\n        where F : Functor<F> =>\n        fa.Map(_ => default(Unit));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Functor.Trait.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functor trait\n/// </summary>\n/// <remarks>\n/// `Map` is used to apply a function of type `Func〈A, B〉` to a value of type `K〈F, A〉`\n/// where `F` is a functor, to produce a value of type `K〈F, B〉`.\n///\n/// Note that for any type with more than one parameter (e.g., `Either`), only the\n/// last type parameter can be modified with `Map` (e.g. `R` in `Either〈L, R〉`).\n/// \n/// Some types two generic parameters or more have a `Bifunctor` instance that allows both\n/// the last and the penultimate parameters to be mapped over.\n/// </remarks>\n/// <typeparam name=\"F\">Self referring type</typeparam>\npublic interface Functor<F>  \n    where F : Functor<F>\n{\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"f\">Mapping function</param>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static abstract K<F, B> Map<A, B>(Func<A, B> f, K<F, A> ma);\n\n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"f\">Mapping function</param>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static virtual K<F, B> Map<A, B>(Func<A, B> f, Memo<F, A> ma) =>\n        ma.Value.Map(f);\n    \n    /// <summary>\n    /// Functor map operation with a constant value\n    /// </summary>\n    /// <param name=\"constantValue\">Constant value used to override each bound value in the structure</param>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static virtual K<F, A> ConstMap<A, B>(A constantValue, K<F, B> ma) =>\n        ma.Map(_ => constantValue);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Operators/Functor.MemoOperators.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FunctorExtensions\n{\n    extension<M, A, B>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, B> operator * (Func<A, B> f, Memo<M, A> ma) =>\n            M.Map(f, ma);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, B> operator * (Memo<M, A> ma, Func<A, B> f) =>\n            M.Map(f, ma);\n    }\n    \n    extension<M, A, B, C>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<M, A, B, C, D>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H, I, J>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(Memo<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            Memo<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Memo<M, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Operators/Functor.Operators.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class FunctorExtensions\n{\n    extension<M, A, B>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, B> operator * (Func<A, B> f, K<M, A> ma) =>\n            M.Map(f, ma);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, B> operator * (Pure<B> pb, K<M, A> ma) =>\n            M.ConstMap(pb.Value, ma);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, B> operator * (K<M, A> ma, Func<A, B> f) =>\n            M.Map(f, ma);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, B> operator * (K<M, A> ma, Pure<B> pb) =>\n            M.ConstMap(pb.Value, ma);\n    }\n    \n    extension<M, A, B, C>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, C>> operator * (\n            K<M, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, D>>> operator * (\n            K<M, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<M, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<M, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<M, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<M, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<M, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<M, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<M, A> self)\n        where M : Functor<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<M, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static K<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<M, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Functor/Prelude/Functor.Prelude.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Ignores the bound value result and instead maps it to `Unit`\n    /// </summary>\n    /// <param name=\"fa\">Functor that returns a bound value that should be ignored</param>\n    /// <typeparam name=\"F\">Functor trait</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Functor with unit bound value</returns>\n    public static K<F, Unit> ignore<F, A>(K<F, A> fa)\n        where F : Functor<F> =>\n        map(_ => default(Unit), fa);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, B> map<Fnctr, A, B>(\n        Func<A, B> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(f, ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, C>> map<Fnctr, A, B, C>(\n        Func<A, B, C> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, D>>> map<Fnctr, A, B, C, D>(\n        Func<A, B, C, D> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, E>>>> map<Fnctr, A, B, C, D, E>(\n        Func<A, B, C, D, E> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, F>>>>> map<Fnctr, A, B, C, D, E, F>(\n        Func<A, B, C, D, E, F> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> map<Fnctr, A, B, C, D, E, F, G>(\n        Func<A, B, C, D, E, F, G> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> map<Fnctr, A, B, C, D, E, F, G, H>(\n        Func<A, B, C, D, E, F, G, H> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> map<Fnctr, A, B, C, D, E, F, G, H, I>(\n        Func<A, B, C, D, E, F, G, H, I> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> map<Fnctr, A, B, C, D, E, F, G, H, I, J>(\n        Func<A, B, C, D, E, F, G, H, I, J> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> map<Fnctr, A, B, C, D, E, F, G, H, I, J, K>(\n        Func<A, B, C, D, E, F, G, H, I, J, K> f, K<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);    \n    \n    \n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, B> map<Fnctr, A, B>(\n        Func<A, B> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(f, ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, C>> map<Fnctr, A, B, C>(\n        Func<A, B, C> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, D>>> map<Fnctr, A, B, C, D>(\n        Func<A, B, C, D> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, E>>>> map<Fnctr, A, B, C, D, E>(\n        Func<A, B, C, D, E> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, F>>>>> map<Fnctr, A, B, C, D, E, F>(\n        Func<A, B, C, D, E, F> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> map<Fnctr, A, B, C, D, E, F, G>(\n        Func<A, B, C, D, E, F, G> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> map<Fnctr, A, B, C, D, E, F, G, H>(\n        Func<A, B, C, D, E, F, G, H> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> map<Fnctr, A, B, C, D, E, F, G, H, I>(\n        Func<A, B, C, D, E, F, G, H, I> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> map<Fnctr, A, B, C, D, E, F, G, H, I, J>(\n        Func<A, B, C, D, E, F, G, H, I, J> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);\n    \n    /// <summary>\n    /// Functor map operation\n    /// </summary>\n    /// <remarks>\n    /// Unwraps the value within the functor, passes it to the map function `f` provided, and\n    /// then takes the mapped value and wraps it back up into a new functor.\n    /// </remarks>\n    /// <remarks>\n    /// This variant takes the passed function and partially applies it, so the result is a\n    /// functor within the value being the partially applied function.  If `Fnctr` is also an\n    /// `Applicative`, which is often the case, you can provide further arguments to the\n    /// partially applied function by calling `.Apply()` on the resulting functor.\n    ///\n    /// You can continue this until all arguments have been provided and then you'll have\n    /// a functor within the result of the function wrapped up inside.\n    /// </remarks>\n    /// <param name=\"ma\">Functor to map</param>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"Fnctr\">Trait of the functor</typeparam>\n    /// <returns>Mapped functor</returns>\n    public static K<Fnctr, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> map<Fnctr, A, B, C, D, E, F, G, H, I, J, K>(\n        Func<A, B, C, D, E, F, G, H, I, J, K> f, Memo<Fnctr, A> ma) \n        where Fnctr : Functor<Fnctr> =>\n        Fnctr.Map(x => curry(f)(x), ma);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Has/Has.Trait.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Makes a value accessible via a property.  This allows for _structural property access_. \n/// </summary>\n/// <typeparam name=\"M\">Higher-kind that supports access to the trait</typeparam>\n/// <typeparam name=\"VALUE\">Type to return as the bound-value</typeparam>\npublic interface Has<in M, VALUE>\n{\n    public static abstract K<M, VALUE> Ask { get; }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Has/Has.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Strongly typed way of accessing a `Has` trait interface from an environment\n/// </summary>\n/// <remarks>\n/// When using multiple `Has` traits, the accessor (`Env.Trait`) will cause ambiguity errors.\n/// This type resolves that by forcing qualification via the type parameters.  It also has\n/// the benefit that we cache the trait interface in a readonly static, saving on allocations. \n/// </remarks>\n/// <typeparam name=\"M\">Higher-kind</typeparam>\n/// <typeparam name=\"Env\">The environment type from which to get the trait-interface value</typeparam>\n/// <typeparam name=\"VALUE\">Trait interface type</typeparam>\npublic static class Has<M, Env, VALUE>\n    where Env : Has<M, VALUE>\n{\n    /// <summary>\n    /// Cached trait interface accessor\n    /// </summary>\n    public static readonly K<M, VALUE> ask =\n        Env.Ask;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Hashable/Hashable.Module.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic static class Hashable\n{\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static int code<A>(A x) where A : Hashable<A> =>\n        A.GetHashCode(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Hashable/Hashable.Trait.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Hashable trait\n/// </summary>\n/// <typeparam name=\"A\">\n/// The type for which GetHashCode is defined\n/// </typeparam>\n[Trait(\"Hashable*\")]\npublic interface Hashable<in A>\n{\n    /// <summary>\n    /// Get the hash-code of the provided value\n    /// </summary>\n    /// <returns>Hash code of x</returns>\n    [Pure]\n    public static abstract int GetHashCode(A x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Identifiable/Identifiable.Module.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Identifiable module\n/// </summary>\npublic static class Identifiable\n{\n    /// <summary>\n    /// Identify the structure\n    /// </summary>\n    /// <param name=\"fa\">Structure to label</param>\n    /// <param name=\"label\">Label to apply</param>\n    /// <typeparam name=\"F\">Structure</typeparam>\n    /// <typeparam name=\"L\">Identifier type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Identified structure</returns>\n    public static K<F, A> identify<F, L, A>(K<F, A> fa, L label) \n        where F : Identifiable<F, L> =>\n        F.Identify(fa, new Label<L>(label));\n    \n    /// <summary>\n    /// Identify the structure\n    /// </summary>\n    /// <param name=\"fa\">Structure to label</param>\n    /// <param name=\"label\">Label to apply</param>\n    /// <typeparam name=\"F\">Structure</typeparam>\n    /// <typeparam name=\"L\">Identifier type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Identified structure</returns>\n    public static K<F, A> identify<F, L, A>(K<F, A> fa, Label<L> label) \n        where F : Identifiable<F, L> =>\n        F.Identify(fa, label);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Identifiable/Identifiable.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Identifiable module\n/// </summary>\npublic static partial class IdentifiableExtensions\n{\n    /// <typeparam name=\"F\">Structure</typeparam>\n    /// <typeparam name=\"L\">Identifier type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    extension<F, L, A>(K<F, A> self)\n        where F : Identifiable<F, L>\n    {\n        /// <summary>\n        /// Identify the structure\n        /// </summary>\n        /// <param name=\"fa\">Structure to label</param>\n        /// <param name=\"label\">Label to apply</param>\n        /// <returns>Identified structure</returns>\n        public static K<F, A> operator |(K<F, A> fa, Label<L> label) =>\n            F.Identify(fa, label);        \n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Identifiable/Identifiable.Prelude.cs",
    "content": "namespace LanguageExt;\n\n/// <summary>\n/// Identifiable module\n/// </summary>\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Construct a label\n    /// </summary>\n    /// <param name=\"value\">Label value</param>\n    /// <typeparam name=\"L\">Label value-type</typeparam>\n    /// <returns></returns>\n    public static Label<L> label<L>(L value) => \n        new(value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Identifiable/Identifiable.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Identifiable structure\n/// </summary>\n/// <typeparam name=\"F\">Structure</typeparam>\n/// <typeparam name=\"L\">Identifier type</typeparam>\npublic interface Identifiable<F, L>\n    where F : Identifiable<F, L>\n{\n    /// <summary>\n    /// Identify the structure\n    /// </summary>\n    /// <param name=\"fa\">Structure to label</param>\n    /// <param name=\"label\">Label to apply</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Identified structure</returns>\n    public static abstract K<F, A> Identify<A>(K<F, A> fa, Label<L> label);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Identifiable/Label.cs",
    "content": "namespace LanguageExt;\n\n/// <summary>\n/// Label to be used with Identifiable structures\n/// </summary>\n/// <param name=\"Value\">Label value</param>\n/// <typeparam name=\"L\">Label type</typeparam>\npublic readonly record struct Label<L>(L Value);\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Indexable/Indexable.cs",
    "content": "﻿namespace LanguageExt.Traits;\n\npublic interface Indexable<in A, in KEY, VALUE>\n{\n    public static abstract Option<VALUE> TryGet(A ma, KEY key);\n    public static abstract VALUE Get(A ma, KEY key);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/K.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class KExtensions\n{\n    /// <summary>\n    /// Get the base kind type.  Avoids casts mid-expression\n    /// </summary>\n    public static K<F, A> Kind<F, A>(this K<F, A> fa) =>\n        fa;\n    \n    /// <summary>\n    /// Get the base kind type.  Avoids casts mid-expression\n    /// </summary>\n    public static K<F, A, B> Kind2<F, A, B>(this K<F, A, B> fab) =>\n        fab;\n    \n    public static FA SafeCast<FA, F, A>(this K<F, A> fa)\n        where FA : K<F, A>\n        where F : Functor<F>\n    {\n        try\n        {\n            return (FA)fa;\n        }\n        catch(InvalidCastException)\n        {\n            return (FA)F.Map(x => (A)x, fa);\n        }\n    }\n    \n    /// <summary>\n    /// `KindT` converts a nested Kind type (inherits `K〈M, A〉`), where the inner\n    /// type is a concrete type and not `K〈N, A〉` to the more general version - which\n    /// allows the other `T` variant methods to work seamlessly.\n    /// </summary>\n    /// <remarks>\n    /// The casting of nested types is especially problematic for C#'s type-system, \n    /// so even though this isn't ideal, it does allow for a truly generic system\n    /// of working with any nested types as long as there's a `Functor` implementation\n    /// for the outer type.\n    /// </remarks>\n    /// <example>\n    ///\n    ///     var mx = Seq〈Option〈int〉〉(Some(1), Some(2), Some(3));\n    ///         \n    ///     var ma = mx.KindT〈Seq, Option, Option〈int〉, int〉()\n    ///                .BindT(a => Some(a + 1))\n    ///                .MapT(a => a + 1);\n    ///                .AsT〈Seq, Option, Option〈int〉, int〉();\n    ///\n    /// </example>\n    /// <param name=\"mna\">Nested functor value</param>\n    /// <typeparam name=\"M\">Outer functor trait (i.e. `Seq`)</typeparam>\n    /// <typeparam name=\"N\">Inner trait (i.e. `Option`)</typeparam>\n    /// <typeparam name=\"NA\">Concrete nested type (i.e. `Option〈int〉`)</typeparam>\n    /// <typeparam name=\"A\">Concrete bound value type (i.e. `int`)</typeparam>\n    /// <returns>More general version of the type that can be used with other `T` extensions, like `BindT`</returns>\n    public static K<M, K<N, A>> KindT<M, N, NA, A>(this K<M, NA> mna)\n        where NA : K<N, A>\n        where M : Functor<M> =>\n        M.Map(na => (K<N, A>)na, mna);\n\n    /// <summary>\n    /// `AsT` converts a nested Kind type (inherits `K〈M, A〉`), where the inner type\n    /// is a general type (`K〈N, A〉`) to its downcast concrete version.\n    /// </summary>\n    /// <remarks>\n    /// The casting of nested types is especially problematic for C#'s type-system, \n    /// so even though this isn't ideal, it does allow for a truly generic system\n    /// of working with any nested types as long as there's a `Functor` implementation\n    /// for the outer type.\n    /// </remarks>\n    /// <example>\n    ///\n    ///     var mx = Seq〈Option〈int〉〉(Some(1), Some(2), Some(3));\n    ///         \n    ///     var ma = mx.KindT〈Seq, Option, Option〈int〉, int〉()\n    ///                .BindT(a => Some(a + 1))\n    ///                .MapT(a => a + 1);\n    ///                .AsT〈Seq, Option, Option〈int〉, int〉();\n    ///\n    /// </example>\n    /// <param name=\"mna\">Nested functor value</param>\n    /// <typeparam name=\"M\">Outer functor trait (i.e. `Seq`)</typeparam>\n    /// <typeparam name=\"N\">Inner trait (i.e. `Option`)</typeparam>\n    /// <typeparam name=\"NA\">Concrete nested type (i.e. `Option〈int〉`)</typeparam>\n    /// <typeparam name=\"A\">Concrete nested-monad bound value type (i.e. `int`)</typeparam>\n    /// <returns>Concrete version of the general type.</returns>\n    public static K<M, NA> AsT<M, N, NA, A>(this K<M, K<N, A>> mna)\n        where NA : K<N, A>\n        where M : Functor<M> =>\n        M.Map(na => (NA)na, mna);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/K.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Arrow kind: `* -〉*` used to represent higher-kinded types.\n/// </summary>\n/// <remarks>\n/// `K〈F, A〉` should be thought of as `F〈A〉` (where both `F` an `A` are parametric).  It currently\n/// can't be represented in C#, so this allows us to define higher-kinded types and pass them\n/// around.  We can then build traits that expected a `K` where the trait is tied to the `F`.\n///\n/// For example:\n///\n///     K〈F, A〉 where F : Functor〈F〉\n///     K〈M, A〉 where M : Monad〈M〉\n///\n/// That means we can write generic functions that work with monads, functors, etc.\n/// </remarks>\n/// <typeparam name=\"F\">Trait type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic interface K<in F, A>;\n\n/// <summary>\n/// Arrow kind: `* -〉* -〉*` used to represent higher-kinded types.\n/// </summary>\n/// <typeparam name=\"F\">Trait type</typeparam>\n/// <typeparam name=\"A\">Alternative value type</typeparam>\n/// <typeparam name=\"B\">Bound value type</typeparam>\npublic interface K<in F, A, B>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Local/Local.Module.cs",
    "content": "using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\npublic static class Local\n{\n    public static K<M, A> with<M, Env, InnerEnv, A>(Func<InnerEnv, InnerEnv> f, K<M, A> ma)\n        where Env : Local<M, InnerEnv> =>\n        Env.With(f, ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Local/Local.Trait.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Creates a local environment to run a computation \n/// </summary>\n/// <typeparam name=\"M\">Structure trait</typeparam>\n/// <typeparam name=\"InnerEnv\">The value extracted from an environment</typeparam>\npublic interface Local<M, InnerEnv> : Has<M, InnerEnv>\n{\n    public static abstract K<M, A> With<A>(Func<InnerEnv, InnerEnv> f, K<M, A> ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Maybe Traits/MonadIO/MonadIO.Trait.cs",
    "content": "using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Maybe\n{\n    /// <summary>\n    /// Monad that is either the IO monad or a transformer with the IO monad in its stack\n    /// </summary>\n    /// <typeparam name=\"M\">Self-referring trait</typeparam>\n    public interface MonadIO<M>\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Lifts the IO monad into a monad transformer stack.  \n        /// </summary>\n        /// <param name=\"ma\">IO computation to lift</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>The outer monad with the IO monad lifted into it</returns>\n        public static virtual K<M, A> LiftIOMaybe<A>(K<IO, A> ma) =>\n            M.LiftIOMaybe(ma.As());\n\n        /// <summary>\n        /// Lifts the IO monad into a monad transformer stack.  \n        /// </summary>\n        /// <remarks>\n        /// IMPLEMENTATION REQUIRED: If this method isn't overloaded in this monad\n        /// or any monad in the stack on the way to the inner-monad, then it will throw\n        /// an exception.\n        ///\n        /// This isn't ideal, it appears to be the only way to achieve this\n        /// kind of functionality in C# without resorting to magic. \n        /// </remarks>\n        /// <param name=\"ma\">IO computation to lift</param>\n        /// <typeparam name=\"A\">Bound value type</typeparam>\n        /// <returns>The outer monad with the IO monad lifted into it</returns>\n        /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n        /// the inner monad or any monad in the stack on the way to the inner-monad,\n        /// then it will throw an exception.</exception>\n        public static virtual K<M, A> LiftIOMaybe<A>(IO<A> ma) =>\n            throw new ExceptionalException(Errors.LiftIONotSupported);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Maybe Traits/MonadUnliftIO/MonadUnliftIO.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class MaybeMonadUnliftIOExtensions\n{\n    /// <summary>\n    /// Convert an action in `ma`to an action in `IO`.\n    /// </summary>\n    public static K<M, IO<A>> ToIO<M, A>(this K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        M.ToIOMaybe(ma);\n\n    /// <summary>\n    /// Convert an action in `ma`to an action in `IO`.\n    /// </summary>\n    public static K<M, B> MapIO<M, A, B>(this K<M, A> ma, Func<IO<A>, IO<B>> f)\n        where M : MonadUnliftIO<M> =>\n        M.MapIOMaybe(ma, f);\n\n    /// <summary>\n    /// Map the underlying IO monad\n    /// </summary>\n    public static K<M, B> MapIO<M, A, B>(this Func<IO<A>, IO<B>> f, K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        M.MapIOMaybe(ma, f);\n    \n    /// <summary>\n    /// Convert an action in `ma`to an action in `IO`.\n    /// </summary>\n    public static K<M, IO<A>> ToIOMaybe<M, A>(this K<M, A> ma)\n        where M : MonadIO<M> =>\n        M.ToIOMaybe(ma);\n\n    /// <summary>\n    /// Convert an action in `ma`to an action in `IO`.\n    /// </summary>\n    public static K<M, B> MapIOMaybe<M, A, B>(this K<M, A> ma, Func<IO<A>, IO<B>> f)\n        where M : MonadIO<M> =>\n        M.MapIOMaybe(ma, f);\n\n    /// <summary>\n    /// Map the underlying IO monad\n    /// </summary>\n    public static K<M, B> MapIOMaybe<M, A, B>(this Func<IO<A>, IO<B>> f, K<M, A> ma)\n        where M : MonadIO<M> =>\n        M.MapIOMaybe(ma, f);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Maybe Traits/MonadUnliftIO/MonadUnliftIO.Trait.cs",
    "content": "using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Maybe\n{\n    /// <summary>\n    /// Monad that is either the IO monad or a transformer with the IO monad in its stack\n    /// </summary>\n    /// <typeparam name=\"M\">Self-referring trait</typeparam>\n    public interface MonadUnliftIO<M> : Maybe.MonadIO<M>\n        where M : MonadUnliftIO<M>, Traits.Monad<M>\n    {\n        /// <summary>\n        /// Extract the IO monad from within the M monad (usually as part of a monad-transformer stack).\n        /// </summary>\n        /// <remarks>\n        /// IMPLEMENTATION REQUIRED: If this method isn't overloaded in this monad\n        /// or any monad in the stack on the way to the inner-monad, then it will throw\n        /// an exception.\n        ///\n        /// This isn't ideal, it appears to be the only way to achieve this\n        /// kind of functionality in C# without resorting to magic. \n        /// </remarks>\n        /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n        /// the inner monad or any monad in the stack on the way to the inner-monad,\n        /// then it will throw an exception.</exception>\n        public static virtual K<M, IO<A>> ToIOMaybe<A>(K<M, A> ma) =>\n            throw new ExceptionalException(Errors.ToIONotSupported);\n\n        /// <summary>\n        /// Extract the IO monad from within the `M` monad (usually as part of a monad-transformer stack).  Then perform\n        /// a mapping operation on the IO action before lifting the IO back into the `M` monad.\n        /// </summary>\n        public static virtual K<M, B> MapIOMaybe<A, B>(K<M, A> ma, Func<IO<A>, IO<B>> f) =>\n            M.ToIOMaybe(ma).Bind(io => M.LiftIOMaybe(f(io)));\n\n        /// <summary>\n        /// Queue this IO operation to run on the thread-pool. \n        /// </summary>\n        /// <param name=\"timeout\">Maximum time that the forked IO operation can run for. `None` for no timeout.</param>\n        /// <returns>Returns a `ForkIO` data-structure that contains two IO effects that can be used to either cancel\n        /// the forked IO operation or to await the result of it.\n        /// </returns>\n        public static virtual K<M, ForkIO<A>> ForkIOMaybe<A>(K<M, A> ma, Option<TimeSpan> timeout = default) =>\n            M.MapIOMaybe(ma, io => io.Fork(timeout));\n\n        /// <summary>\n        /// Await a forked operation\n        /// </summary>\n        public static virtual K<M, A> AwaitMaybe<A>(K<M, ForkIO<A>> ma) =>\n            M.MapIOMaybe(ma, io => io.Bind(f => f.Await));\n\n        /// <summary>\n        /// Creates a local cancellation environment\n        /// </summary>\n        /// <remarks>\n        /// A local cancellation environment stops other IO computations, that rely on the same\n        /// environmental cancellation token, from being taken down by a regional cancellation.\n        ///\n        /// If an `IO.cancel` is invoked locally, then it will still create an exception that\n        /// propagates upwards and so catching cancellations is still important. \n        /// </remarks>\n        /// <param name=\"ma\">Computation to run within the local context</param>\n        /// <typeparam name=\"A\">Bound value</typeparam>\n        /// <returns>Result of the computation</returns>\n        public static virtual K<M, A> LocalIOMaybe<A>(K<M, A> ma) =>\n            M.MapIOMaybe(ma, io => io.Local());\n\n        /// <summary>\n        /// Make this IO computation run on the `SynchronizationContext` that was captured at the start\n        /// of the IO chain (i.e. the one embedded within the `EnvIO` environment that is passed through\n        /// all IO computations)\n        /// </summary>\n        public static virtual K<M, A> PostIOMaybe<A>(K<M, A> ma) =>\n            M.MapIOMaybe(ma, io => io.Post());\n\n        /// <summary>\n        /// Timeout operation if it takes too long\n        /// </summary>\n        public static virtual K<M, A> TimeoutIOMaybe<A>(K<M, A> ma, TimeSpan timeout) =>\n            M.MapIOMaybe(ma, io => io.Timeout(timeout));\n\n        /// <summary>\n        /// The IO monad tracks resources automatically; this creates a local resource environment\n        /// to run this computation in.  Once the computation is completed, any resources acquired\n        /// are automatically released.  Imagine this as the ultimate `using` statement.\n        /// </summary>\n        public static virtual K<M, A> BracketIOMaybe<A>(K<M, A> ma) =>\n            M.MapIOMaybe(ma, io => io.Bracket());\n\n        /// <summary>\n        /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n        /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n        /// in between.\n        /// </summary>\n        /// <param name=\"Acq\">Resource acquisition</param>\n        /// <param name=\"Use\">Function to use the acquired resource</param>\n        /// <param name=\"Fin\">Function to invoke to release the resource</param>\n        public static virtual K<M, C> BracketIOMaybe<A, B, C>(\n            K<M, A> Acq,\n            Func<A, IO<C>> Use,\n            Func<A, IO<B>> Fin) =>\n            M.MapIOMaybe(Acq, io => io.Bracket(Use, Fin));\n\n        /// <summary>\n        /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n        /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n        /// in between.\n        /// </summary>\n        /// <param name=\"Acq\">Resource acquisition</param>\n        /// <param name=\"Use\">Function to use the acquired resource</param>\n        /// <param name=\"Catch\">Function to run to handle any exceptions</param>\n        /// <param name=\"Fin\">Function to invoke to release the resource</param>\n        public static virtual K<M, C> BracketIOMaybe<A, B, C>(\n            K<M, A> Acq,\n            Func<A, IO<C>> Use,\n            Func<Error, IO<C>> Catch,\n            Func<A, IO<B>> Fin) =>\n            M.MapIOMaybe(Acq, io => io.Bracket(Use, Catch, Fin));\n\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n        //\n        //  Repeating the effect\n        //\n\n        /// <summary>\n        /// Keeps repeating the computation forever, or until an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <returns>The result of the last invocation</returns>\n        public static virtual K<M, A> RepeatIOMaybe<A>(K<M, A> ma) =>\n            M.MapIOMaybe(ma, io => io.Repeat());\n\n        /// <summary>\n        /// Keeps repeating the computation until the scheduler expires, or an error occurs  \n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <returns>The result of the last invocation</returns>\n        public static virtual K<M, A> RepeatIOMaybe<A>(\n            K<M, A> ma,\n            Schedule schedule) =>\n            M.MapIOMaybe(ma, io => io.Repeat(schedule));\n\n        /// <summary>\n        /// Keeps repeating the computation until the predicate returns false, or an error occurs \n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        public static virtual K<M, A> RepeatWhileIOMaybe<A>(\n            K<M, A> ma,\n            Func<A, bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.RepeatWhile(predicate));\n\n        /// <summary>\n        /// Keeps repeating the computation, until the scheduler expires, or the predicate returns false, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        public static virtual K<M, A> RepeatWhileIOMaybe<A>(\n            K<M, A> ma,\n            Schedule schedule,\n            Func<A, bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.RepeatWhile(schedule, predicate));\n\n        /// <summary>\n        /// Keeps repeating the computation until the predicate returns true, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        public static virtual K<M, A> RepeatUntilIOMaybe<A>(\n            K<M, A> ma,\n            Func<A, bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.RepeatUntil(predicate));\n\n        /// <summary>\n        /// Keeps repeating the computation until the scheduler expires, or the predicate returns true, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        public static virtual K<M, A> RepeatUntilIOMaybe<A>(\n            K<M, A> ma,\n            Schedule schedule,\n            Func<A, bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.RepeatUntil(schedule, predicate));\n\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n        //\n        //  Retrying the effect when it fails\n        //\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will retry forever\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public static virtual K<M, A> RetryIOMaybe<A>(K<M, A> ma) =>\n            M.MapIOMaybe(ma, io => io.Retry());\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will retry until the schedule expires\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public static virtual K<M, A> RetryIOMaybe<A>(\n            K<M, A> ma,\n            Schedule schedule) =>\n            M.MapIOMaybe(ma, io => io.Retry(schedule));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n        /// at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public static virtual K<M, A> RetryWhileIOMaybe<A>(\n            K<M, A> ma,\n            Func<Error, bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.RetryWhile(predicate));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n        /// or, until the schedule expires; at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public static virtual K<M, A> RetryWhileIOMaybe<A>(\n            K<M, A> ma,\n            Schedule schedule,\n            Func<Error, bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.RetryWhile(schedule, predicate));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n        /// at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public static virtual K<M, A> RetryUntilIOMaybe<A>(\n            K<M, A> ma,\n            Func<Error, bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.RetryUntil(predicate));\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n        /// or, until the schedule expires; at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public static virtual K<M, A> RetryUntilIOMaybe<A>(\n            K<M, A> ma,\n            Schedule schedule,\n            Func<Error, bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.RetryUntil(schedule, predicate));\n\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n        // \n        //  Folding\n        //\n\n        public static virtual K<M, S> FoldIOMaybe<S, A>(\n            K<M, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder) =>\n            M.MapIOMaybe(ma, io => io.Fold(schedule, initialState, folder));\n\n        public static virtual K<M, S> FoldIOMaybe<S, A>(\n            K<M, A> ma,\n            S initialState,\n            Func<S, A, S> folder) =>\n            M.MapIOMaybe(ma, io => io.Fold(initialState, folder));\n\n        public static virtual K<M, S> FoldWhileIOMaybe<S, A>(\n            K<M, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<S, bool> stateIs) =>\n            M.MapIOMaybe(ma, io => io.FoldWhile(schedule, initialState, folder, stateIs));\n\n        public static virtual K<M, S> FoldWhileIOMaybe<S, A>(\n            K<M, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<S, bool> stateIs) =>\n            M.MapIOMaybe(ma, io => io.FoldWhile(initialState, folder, stateIs));\n\n        public static virtual K<M, S> FoldWhileIOMaybe<S, A>(\n            K<M, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<A, bool> valueIs) =>\n            M.MapIOMaybe(ma, io => io.FoldWhile(schedule, initialState, folder, valueIs));\n\n        public static virtual K<M, S> FoldWhileIOMaybe<S, A>(\n            K<M, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<A, bool> valueIs) =>\n            M.MapIOMaybe(ma, io => io.FoldWhile(initialState, folder, valueIs));\n\n        public static virtual K<M, S> FoldWhileIOMaybe<S, A>(\n            K<M, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<(S State, A Value), bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.FoldWhile(schedule, initialState, folder, predicate));\n\n        public static virtual K<M, S> FoldWhileIOMaybe<S, A>(\n            K<M, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<(S State, A Value), bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.FoldWhile(initialState, folder, predicate));\n\n        public static virtual K<M, S> FoldUntilIOMaybe<S, A>(\n            K<M, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<S, bool> stateIs) =>\n            M.MapIOMaybe(ma, io => io.FoldUntil(schedule, initialState, folder, stateIs));\n\n        public static virtual K<M, S> FoldUntilIOMaybe<S, A>(\n            K<M, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<S, bool> stateIs) =>\n            M.MapIOMaybe(ma, io => io.FoldUntil(initialState, folder, stateIs));\n\n        public static virtual K<M, S> FoldUntilIOMaybe<S, A>(\n            K<M, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<A, bool> valueIs) =>\n            M.MapIOMaybe(ma, io => io.FoldUntil(schedule, initialState, folder, valueIs));\n\n        public static virtual K<M, S> FoldUntilIOMaybe<S, A>(\n            K<M, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<A, bool> valueIs) =>\n            M.MapIOMaybe(ma, io => io.FoldUntil(initialState, folder, valueIs));\n\n        public static virtual K<M, S> FoldUntilIOMaybe<S, A>(\n            K<M, A> ma,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<(S State, A Value), bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.FoldUntil(initialState, folder, predicate));\n\n        public static virtual K<M, S> FoldUntilIOMaybe<S, A>(\n            K<M, A> ma,\n            Schedule schedule,\n            S initialState,\n            Func<S, A, S> folder,\n            Func<(S State, A Value), bool> predicate) =>\n            M.MapIOMaybe(ma, io => io.FoldUntil(schedule, initialState, folder, predicate));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/Monad/Monad.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class MonadExtensions\n{\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Monadic bind function</param>\n    /// <typeparam name=\"A\">Initial bound value type</typeparam>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <returns>M〈B〉</returns>\n    [Pure]\n    public static K<M, B> Bind<M, A, B>(\n        this K<M, A> ma,\n        Func<A, K<M, B>> f)\n        where M : Monad<M> =>\n        M.Bind(ma, f);\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"f\">Monadic bind function</param>\n    /// <typeparam name=\"A\">Initial bound value type</typeparam>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <returns>M〈B〉</returns>\n    public static K<M, B> Bind<M, A, B>(\n        this K<M, A> ma,\n        Func<A, Pure<B>> f)\n        where M : Functor<M> =>\n        M.Map(x => f(x).Value, ma);\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"A\">Initial bound value type</typeparam>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>M〈C〉</returns>\n    public static K<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma,\n        Func<A, K<M, B>> bind,\n        Func<A, B, C> project)\n        where M : Monad<M> =>\n        M.Bind(ma, a => M.Map(b => project(a, b) , bind(a)));\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"A\">Initial bound value type</typeparam>\n    /// <typeparam name=\"B\">Intermediate bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>M〈C〉</returns>\n    public static K<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma,\n        Func<A, Pure<B>> bind,\n        Func<A, B, C> project)\n        where M : Functor<M> =>\n        M.Map(a => project(a, bind(a).Value), ma);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"A\">Initial bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>M〈C〉</returns>\n    public static K<M, C> SelectMany<E, M, A, C>(\n        this K<M, A> ma,\n        Func<A, Guard<E, Unit>> bind,\n        Func<A, Unit, C> project)\n        where M : Monad<M>, Fallible<E, M> =>\n        M.Bind(ma, a => bind(a) switch\n                        {\n                            { Flag: true } => M.Pure(project(a, default)),\n                            var guard      => M.Fail<C>(guard.OnFalse())\n                        });\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    /// <param name=\"bind\">Monadic bind function</param>\n    /// <param name=\"project\">Projection function</param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"A\">Initial bound value type</typeparam>\n    /// <typeparam name=\"C\">Target bound value type</typeparam>\n    /// <returns>M〈C〉</returns>\n    public static K<M, C> SelectMany<E, M, A, C>(\n        this K<M, A> ma,\n        Func<A, Guard<Fail<E>, Unit>> bind,\n        Func<A, Unit, C> project)\n        where M : Monad<M>, Fallible<E, M> =>\n        M.Bind(ma, a => bind(a) switch\n                        {\n                            { Flag: true } => M.Pure(project(a, default)),\n                            var guard      => M.Fail<C>(guard.OnFalse().Value)\n                        });\n    \n    /// <summary>\n    /// Monadic join operation\n    /// </summary>\n    /// <param name=\"mma\"></param>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Joined monad</returns>\n    public static K<M, A> Flatten<M, A>(this K<M, K<M, A>> mma)\n        where M : Monad<M> =>\n        M.Bind(mma, Prelude.identity);\n\n    /// <param name=\"ma\">Computation to recursively run</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    extension<M, A>(K<M, A> ma) \n        where M : Monad<M>\n    {\n        /// <summary>\n        /// This is equivalent to the infinite loop below without the stack-overflow issues:\n        /// \n        ///     K〈M, A〉go =>\n        ///         ma.Bind(_ => go);\n        /// \n        /// </summary>\n        /// <typeparam name=\"B\">'Result' type, there will never be a result of `B`, but the monad rules may exit the loop\n        /// with an alternative value; and so `B` is still valid</typeparam>\n        /// <returns>A looped computation</returns>\n        [Pure]\n        public K<M, A> Forever() =>\n            Monad.forever<M, A, A>(ma);\n\n        /// <summary>\n        /// This is equivalent to the infinite loop below without the stack-overflow issues:\n        /// \n        ///     K〈M, A〉go =>\n        ///         ma.Bind(_ => go);\n        /// \n        /// </summary>\n        /// <typeparam name=\"B\">'Result' type, there will never be a result of `B`, but the monad rules may exit the loop\n        /// with an alternative value; and so `B` is still valid</typeparam>\n        /// <returns>A looped computation</returns>\n        [Pure]\n        public K<M, B> Forever<B>() =>\n            Monad.forever<M, A, B>(ma);\n\n        /// <summary>\n        /// Running the monadic computation `ma` a fixed number of times (`count`) collecting the results\n        /// </summary>\n        /// <param name=\"count\">Number of times to replicate monadic computation</param>\n        /// <returns>A lifted iterable of values collected</returns>\n        [Pure]\n        public K<M, Iterable<A>> Replicate(int count) =>\n            Monad.replicate(ma, count);\n\n        /// <summary>\n        /// Keep running the monadic computation `ma` collecting the result values until a result value\n        /// yielded triggers a `true` value when passed to the `f` predicate\n        /// </summary>\n        /// <param name=\"f\">Predicate</param>\n        /// <returns>A lifted iterable of values collected</returns>\n        [Pure]\n        public K<M, Iterable<A>> AccumUntil(Func<A, bool> f) =>\n            Monad.accumWhile(ma, f);\n\n        /// <summary>\n        /// Keep running the monadic computation `ma` collecting the result values until a result value\n        /// yielded triggers a `true` value when passed to the `f` predicate\n        /// </summary>\n        /// <param name=\"f\">Predicate</param>\n        /// <returns>A lifted iterable of values collected</returns>\n        [Pure]\n        public K<M, Iterable<A>> AccumUntilM(Func<A, K<M, bool>> f) =>\n            Monad.accumUntilM(ma, f);\n\n        /// <summary>\n        /// Keep running the monadic computation `ma` collecting the result values until a result value\n        /// yielded triggers a `true` value when passed to the `f` predicate\n        /// </summary>\n        /// <param name=\"f\">Predicate</param>\n        /// <returns>A lifted iterable of values collected</returns>\n        [Pure]\n        public K<M, Iterable<A>> AccumWhile(Func<A, bool> f) =>\n            Monad.accumWhile(ma, f);\n\n        /// <summary>\n        /// Keep running the monadic computation `ma` collecting the result values until a result value\n        /// yielded triggers a `true` value when passed to the `f` predicate\n        /// </summary>\n        /// <param name=\"f\">Predicate</param>\n        /// <returns>A lifted iterable of values collected</returns>\n        [Pure]\n        public K<M, Iterable<A>> AccumWhileM(Func<A, K<M, bool>> f) =>\n            Monad.accumWhileM(ma, f);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/Monad/Monad.ExtensionsT.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Monad module\n/// </summary>\npublic static partial class MonadExtensions\n{\n    /// <summary>\n    /// Runs a monadic bind operation on the nested monads \n    /// </summary>\n    /// <remarks>\n    /// If you're working with an inner monad that is concrete then you will first need to\n    /// call `KindT` to cast the monad to a more general `K` version.  This enables the\n    /// `T` variant extensions (like `BindT`, `MapT, etc.) to work without providing\n    /// excessive generic arguments all the way down the chain.\n    /// </remarks>\n    /// <example>\n    ///\n    ///    var mx = Seq〈Option〈int〉〉(Some(1), Some(2), Some(3));\n    ///         \n    ///    var ma = mx.MapT(a => a + 1);\n    ///\n    /// </example>\n    /// <param name=\"mna\">Nested monadic value</param>\n    /// <param name=\"f\">Bind function</param>\n    /// <typeparam name=\"M\">Outer monad trait</typeparam>\n    /// <typeparam name=\"N\">Inner monad trait</typeparam>\n    /// <typeparam name=\"A\">Input bound value</typeparam>\n    /// <typeparam name=\"B\">Output bound value</typeparam>\n    /// <returns>Mapped value</returns>\n    public static K<M, K<N, B>> BindT<M, N, A, B>(this K<M, K<N, A>> mna, Func<A, K<N, B>> f)\n        where M : Functor<M>\n        where N : Monad<N> =>\n        M.Map(na => N.Bind(na, f), mna);\n    \n    /// <summary>\n    /// Runs a monadic bind operation on the nested monads \n    /// </summary>\n    /// <remarks>\n    /// If you're working with an inner monad that is concrete then you will first need to\n    /// call `KindT` to cast the monad to a more general `K` version.  This enables the\n    /// `T` variant extensions (like `BindT`, `MapT, etc.) to work without providing\n    /// excessive generic arguments all the way down the chain.\n    /// </remarks>\n    /// <example>\n    ///\n    ///    var mx = Seq〈Option〈int〉〉(Some(1), Some(2), Some(3));\n    ///         \n    ///    var ma = mx.BindT(a => Seq(Some(a + 1)))\n    ///               .MapT(a => a + 1);;\n    ///\n    /// </example>\n    /// <param name=\"mna\">Nested monadic value</param>\n    /// <param name=\"f\">Bind function</param>\n    /// <typeparam name=\"M\">Outer monad trait</typeparam>\n    /// <typeparam name=\"N\">Inner monad trait</typeparam>\n    /// <typeparam name=\"A\">Input bound value</typeparam>\n    /// <typeparam name=\"B\">Output bound value</typeparam>\n    /// <returns>Mapped value</returns>\n    public static K<M, K<N, B>> BindT<M, N, A, B>(this K<M, K<N, A>> mna, Func<A, K<M, K<N, B>>> f)\n        where M : Monad<M>\n        where N : Monad<N>, Traversable<N> =>\n        mna.Bind(na => na.Map(f).SequenceM()).Map(nna => nna.Flatten());\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/Monad/Monad.Laws.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functions that test that monad laws hold for the `F` monad provided.\n/// </summary>\n/// <para>\n///  * Homomorphism\n///  * Identity\n///  * Interchange\n///  * Monad\n///  * Composition\n/// </para>\n/// <remarks>\n/// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n/// can be proven to be true.  If your monad doesn't have `Equals` then you must provide\n/// the optional `equals` parameter so that the equality of outcomes can be tested.\n/// </remarks>\n/// <typeparam name=\"F\">Functor type</typeparam>\npublic static class MonadLaw<F>\n    where F : Monad<F>\n{\n    /// <summary>\n    /// Assert that the monad laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your monad doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Unit assert(Func<K<F, int>, K<F, int>, bool>? equals = null) =>\n        validate(equals)\n           .IfFail(errors => errors.Throw());\n\n    /// <summary>\n    /// Validate that the monad laws hold\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your monad doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> validate(Func<K<F, int>, K<F, int>, bool>? equals = null)\n    {\n        equals ??= (fa, fb) => fa.Equals(fb);\n        return ApplicativeLaw<F>.validate(equals) >>>\n               leftIdentityLaw(equals)            >>>\n               rightIdentityLaw(equals)           >>>\n               associativityLaw(equals)           >>>\n               recurIsSameAsBind(equals);\n    }\n\n    public static Validation<Error, Unit> recurIsSameAsBind(Func<K<F, int>, K<F, int>, bool>? equals = null)\n    {\n        var example = Seq(1, 2, 3, 4, 5, 6, 7, 8, 9);\n\n        var result1 = Monad.recur((0, example), rec);\n        var result2 = Monad.unsafeRecur((0, example), rec);\n        var result3 = bind(example);\n\n        equals ??= (fa, fb) => fa.Equals(fb);\n        if(!equals(result1, result2)) throw new Exception(\"Bug in MonadLaw or Monad.unsafeRecur. Contact language-ext maintainer via the repo.\");\n        if (!equals(result1, result3))\n        {\n            return Validation.Fail<Error, Unit>(\n                Error.New($\"Monad trait implementation for {typeof(F).Name}.Recur gives a different \"    +\n                          $\"result to the equivalent recursive {typeof(F).Name}.Bind.  This suggests \"   +\n                          $\"an implementation bug, most likely in {typeof(F).Name}.Recur, but possibly \" +\n                          $\"in {typeof(F).Name}.Bind.\"));\n        }\n\n        return Validation.Success<Error, Unit>(unit);\n        \n        K<F, Next<(int Total, Seq<int> Values), int>> rec((int Total, Seq<int> Values) pair) =>\n            pair.Values switch\n            {\n                []          => F.Pure(Next.Done<(int, Seq<int>), int>(pair.Total)),\n                var (x, xs) => F.Pure(Next.Loop<(int, Seq<int>), int>((pair.Total + x, xs))) \n            };\n\n        K<F, int> bind(Seq<int> values) =>\n            values switch\n            {\n                [var x]     => F.Pure(x),\n                var (x, xs) => bind(xs) * (t => x + t)\n            };\n    }\n\n    /// <summary>\n    /// Validate the left-identity law\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your monad doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> leftIdentityLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var a   = 100;\n        var h   = (int x) => F.Pure(x);\n        var lhs = F.Pure(a).Bind(h);\n        var rhs = h(a);\n        \n        return equals(lhs, rhs) \n                   ? unit\n                   : Error.New($\"Monad left-identity law does not hold for {typeof(F).Name}\");\n    }\n\n    /// <summary>\n    /// Validate the right-identity law\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your monad doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> rightIdentityLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var a   = 100;\n        var m   = F.Pure(a);\n        var lhs = m.Bind(F.Pure);\n        var rhs = m;\n        \n        return equals(lhs, rhs) \n                   ? unit\n                   : Error.New($\"Monad right-identity law does not hold for {typeof(F).Name}\");\n    }\n\n    /// <summary>\n    /// Validate the associativity law\n    /// </summary>\n    /// <remarks>\n    /// NOTE: `Equals` must be implemented for the `K〈F, *〉` derived-type, so that the laws\n    /// can be proven to be true.  If your monad doesn't have `Equals` then you must provide\n    /// the optional `equals` parameter so that the equality of outcomes can be tested.\n    /// </remarks>\n    public static Validation<Error, Unit> associativityLaw(Func<K<F, int>, K<F, int>, bool> equals)\n    {\n        var m = F.Pure(100);\n        var g = (int x) => F.Pure(x * 10);\n        var h = (int x) => F.Pure(x + 83);\n        \n        var lhs = m.Bind(g).Bind(h);\n        var rhs = m.Bind(x => g(x).Bind(h));\n        \n        return equals(lhs, rhs) \n                   ? unit\n                   : Error.New($\"Monad associativity law does not hold for {typeof(F).Name}\");\n    }\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/Monad/Monad.Module.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Monad module\n/// </summary>\npublic static partial class Monad\n{\n    [Pure]\n    public static K<M, A> pure<M, A>(A value) \n        where M : Monad<M> =>\n        M.Pure(value);\n\n    [Pure]\n    public static K<M, A> flatten<M, A>(K<M, K<M, A>> mma)\n        where M : Monad<M> =>\n        M.Flatten(mma);\n\n    [Pure]\n    public static K<M, B> bind<M, A, B>(K<M, A> ma, Func<A, K<M, B>> f)\n        where M : Monad<M> =>\n        M.Bind(ma, f);\n    \n    [Pure]\n    public static MB bind<M, MB, A, B>(K<M, A> ma, Func<A, MB> f)\n        where MB : K<M, B>\n        where M : Monad<M> =>\n        (MB)bind(ma, x => f(x));\n\n    /// <summary>\n    /// This is equivalent to the infinite loop below without the stack-overflow issues:\n    ///\n    ///     K〈M, A〉go =>\n    ///         ma.Bind(_ => go);\n    /// \n    /// </summary>\n    /// <param name=\"ma\">Computation to recursively run</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"B\">'Result' type, there will never be a result of `B`, but the monad rules may exit the loop\n    /// with an alternative value; and so `B` is still valid</typeparam>\n    /// <returns>A looped computation</returns>\n    [Pure]\n    public static K<M, A> forever<M, A>(K<M, A> ma)\n        where M : Monad<M> =>\n        forever<M, A, A>(ma);\n    \n    /// <summary>\n    /// This is equivalent to the infinite loop below without the stack-overflow issues:\n    ///\n    ///     K〈M, A〉go =>\n    ///         ma.Bind(_ => go);\n    /// \n    /// </summary>\n    /// <param name=\"ma\">Monadic computation to recursively run</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"B\">'Result' type, there will never be a result of `B`, but the monad rules may exit the loop\n    /// with an alternative value; and so `B` is still valid</typeparam>\n    /// <returns>A looped computation</returns>\n    [Pure]\n    public static K<M, B> forever<M, A, B>(K<M, A> ma) \n        where M : Monad<M> => \n        recur<M, A, B>(default!, _ => ma.Map(_ => Next<A, B>.UnsafeDefault));\n\n    /// <summary>\n    /// Running the monadic computation `ma` a fixed number of times (`count`) collecting the results\n    /// </summary>\n    /// <param name=\"ma\">Monadic computation to repeatedly run</param>\n    /// <param name=\"count\">Number of times to replicate monadic computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>A lifted iterable of values collected</returns>\n    [Pure]\n    public static K<M, Iterable<A>> replicate<M, A>(K<M, A> ma, int count)\n        where M : Monad<M> =>\n        recur<M, (Iterable<A> Items, int Remain), Iterable<A>>(\n            ([], count),\n            acc => ma * (a => acc.Remain > 0 \n                          ? Next.Loop<(Iterable<A> Items, int Remain), Iterable<A>>((acc.Items.Add(a), acc.Remain - 1))\n                          : Next.Done<(Iterable<A> Items, int Remain), Iterable<A>>(acc.Items.Add(a))));\n\n    /// <summary>\n    /// Keep running the monadic computation `ma` collecting the result values until a result value\n    /// yielded triggers a `true` value when passed to the `f` predicate\n    /// </summary>\n    /// <param name=\"ma\">Monadic computation to repeatedly run</param>\n    /// <param name=\"f\">Predicate</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>A lifted iterable of values collected</returns>\n    [Pure]\n    public static K<M, Iterable<A>> accumUntil<M, A>(K<M, A> ma, Func<A, bool> f)\n        where M : Monad<M> =>\n        recur<M, Iterable<A>, Iterable<A>>(\n            [],\n            acc => ma * (a => f(a) ? Next.Done<Iterable<A>, Iterable<A>>(acc)\n                                   : Next.Loop<Iterable<A>, Iterable<A>>(acc.Add(a))));\n\n    /// <summary>\n    /// Keep running the monadic computation `ma` collecting the result values until a result value\n    /// yielded triggers a `true` value when passed to the `f` predicate\n    /// </summary>\n    /// <param name=\"ma\">Monadic computation to repeatedly run</param>\n    /// <param name=\"f\">Predicate</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>A lifted iterable of values collected</returns>\n    [Pure]\n    public static K<M, Iterable<A>> accumUntilM<M, A>(K<M, A> ma, Func<A, K<M, bool>> f)\n        where M : Monad<M> =>\n        recur<M, Iterable<A>, Iterable<A>>(\n            [],\n            acc => ma >> (a => f(a) * (r => r ? Next.Done<Iterable<A>, Iterable<A>>(acc)\n                                              : Next.Loop<Iterable<A>, Iterable<A>>(acc.Add(a)))));\n\n    /// <summary>\n    /// Keep running the monadic computation `ma` collecting the result values until a result value\n    /// yielded triggers a `true` value when passed to the `f` predicate\n    /// </summary>\n    /// <param name=\"ma\">Monadic computation to repeatedly run</param>\n    /// <param name=\"f\">Predicate</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>A lifted iterable of values collected</returns>\n    [Pure]\n    public static K<M, Iterable<A>> accumWhile<M, A>(K<M, A> ma, Func<A, bool> f)\n        where M : Monad<M> =>\n        recur<M, Iterable<A>, Iterable<A>>(\n            [],\n            acc => ma * (a => f(a) ? Next.Loop<Iterable<A>, Iterable<A>>(acc.Add(a))\n                                   : Next.Done<Iterable<A>, Iterable<A>>(acc)));\n\n    /// <summary>\n    /// Keep running the monadic computation `ma` collecting the result values until a result value\n    /// yielded triggers a `true` value when passed to the `f` predicate\n    /// </summary>\n    /// <param name=\"ma\">Monadic computation to repeatedly run</param>\n    /// <param name=\"f\">Predicate</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>A lifted iterable of values collected</returns>\n    [Pure]\n    public static K<M, Iterable<A>> accumWhileM<M, A>(K<M, A> ma, Func<A, K<M, bool>> f)\n        where M : Monad<M> =>\n        recur<M, Iterable<A>, Iterable<A>>(\n            [],\n            acc => ma >> (a => f(a) * (r => r ? Next.Loop<Iterable<A>, Iterable<A>>(acc.Add(a))\n                                              : Next.Done<Iterable<A>, Iterable<A>>(acc))));\n    \n    /// <summary>\n    /// Lift a Next.Done value into the monad\n    /// </summary>\n    [Pure]\n    public static K<M, Next<A, B>> done<M, A, B>(B value) \n        where M : Monad<M> =>\n        M.Pure(Next.Done<A, B>(value));\n    \n    /// <summary>\n    /// Lift a Next.Done value into the monad\n    /// </summary>\n    [Pure]\n    public static K<M, Next<A, B>> loop<M, A, B>(A value) \n        where M : Monad<M> =>\n        M.Pure(Next.Loop<A, B>(value));\n    \n    /// <summary>\n    /// Allow for tail-recursion by using a trampoline function that returns a monad with the bound value\n    /// wrapped by `Next`, which enables decision-making about whether to keep the computation going or not.  \n    /// </summary>\n    /// <remarks>\n    /// It is expected that the implementor of the `Monad` trait has made a 'stack-neutral' implementation\n    /// of `Monad.Recur` \n    /// </remarks>\n    /// <param name=\"value\">Initial value to start the recursive process</param>\n    /// <param name=\"f\">Bind function that returns a monad with the bound value wrapped by `Next`, which\n    /// enables decision-making about whether to recur, or not.</param>\n    /// <typeparam name=\"M\">Monad type</typeparam>\n    /// <typeparam name=\"A\">Loop value</typeparam>\n    /// <typeparam name=\"B\">Done value</typeparam>\n    /// <returns>Monad structure</returns>\n    [Pure]\n    public static K<M, B> recur<M, A, B>(A value, Func<A, K<M, Next<A, B>>> f) \n        where M : Monad<M> =>\n        M.Recur(value, f);\n\n    /// <summary>\n    /// This is a default implementation of `Monad.Recur` that doesn't use the trampoline.\n    /// It's here to use as a placeholder implementation for the trampoline version and for types\n    /// where it's unlikely that recursion will be a problem.  NOTE: Using this isn't declarative,\n    /// and the users of `Monad.recur` would rightly be miffed if an implementation yielded a\n    /// stack-overflow, so use this function with caution.\n    /// </summary>\n    /// <param name=\"value\">Initial value to start the recursive process</param>\n    /// <param name=\"f\">Bind function that returns a monad with the bound value wrapped by `Next`, which\n    /// enables decision-making about whether to recur, or not.</param>\n    /// <typeparam name=\"M\">Monad type</typeparam>\n    /// <typeparam name=\"A\">Loop value</typeparam>\n    /// <typeparam name=\"B\">Done value</typeparam>\n    /// <returns>Monad structure</returns>\n    /// <exception cref=\"BottomException\"></exception>\n    [Pure]\n    public static K<M, B> unsafeRecur<M, A, B>(A value, Func<A, K<M, Next<A, B>>> f)\n        where M : Monad<M> =>\n        f(value).Bind(n => n switch\n                           {\n                               { IsLoop: true, Loop: var v } => unsafeRecur(v, f),\n                               { IsDone: true, Done: var v } => M.Pure(v),\n                               _                                  => throw new BottomException()\n                           });\n\n    /// <summary>\n    /// Allow for tail-recursion by using a trampoline function that returns a monad with the bound value\n    /// wrapped by `Next`, which enables decision-making about whether to keep the computation going or not.  \n    /// </summary>\n    /// <remarks>\n    /// This is a handy pre-built version of `Monad.Recur` that works with `Iterable` (a lazy stream that supports\n    /// both synchronicity and asynchronicity).  The `Natural` and `CoNatural` constraints allow any type that can\n    /// convert to and from `Iterable` to gain this prebuilt stack-protecting recursion.  \n    /// </remarks>\n    /// <param name=\"value\">Initial value to start the recursive process</param>\n    /// <param name=\"f\">Bind function that returns a monad with the bound value wrapped by `Next`, which\n    /// enables decision-making about whether to recur, or not.</param>\n    /// <typeparam name=\"M\">Monad type</typeparam>\n    /// <typeparam name=\"A\">Loop value</typeparam>\n    /// <typeparam name=\"B\">Done value</typeparam>\n    /// <returns>Monad structure</returns>\n    [Pure]\n    public static K<M, B> iterableRecur<M, A, B>(A value, Func<A, K<M, Next<A, B>>> f)\n        where M : Natural<M, Iterable>, CoNatural<M, Iterable>\n    {\n        var iterable = Iterable.createRange(IO.lift(e => go(e.Token)));\n        return CoNatural.transform<M, Iterable, B>(iterable);\n        \n        async IAsyncEnumerable<B> go([EnumeratorCancellation] CancellationToken token)\n        {\n            List<A> values = [value];\n            List<A> next   = [];\n\n            while (true)\n            {\n                foreach (var x in values)\n                {\n                    var iterable1 = Natural.transform<M, Iterable, Next<A, B>>(f(x)).As().AsAsyncEnumerable(token);\n                    await foreach (var mb in iterable1)\n                    {\n                        if (mb.IsDone)\n                        {\n                            yield return mb.Done;\n                        }\n                        else\n                        {\n                            next.Add(mb.Loop);\n                        }\n                    }\n                }\n\n                if (next.Count == 0)\n                {\n                    break;\n                }\n                else\n                {\n                    (values, next) = (next, values);\n                    next.Clear();\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Allow for tail-recursion by using a trampoline function that returns an enumerable monad with the bound value\n    /// wrapped by `Next`, which enables decision-making about whether to keep the computation going or not.  \n    /// </summary>\n    /// <remarks>\n    /// This is a handy pre-built version of `Monad.Recur` that works with `IEnumerable` (a lazy stream that supports\n    /// synchronicity only)  \n    /// </remarks>\n    /// <param name=\"value\">Initial value to start the recursive process</param>\n    /// <param name=\"f\">Bind function that returns a monad with the bound value wrapped by `Next`, which\n    /// enables decision-making about whether to recur, or not.</param>\n    /// <typeparam name=\"M\">Monad type</typeparam>\n    /// <typeparam name=\"A\">Loop value</typeparam>\n    /// <typeparam name=\"B\">Done value</typeparam>\n    /// <returns>Monad structure</returns>\n    [Pure]\n    public static IEnumerable<B> enumerableRecur<A, B>(A value, Func<A, IEnumerable<Next<A, B>>> f)\n    {\n        List<A> values = [value];\n        List<A> next   = [];\n\n        while (true)\n        {\n            foreach (var x in values)\n            {\n                var iterable1 = f(x);\n                foreach (var mb in iterable1)\n                {\n                    if (mb.IsDone)\n                    {\n                        yield return mb.Done;\n                    }\n                    else\n                    {\n                        next.Add(mb.Loop);\n                    }\n                }\n            }\n\n            if (next.Count == 0)\n            {\n                break;\n            }\n            else\n            {\n                (values, next) = (next, values);\n                next.Clear();\n            }\n        }\n    }\n    \n    \n    /// <summary>\n    /// When the predicate evaluates to `true`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> when<M>(K<M, bool> Pred, K<M, Unit> Then)\n        where M : Monad<M> =>\n        Pred.Bind(f => Applicative.when(f, Then));\n\n    /// <summary>\n    /// When the predicate evaluates to `true`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> when<M>(K<M, bool> Pred, Pure<Unit> Then)\n        where M : Monad<M> =>\n        Pred.Bind(f => Applicative.when(f, M.Pure(Prelude.unit)));\n\n    /// <summary>\n    /// When the predicate evaluates to `false`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> unless<M>(K<M, bool> Pred, K<M, Unit> Then)\n        where M : Monad<M> =>\n        Pred.Bind(f => Applicative.unless(f, Then));\n\n    /// <summary>\n    /// When the predicate evaluates to `false`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> unless<M>(K<M, bool> Pred, Pure<Unit> Then)\n        where M : Monad<M> =>\n        Pred.Bind(f => Applicative.unless(f, M.Pure(Prelude.unit)));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<M, A> Then, K<M, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? Then : Else);\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<M, A> Then, K<IO, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? Then : M.LiftIOMaybe(Else));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<IO, A> Then, K<M, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.LiftIOMaybe(Then) : Else);\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<IO, A> Then, K<IO, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.LiftIOMaybe(Then) : M.LiftIOMaybe(Else));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<M, A> Then, Pure<A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? Then : M.Pure(Else.Value));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, Pure<A> Then, K<M, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.Pure(Then.Value) : Else);\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, Pure<A> Then, Pure<A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.Pure(Then.Value) : M.Pure(Else.Value));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, Pure<A> Then, K<IO, A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.Pure(Then.Value) : M.LiftIOMaybe(Else));\n\n    /// <summary>\n    /// Compute the predicate and depending on its state compute `Then` or `Else`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <param name=\"Else\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, A> iff<M, A>(K<M, bool> Pred, K<IO, A> Then, Pure<A> Else)\n        where M : Monad<M> =>\n        Pred.Bind(f => f ? M.LiftIOMaybe(Then) : M.Pure(Else.Value));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/Monad/Monad.Operators.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class MonadExtensions\n{\n    extension<M, A, B>(K<M, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static K<M, B> operator >> (K<M, A> ma, Func<A, K<M, B>> f) =>\n            ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators\n        /// (such as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static K<M, B> operator >> (K<M, A> lhs, K<M, B> rhs) =>\n            lhs >> (_ => rhs);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the second, like sequencing operators\n        /// (such as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"mb\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static K<M, A> operator << (K<M, A> lhs, K<M, B> rhs) =>\n            lhs >> (x => rhs.Map(_ => x));\n    }\n    \n    extension<M, A, B>(K<M, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static K<M, B> operator >> (K<M, A> ma, Func<A, K<IO, B>> f) =>\n            ma.Bind(x => M.LiftIO(f(x)));\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static K<M, B> operator >> (K<M, A> lhs, K<IO, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<M, A, B>(K<IO, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static K<M, B> operator >> (K<IO, A> ma, Func<A, K<M, B>> f) =>\n            M.LiftIO(ma).Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static K<M, B> operator >> (K<IO, A> lhs, K<M, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<M, A>(K<M, A> self)\n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static K<M, A> operator >> (K<M, A> lhs, K<M, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n    \n    extension<M, A>(K<M, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static K<M, A> operator >> (K<M, A> lhs, K<IO, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/Monad/Monad.Trait.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Monad trait\n/// </summary>\n/// <typeparam name=\"M\">Self-referring trait</typeparam>\npublic interface Monad<M> :\n    Applicative<M>, \n    Maybe.MonadUnliftIO<M> \n    where M : Monad<M>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Abstract members\n    //\n    \n    public static abstract K<M, B> Bind<A, B>(K<M, A> ma, Func<A, K<M, B>> f);\n\n    /// <summary>\n    /// Tail-recursive bind\n    /// </summary>\n    /// <param name=\"value\">Initial value to the bind expression</param>\n    /// <param name=\"f\">Bind function</param>\n    /// <typeparam name=\"A\">Continuation value type</typeparam>\n    /// <typeparam name=\"B\">Completed value type</typeparam>\n    /// <returns>Result of repeatedly invoking `f` until Right(b) is returned</returns>\n    public static abstract K<M, B> Recur<A, B>(A value, Func<A, K<M, Next<A, B>>> f);\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Default implementations\n    //\n    \n    /// <summary>\n    /// Lift a Next.Done value into the monad\n    /// </summary>\n    public static virtual K<M, Next<A, B>> Done<A, B>(B value) =>\n        M.Pure(Next.Done<A, B>(value));\n    \n    /// <summary>\n    /// Lift a Next.Done value into the monad\n    /// </summary>\n    public static virtual K<M, Next<A, B>> Loop<A, B>(A value) =>\n        M.Pure(Next.Loop<A, B>(value));\n\n    public static virtual K<M, C> SelectMany<A, B, C>(K<M, A> ma, Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        ma.Bind(x => bind(x).Map(y => project(x, y)));\n\n    public static virtual K<M, C> SelectMany<A, B, C>(K<M, A> ma, Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        M.Map(x => project(x, bind(x).Value), ma);\n\n    public static virtual K<M, A> Flatten<A>(K<M, K<M, A>> mma) =>\n        M.Bind(mma, identity);\n\n    static K<M, A> Applicative<M>.Actions<A>(IterableNE<K<M, A>> mas)\n    {\n        // TODO: Check if this implementation is valid\n        \n        return M.Recur(mas.GetIterator(), go).Flatten();\n        K<M, Next<Iterator<K<M, A>>, K<M, A>>> go(Iterator<K<M, A>> iter) =>\n            iter switch\n            {\n                (var head, { IsEmpty : true }) => M.Pure(Next.Done<Iterator<K<M, A>>, K<M, A>>(head)),\n                var (head, tail)               => head.Map(_ => Next.Loop<Iterator<K<M, A>>, K<M, A>>(tail.Clone()))\n            };\n    }   \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadIO/MonadIO.Extensions.cs",
    "content": "using System;\nusing LanguageExt.DSL;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class MonadIOExtensions\n{\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static K<M, B> Bind<M, A, B>(\n        this K<M, A> ma,\n        Func<A, IO<B>> f)\n        where M : MonadIO<M>, Monad<M> =>\n        M.Bind(ma, x => M.LiftIO(f(x)));\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static K<M, B> Bind<M, A, B>(\n        this IO<A> ma,\n        Func<A, K<M, B>> f)\n        where M : MonadIO<M>, Monad<M> =>\n        M.Bind(M.LiftIO(ma), f);\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static K<M, C> SelectMany<M, A, B, C>(this K<M, A> ma, Func<A, IO<B>> bind, Func<A, B, C> project) \n        where M : MonadIO<M> =>\n        ma.Bind(x => IOTail<A>.resolve(x, bind(x), project));\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static K<M, C> SelectMany<M, A, B, C>(this IO<A> ma, Func<A, K<M, B>> bind, Func<A, B, C> project) \n        where M : MonadIO<M>, Monad<M> =>\n        M.SelectMany(M.LiftIOMaybe(ma), bind, project);\n    \n    /// <summary>\n    /// Queue this IO operation to run on the thread-pool. \n    /// </summary>\n    /// <param name=\"timeout\">Maximum time that the forked IO operation can run for. `None` for no timeout.</param>\n    /// <returns>Returns a `ForkIO` data-structure that contains two IO effects that can be used to either cancel\n    /// the forked IO operation or to await the result of it.\n    /// </returns>\n    public static K<M, ForkIO<A>> ForkIO<M, A>(this K<M, A> ma, Option<TimeSpan> timeout = default) \n        where M : MonadUnliftIO<M> =>\n        M.ForkIO(ma, timeout);\n    \n    /// <summary>\n    /// Queue this IO operation to run on the thread-pool. \n    /// </summary>\n    /// <param name=\"timeout\">Maximum time that the forked IO operation can run for. `None` for no timeout.</param>\n    /// <returns>Returns a `ForkIO` data-structure that contains two IO effects that can be used to either cancel\n    /// the forked IO operation or to await the result of it.\n    /// </returns>\n    public static K<M, ForkIO<A>> ForkIOMaybe<M, A>(this K<M, A> ma, Option<TimeSpan> timeout = default) \n        where M : MonadIO<M> =>\n        M.ForkIOMaybe(ma, timeout);    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadIO/MonadIO.Module.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Monad module\n/// </summary>\npublic static class MonadIO\n{\n    /// <summary>\n    /// When the predicate evaluates to `true`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> when<M>(K<M, bool> Pred, K<IO, Unit> Then)\n        where M : MonadIO<M> =>\n        Pred.Bind(f => Applicative.when(f, Then).As());\n\n    /// <summary>\n    /// When the predicate evaluates to `false`, compute `Then`\n    /// </summary>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Then\">Computation</param>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <returns>Unit monad</returns>\n    [Pure]\n    public static K<M, Unit> unless<M>(K<M, bool> Pred, K<IO, Unit> Then)\n        where M : MonadIO<M> =>\n        Pred.Bind(f => Applicative.unless(f, Then).As());\n    \n    /// <summary>\n    /// Embeds the `IO` monad into the `M〈A〉` monad.  NOTE: This will fail if the monad transformer\n    /// stack doesn't have an `IO` monad as its innermost monad.\n    /// </summary>\n    [Pure]\n    public static K<M, A> liftIO<M, A>(IO<A> ma) \n        where M : Maybe.MonadIO<M>, Monad<M> =>\n        M.LiftIOMaybe(ma);\n    \n    /// <summary>\n    /// Embeds the `IO` monad into the `M〈A〉` monad.  NOTE: This will fail if the monad transformer\n    /// stack doesn't have an `IO` monad as its innermost monad.\n    /// </summary>\n    [Pure]\n    public static K<M, A> liftIO<M, A>(K<IO, A> ma) \n        where M : Maybe.MonadIO<M>, Monad<M> =>\n        M.LiftIOMaybe(ma);\n\n    /// <summary>\n    /// Get the environment value threaded through the IO computation\n    /// </summary>\n    /// <typeparam name=\"M\">Trait</typeparam>\n    /// <returns>Lifted environment value</returns>\n    [Pure]\n    public static K<M, EnvIO> envIO<M>()  \n        where M : MonadIO<M>, Monad<M> =>\n        M.EnvIO;\n    \n    /// <summary>\n    /// Get the cancellation token threaded through the IO computation\n    /// </summary>\n    /// <typeparam name=\"M\">Trait</typeparam>\n    /// <returns>Lifted cancellation token</returns>\n    [Pure]\n    public static K<M, CancellationToken> token<M>()  \n        where M : MonadIO<M>, Monad<M> =>\n        M.Token;\n\n    /// <summary>\n    /// Get the cancellation token-source threaded through the IO computation\n    /// </summary>\n    /// <typeparam name=\"M\">Trait</typeparam>\n    /// <returns>Lifted cancellation token-source</returns>\n    [Pure]\n    public static K<M, CancellationTokenSource> tokenSource<M>() \n        where M : MonadIO<M>, Monad<M> =>\n        M.TokenSource;\n\n    /// <summary>\n    /// Get the synchronisation-context threaded through the IO computation\n    /// </summary>\n    /// <typeparam name=\"M\">Trait</typeparam>\n    /// <returns>Lifted synchronisation-context</returns>\n    [Pure]\n    public static K<M, Option<SynchronizationContext>> syncContext<M>() \n        where M : MonadIO<M>, Monad<M> =>\n        M.SyncContext;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadIO/MonadIO.Trait.cs",
    "content": "using System;\nusing System.Threading;\nusing LanguageExt.Common;\nusing LanguageExt.DSL;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Monad that is either the IO monad or a transformer with the IO monad in its stack\n/// </summary>\n/// <typeparam name=\"M\">Self-referring trait</typeparam>\npublic interface MonadIO<M> : Monad<M>\n    where M : MonadIO<M>\n{\n    /// <summary>\n    /// Lifts the IO monad into a monad transformer stack.  \n    /// </summary>\n    /// <param name=\"ma\">IO computation to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>The outer monad with the IO monad lifted into it</returns>\n    public static virtual K<M, A> LiftIO<A>(K<IO, A> ma) =>\n        M.LiftIO(ma.As());\n\n    /// <summary>\n    /// Lifts the IO monad into a monad transformer stack.  \n    /// </summary>\n    /// <remarks>\n    /// IMPLEMENTATION REQUIRED: If this method isn't overloaded in this monad\n    /// or any monad in the stack on the way to the inner-monad, then it will throw\n    /// an exception.\n    ///\n    /// This isn't ideal, it appears to be the only way to achieve this\n    /// kind of functionality in C# without resorting to magic. \n    /// </remarks>\n    /// <param name=\"ma\">IO computation to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>The outer monad with the IO monad lifted into it</returns>\n    /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n    /// the inner monad or any monad in the stack on the way to the inner-monad,\n    /// then it will throw an exception.</exception>\n    public static abstract K<M, A> LiftIO<A>(IO<A> ma);\n\n    static K<M, A> Maybe.MonadIO<M>.LiftIOMaybe<A>(IO<A> ma) => \n        M.LiftIO(ma);\n\n    static K<M, A> Maybe.MonadIO<M>.LiftIOMaybe<A>(K<IO, A> ma) => \n        M.LiftIO(ma);\n    \n    public static virtual K<M, EnvIO> EnvIO => \n        M.LiftIOMaybe(IO.env);\n    \n    public static virtual K<M, CancellationToken> Token => \n        M.LiftIOMaybe(IO.token);\n\n    public static virtual K<M, CancellationTokenSource> TokenSource =>\n        M.LiftIOMaybe(IO.source);\n\n    public static virtual K<M, Option<SynchronizationContext>> SyncContext =>\n        M.LiftIOMaybe(IO.syncContext);\n    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadT/MonadT.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadT/MonadT.Module.cs",
    "content": "﻿namespace LanguageExt.Traits;\n\npublic static partial class MonadT\n{\n    /// <summary>\n    /// Lift a monad into a transformer\n    /// </summary>\n    /// <param name=\"ma\">Monad to lift</param>\n    /// <typeparam name=\"MTran\">Transformer</typeparam>\n    /// <typeparam name=\"M\">Monad</typeparam>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Monad transformer with the monad lifted into it</returns>\n    public static K<MTran, A> lift<MTran, M, A>(K<M, A> ma)\n        where M : Monad<M>\n        where MTran : MonadT<MTran, M> =>\n        MTran.Lift(ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadT/MonadT.Trait.cs",
    "content": "﻿namespace LanguageExt.Traits;\n\n/// <summary>\n/// MonadT trait\n/// </summary>\n/// <typeparam name=\"T\">Self referring trait</typeparam>\n/// <typeparam name=\"M\">Inner monad trait</typeparam>\npublic interface MonadT<T, out M> : Monad<T> \n    where T : MonadT<T, M>\n    where M : Monad<M>\n{\n    public static abstract K<T, A> Lift<A>(K<M, A> ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadUnliftIO/MonadUnliftIO.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class MonadUnliftIOExtensions\n{\n    /// <summary>\n    /// Await a forked operation\n    /// </summary>\n    public static K<M, A> Await<M, A>(this K<M, ForkIO<A>> ma) \n        where M : MonadUnliftIO<M> =>\n        M.Await(ma);\n\n    /// <param name=\"ma\">Resource acquisition</param>\n    extension<M, A>(K<M, A> ma) where M : MonadUnliftIO<M>\n    {\n        /// <summary>\n        /// Creates a local cancellation environment\n        /// </summary>\n        /// <remarks>\n        /// A local cancellation environment stops other IO computations, that rely on the same\n        /// environmental cancellation token, from being taken down by a regional cancellation.\n        /// \n        /// If an `IO.cancel` is invoked locally, then it will still create an exception that\n        /// propagates upwards and so catching cancellations is still important. \n        /// </remarks>\n        /// <returns>Result of the computation</returns>\n        public K<M, A> LocalIO() =>\n            M.LocalIO(ma);\n\n        /// <summary>\n        /// Wraps this computation in a local-environment that ignores any cancellation-token cancellation requests.\n        /// </summary>\n        /// <returns>An uninterruptible computation</returns>\n        public K<M, A> UninterruptibleIO() =>\n            M.UninterruptibleIO(ma);\n\n        /// <summary>\n        /// Make this IO computation run on the `SynchronizationContext` that was captured at the start\n        /// of the IO chain (i.e. the one embedded within the `EnvIO` environment that is passed through\n        /// all IO computations)\n        /// </summary>\n        public K<M, A> PostIO() =>\n            M.PostIO(ma);\n        \n        /// <summary>\n        /// Timeout operation if it takes too long\n        /// </summary>\n        public K<M, A> TimeoutIO(TimeSpan timeout) =>\n            M.TimeoutIO(ma, timeout);\n\n        /// <summary>\n        /// The IO monad tracks resources automatically, this creates a local resource environment\n        /// to run this computation in.  Once the computation has completed any resources acquired\n        /// are automatically released.  Imagine this as the ultimate `using` statement.\n        /// </summary>\n        public K<M, A> BracketIO() =>\n            M.BracketIO(ma);\n\n        /// <summary>\n        /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n        /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n        /// in between.\n        /// </summary>\n        /// <param name=\"Use\">Function to use the acquired resource</param>\n        /// <param name=\"Fin\">Function to invoke to release the resource</param>\n        public K<M, C> BracketIO<B, C>(Func<A, IO<C>> Use,\n                                       Func<A, IO<B>> Fin) =>\n            M.BracketIO(ma, Use, Fin);\n\n        /// <summary>\n        /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n        /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n        /// in between.\n        /// </summary>\n        /// <param name=\"Use\">Function to use the acquired resource</param>\n        /// <param name=\"Catch\">Function to run to handle any exceptions</param>\n        /// <param name=\"Fin\">Function to invoke to release the resource</param>\n        public K<M, C> BracketIO<B, C>(Func<A, IO<C>> Use,\n                                       Func<Error, IO<C>> Catch,\n                                       Func<A, IO<B>> Fin) =>\n            M.BracketIO(ma, Use, Catch, Fin);\n\n\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n        //\n        //  Repeating the effect\n        //\n        \n        /// <summary>\n        /// Keeps repeating the computation forever, or until an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <returns>The result of the last invocation</returns>\n        public K<M, A> RepeatIO() =>\n            M.RepeatIO(ma);\n\n        /// <summary>\n        /// Keeps repeating the computation, until the scheduler expires, or an error occurs  \n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <returns>The result of the last invocation</returns>\n        public K<M, A> RepeatIO(Schedule schedule) =>\n            M.RepeatIO(ma, schedule);\n\n        /// <summary>\n        /// Keeps repeating the computation until the predicate returns false, or an error occurs \n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        public K<M, A> RepeatWhileIO(Func<A, bool> predicate) =>\n            M.RepeatWhileIO(ma, predicate);\n\n        /// <summary>\n        /// Keeps repeating the computation, until the scheduler expires, or the predicate returns false, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        public K<M, A> RepeatWhileIO(Schedule schedule,\n                                     Func<A, bool> predicate) =>\n            M.RepeatWhileIO(ma, schedule, predicate);\n\n        /// <summary>\n        /// Keeps repeating the computation until the predicate returns true, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        public K<M, A> RepeatUntilIO(Func<A, bool> predicate) =>\n            M.RepeatUntilIO(ma, predicate);\n\n        /// <summary>\n        /// Keeps repeating the computation, until the scheduler expires, or the predicate returns true, or an error occurs\n        /// </summary>\n        /// <remarks>\n        /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n        /// acquire resources and return them from within a repeated computation.\n        /// </remarks>\n        /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n        /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n        /// <returns>The result of the last invocation</returns>\n        public K<M, A> RepeatUntilIO(Schedule schedule,\n                                     Func<A, bool> predicate) =>\n            M.RepeatUntilIO(ma, schedule, predicate);\n\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n        //\n        //  Retrying the effect when it fails\n        //\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will retry forever\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public K<M, A> RetryIO() =>\n            M.RetryIO(ma);\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will retry until the schedule expires\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public K<M, A> RetryIO(Schedule schedule) =>\n            M.RetryIO(ma, schedule);\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n        /// at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public K<M, A> RetryWhileIO(Func<Error, bool> predicate) =>\n            M.RetryWhileIO(ma, predicate);\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n        /// or, until the schedule expires; at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public K<M, A> RetryWhileIO(Schedule schedule,\n                                    Func<Error, bool> predicate) =>\n            M.RetryWhileIO(ma, schedule, predicate);\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n        /// at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public K<M, A> RetryUntilIO(Func<Error, bool> predicate) =>\n            M.RetryUntilIO(ma, predicate);\n\n        /// <summary>\n        /// Retry if the IO computation fails \n        /// </summary>\n        /// <remarks>\n        /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n        /// or, until the schedule expires; at which point the last raised error will be thrown.\n        /// </remarks>\n        /// <remarks>\n        /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n        /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n        /// acquires resources will have them tracked in the usual way. \n        /// </remarks>\n        public K<M, A> RetryUntilIO(Schedule schedule,\n                                    Func<Error, bool> predicate) =>\n            M.RetryUntilIO(ma, schedule, predicate);\n    }\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Folding\n    //\n\n    public static K<M, S> FoldIO<M, S, A>(\n        this K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder) \n        where M : MonadUnliftIO<M> =>\n        M.FoldIO(ma, schedule, initialState, folder);\n\n    public static K<M, S> FoldIO<M, S, A>(\n        this K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder) \n        where M : MonadUnliftIO<M> =>\n        M.FoldIO(ma, initialState, folder);\n\n    public static K<M, S> FoldWhileIO<M, S, A>(\n        this K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) \n        where M : MonadUnliftIO<M> =>\n        M.FoldWhileIO(ma, schedule, initialState, folder, stateIs);\n\n    public static K<M, S> FoldWhileIO<M, S, A>(\n        this K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) \n        where M : MonadUnliftIO<M> =>\n        M.FoldWhileIO(ma, initialState, folder, stateIs);\n\n    public static K<M, S> FoldWhileIO<M, S, A>(\n        this K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) \n        where M : MonadUnliftIO<M> =>\n        M.FoldWhileIO(ma, schedule, initialState, folder, valueIs);\n\n    public static K<M, S> FoldWhileIO<M, S, A>(\n        this K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) \n        where M : MonadUnliftIO<M> =>\n        M.FoldWhileIO(ma, initialState, folder, valueIs);\n    \n    public static K<M, S> FoldWhileIO<M, S, A>(\n        this K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        M.FoldWhileIO(ma, schedule, initialState, folder, predicate);\n\n    public static K<M, S> FoldWhileIO<M, S, A>(\n        this K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        M.FoldWhileIO(ma, initialState, folder, predicate);\n    \n    public static K<M, S> FoldUntilIO<M, S, A>(\n        this K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) \n        where M : MonadUnliftIO<M> =>\n        M.FoldUntilIO(ma, schedule, initialState, folder, stateIs);\n    \n    public static K<M, S> FoldUntilIO<M, S, A>(\n        this K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) \n        where M : MonadUnliftIO<M> =>\n        M.FoldUntilIO(ma, initialState, folder, stateIs);\n    \n    public static K<M, S> FoldUntilIO<M, S, A>(\n        this K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) \n        where M : MonadUnliftIO<M> =>\n        M.FoldUntilIO(ma, schedule, initialState, folder, valueIs);\n    \n    public static K<M, S> FoldUntilIO<M, S, A>(\n        this K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) \n        where M : MonadUnliftIO<M> =>\n        M.FoldUntilIO(ma, initialState, folder, valueIs);\n    \n    public static K<M, S> FoldUntilIO<M, S, A>(\n        this K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        M.FoldUntilIO(ma, initialState, folder, predicate);\n\n    public static K<M, S> FoldUntilIO<M, S, A>(\n        this K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) \n        where M : MonadUnliftIO<M> =>\n        M.FoldUntilIO(ma, schedule, initialState, folder, predicate);\n }\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadUnliftIO/MonadUnliftIO.Module.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Monad module\n/// </summary>\npublic static class MonadUnliftIO\n{\n    /// <summary>\n    /// Get the `IO` monad from within the `M` monad\n    /// </summary>\n    /// <remarks>\n    /// This only works if the `M` trait implements `MonadIO.ToIO`.\n    /// </remarks>\n    [Pure]\n    public static K<M, IO<A>> toIO<M, A>(K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        M.ToIOMaybe(ma);\n    \n    /// <summary>\n    /// Map the underlying IO monad\n    /// </summary>\n    [Pure]\n    public static K<M, B> mapIO<M, A, B>(Func<IO<A>, IO<B>> f, K<M, A> ma)\n        where M : MonadUnliftIO<M> =>\n        M.MapIOMaybe(ma, f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/MonadUnliftIO/MonadUnliftIO.Trait.cs",
    "content": "using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Monad that is either the IO monad or a transformer with the IO monad in its stack.\n///\n/// 'Unlifting' allows us to get at the nested `IO` monad and work on it, then to repackage it\n/// wherever it is in the transformer stack.  This allows all IO functionality to work on any\n/// type that encapsulates the `IO` monad.\n///\n/// This opens up a ton of default functionality for monads that are able to support unlifting.\n/// It must be stated that not all monads are capable of supporting unlifting.  It's usually the\n/// case that if they have a complex return type (like a union) then they can't support unlifting\n/// without compromising the integrity of the monad.\n/// </summary>\n/// <typeparam name=\"M\">Self-referring trait</typeparam>\npublic interface MonadUnliftIO<M> : MonadIO<M>\n    where M : MonadUnliftIO<M>\n{\n    /// <summary>\n    /// Extract the IO monad from within the M monad (usually as part of a monad-transformer stack).\n    /// </summary>\n    /// <remarks>\n    /// IMPLEMENTATION REQUIRED: If this method isn't overloaded in this monad\n    /// or any monad in the stack on the way to the inner-monad, then it will throw\n    /// an exception.\n    ///\n    /// This isn't ideal, it appears to be the only way to achieve this\n    /// kind of functionality in C# without resorting to magic. \n    /// </remarks>\n    /// <exception cref=\"ExceptionalException\">If this method isn't overloaded in\n    /// the inner monad or any monad in the stack on the way to the inner-monad,\n    /// then it will throw an exception.</exception>\n    public static abstract K<M, IO<A>> ToIO<A>(K<M, A> ma);\n\n    /// <summary>\n    /// Extract the IO monad from within the `M` monad (usually as part of a monad-transformer stack).  Then perform\n    /// a mapping operation on the IO action before lifting the IO back into the `M` monad.\n    /// </summary>\n    public static virtual K<M, B> MapIO<A, B>(K<M, A> ma, Func<IO<A>, IO<B>> f) =>\n        M.ToIO(ma).Bind(io => M.LiftIO(f(io)));\n\n    /// <summary>\n    /// Queue this IO operation to run on the thread-pool. \n    /// </summary>\n    /// <param name=\"timeout\">Maximum time that the forked IO operation can run for. `None` for no timeout.</param>\n    /// <returns>Returns a `ForkIO` data-structure that contains two IO effects that can be used to either cancel\n    /// the forked IO operation or to await the result of it.\n    /// </returns>\n    public static virtual K<M, ForkIO<A>> ForkIO<A>(K<M, A> ma, Option<TimeSpan> timeout) =>\n        M.MapIO(ma, io => io.Fork(timeout));\n\n    /// <summary>\n    /// Await a forked operation\n    /// </summary>\n    public static virtual K<M, A> Await<A>(K<M, ForkIO<A>> ma) =>\n        M.MapIO(ma, io => io.Bind(f => f.Await));\n\n    /// <summary>\n    /// Creates a local cancellation environment\n    /// </summary>\n    /// <remarks>\n    /// A local cancellation environment stops other IO computations, that rely on the same\n    /// environmental cancellation token, from being taken down by a regional cancellation.\n    ///\n    /// If an `IO.cancel` is invoked locally, then it will still create an exception that\n    /// propagates upwards and so catching cancellations is still important. \n    /// </remarks>\n    /// <param name=\"ma\">Computation to run within the local context</param>\n    /// <typeparam name=\"A\">Bound value</typeparam>\n    /// <returns>Result of the computation</returns>\n    public static virtual K<M, A> LocalIO<A>(K<M, A> ma) =>\n        M.MapIO(ma, io => io.Local());\n\n    /// <summary>\n    /// Wraps this computation in a local-environment that ignores any cancellation-token cancellation requests.\n    /// </summary>\n    /// <returns>An uninterruptible computation</returns>\n    public static virtual K<M, A> UninterruptibleIO<A>(K<M, A> ma) =>\n        M.MapIO(ma, io => io.Uninterruptible());\n\n    /// <summary>\n    /// Make this IO computation run on the `SynchronizationContext` that was captured at the start\n    /// of the IO chain (i.e. the one embedded within the `EnvIO` environment that is passed through\n    /// all IO computations)\n    /// </summary>\n    public static virtual K<M, A> PostIO<A>(K<M, A> ma) =>\n        M.MapIO(ma, io => io.Post());\n\n    /// <summary>\n    /// Timeout operation if it takes too long\n    /// </summary>\n    public static virtual K<M, A> TimeoutIO<A>(K<M, A> ma, TimeSpan timeout) =>\n        M.MapIO(ma, io => io.Timeout(timeout));\n\n    /// <summary>\n    /// The IO monad tracks resources automatically; this creates a local resource environment\n    /// to run this computation in.  Once the computation is completed, any resources acquired\n    /// are automatically released.  Imagine this as the ultimate `using` statement.\n    /// </summary>\n    public static virtual K<M, A> BracketIO<A>(K<M, A> ma) =>\n        M.MapIO(ma, io => io.Bracket());\n\n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <param name=\"Acq\">Resource acquisition</param>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Fin\">Function to invoke to release the resource</param>\n    public static virtual K<M, C> BracketIO<A, B, C>(\n        K<M, A> Acq,\n        Func<A, IO<C>> Use,\n        Func<A, IO<B>> Fin) =>\n        M.MapIO(Acq, io => io.Bracket(Use, Fin));\n\n    /// <summary>\n    /// When acquiring, using, and releasing various resources, it can be quite convenient to write a function to manage\n    /// the acquisition and releasing, taking a function of the acquired value that specifies an action to be performed\n    /// in between.\n    /// </summary>\n    /// <param name=\"Acq\">Resource acquisition</param>\n    /// <param name=\"Use\">Function to use the acquired resource</param>\n    /// <param name=\"Catch\">Function to run to handle any exceptions</param>\n    /// <param name=\"Fin\">Function to invoke to release the resource</param>\n    public static virtual K<M, C> BracketIO<A, B, C>(\n        K<M, A> Acq,\n        Func<A, IO<C>> Use,\n        Func<Error, IO<C>> Catch,\n        Func<A, IO<B>> Fin) =>\n        M.MapIO(Acq, io => io.Bracket(Use, Catch, Fin));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Repeating the effect\n    //\n\n    /// <summary>\n    /// Keeps repeating the computation forever, or until an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <returns>The result of the last invocation</returns>\n    public static virtual K<M, A> RepeatIO<A>(K<M, A> ma) =>\n        M.MapIO(ma, io => io.Repeat());\n\n    /// <summary>\n    /// Keeps repeating the computation until the scheduler expires, or an error occurs  \n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <returns>The result of the last invocation</returns>\n    public static virtual K<M, A> RepeatIO<A>(\n        K<M, A> ma,\n        Schedule schedule) =>\n        M.MapIO(ma, io => io.Repeat(schedule));\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns false, or an error occurs \n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    public static virtual K<M, A> RepeatWhileIO<A>(\n        K<M, A> ma,\n        Func<A, bool> predicate) =>\n        M.MapIO(ma, io => io.RepeatWhile(predicate));\n\n    /// <summary>\n    /// Keeps repeating the computation until the scheduler expires, or the predicate returns false, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"predicate\">Keep repeating while this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    public static virtual K<M, A> RepeatWhileIO<A>(\n        K<M, A> ma,\n        Schedule schedule,\n        Func<A, bool> predicate) =>\n        M.MapIO(ma, io => io.RepeatWhile(schedule, predicate));\n\n    /// <summary>\n    /// Keeps repeating the computation until the predicate returns true, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    public static virtual K<M, A> RepeatUntilIO<A>(\n        K<M, A> ma,\n        Func<A, bool> predicate) =>\n        M.MapIO(ma, io => io.RepeatUntil(predicate));\n\n    /// <summary>\n    /// Keeps repeating the computation until the scheduler expires, or the predicate returns true, or an error occurs\n    /// </summary>\n    /// <remarks>\n    /// Any resources acquired within a repeated IO computation will automatically be released.  This also means you can't\n    /// acquire resources and return them from within a repeated computation.\n    /// </remarks>\n    /// <param name=\"schedule\">Scheduler strategy for repeating</param>\n    /// <param name=\"predicate\">Keep repeating until this predicate returns `true` for each computed value</param>\n    /// <returns>The result of the last invocation</returns>\n    public static virtual K<M, A> RepeatUntilIO<A>(\n        K<M, A> ma,\n        Schedule schedule,\n        Func<A, bool> predicate) =>\n        M.MapIO(ma, io => io.RepeatUntil(schedule, predicate));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Retrying the effect when it fails\n    //\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will retry forever\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public static virtual K<M, A> RetryIO<A>(K<M, A> ma) =>\n        M.MapIO(ma, io => io.Retry());\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will retry until the schedule expires\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public static virtual K<M, A> RetryIO<A>(\n        K<M, A> ma,\n        Schedule schedule) =>\n        M.MapIO(ma, io => io.Retry(schedule));\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n    /// at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public static virtual K<M, A> RetryWhileIO<A>(\n        K<M, A> ma,\n        Func<Error, bool> predicate) =>\n        M.MapIO(ma, io => io.RetryWhile(predicate));\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying whilst the predicate returns `true` for the error generated at each iteration;\n    /// or, until the schedule expires; at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public static virtual K<M, A> RetryWhileIO<A>(\n        K<M, A> ma,\n        Schedule schedule,\n        Func<Error, bool> predicate) =>\n        M.MapIO(ma, io => io.RetryWhile(schedule, predicate));\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n    /// at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public static virtual K<M, A> RetryUntilIO<A>(\n        K<M, A> ma,\n        Func<Error, bool> predicate) =>\n        M.MapIO(ma, io => io.RetryUntil(predicate));\n\n    /// <summary>\n    /// Retry if the IO computation fails \n    /// </summary>\n    /// <remarks>\n    /// This variant will keep retrying until the predicate returns `true` for the error generated at each iteration;\n    /// or, until the schedule expires; at which point the last raised error will be thrown.\n    /// </remarks>\n    /// <remarks>\n    /// Any resources acquired within a retrying IO computation will automatically be released *if* the operation fails.\n    /// So, successive retries will not grow the acquired resources on each retry iteration.  Any successful operation that\n    /// acquires resources will have them tracked in the usual way. \n    /// </remarks>\n    public static virtual K<M, A> RetryUntilIO<A>(\n        K<M, A> ma,\n        Schedule schedule,\n        Func<Error, bool> predicate) =>\n        M.MapIO(ma, io => io.RetryUntil(schedule, predicate));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    // \n    //  Folding\n    //\n\n    public static virtual K<M, S> FoldIO<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder) =>\n        M.MapIO(ma, io => io.Fold(schedule, initialState, folder));\n\n    public static virtual K<M, S> FoldIO<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder) =>\n        M.MapIO(ma, io => io.Fold(initialState, folder));\n\n    public static virtual K<M, S> FoldWhileIO<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        M.MapIO(ma, io => io.FoldWhile(schedule, initialState, folder, stateIs));\n\n    public static virtual K<M, S> FoldWhileIO<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        M.MapIO(ma, io => io.FoldWhile(initialState, folder, stateIs));\n\n    public static virtual K<M, S> FoldWhileIO<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        M.MapIO(ma, io => io.FoldWhile(schedule, initialState, folder, valueIs));\n\n    public static virtual K<M, S> FoldWhileIO<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        M.MapIO(ma, io => io.FoldWhile(initialState, folder, valueIs));\n\n    public static virtual K<M, S> FoldWhileIO<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        M.MapIO(ma, io => io.FoldWhile(schedule, initialState, folder, predicate));\n\n    public static virtual K<M, S> FoldWhileIO<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        M.MapIO(ma, io => io.FoldWhile(initialState, folder, predicate));\n\n    public static virtual K<M, S> FoldUntilIO<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        M.MapIO(ma, io => io.FoldUntil(schedule, initialState, folder, stateIs));\n\n    public static virtual K<M, S> FoldUntilIO<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        M.MapIO(ma, io => io.FoldUntil(initialState, folder, stateIs));\n\n    public static virtual K<M, S> FoldUntilIO<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        M.MapIO(ma, io => io.FoldUntil(schedule, initialState, folder, valueIs));\n\n    public static virtual K<M, S> FoldUntilIO<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        M.MapIO(ma, io => io.FoldUntil(initialState, folder, valueIs));\n\n    public static virtual K<M, S> FoldUntilIO<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        M.MapIO(ma, io => io.FoldUntil(initialState, folder, predicate));\n\n    public static virtual K<M, S> FoldUntilIO<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        M.MapIO(ma, io => io.FoldUntil(schedule, initialState, folder, predicate));\n\n\n    static K<M, B> Maybe.MonadUnliftIO<M>.MapIOMaybe<A, B>(K<M, A> ma, Func<IO<A>, IO<B>> f) =>\n        M.MapIO(ma, f);\n\n    static K<M, IO<A>> Maybe.MonadUnliftIO<M>.ToIOMaybe<A>(K<M, A> ma) =>\n        M.ToIO(ma);\n\n    static K<M, ForkIO<A>> Maybe.MonadUnliftIO<M>.ForkIOMaybe<A>(K<M, A> ma, Option<TimeSpan> timeout) =>\n        M.ForkIO(ma, timeout);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.AwaitMaybe<A>(K<M, ForkIO<A>> ma) =>\n        M.Await(ma);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.LocalIOMaybe<A>(K<M, A> ma) =>\n        M.LocalIO(ma);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.PostIOMaybe<A>(K<M, A> ma) =>\n        M.PostIO(ma);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.TimeoutIOMaybe<A>(K<M, A> ma, TimeSpan timeout) =>\n        M.TimeoutIO(ma, timeout);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.BracketIOMaybe<A>(K<M, A> ma) =>\n        M.BracketIO(ma);\n\n    static K<M, C> Maybe.MonadUnliftIO<M>.BracketIOMaybe<A, B, C>(\n        K<M, A> Acq,\n        Func<A, IO<C>> Use,\n        Func<A, IO<B>> Fin) =>\n        M.BracketIO(Acq, Use, Fin);\n\n    static K<M, C> Maybe.MonadUnliftIO<M>.BracketIOMaybe<A, B, C>(\n        K<M, A> Acq,\n        Func<A, IO<C>> Use,\n        Func<Error, IO<C>> Catch,\n        Func<A, IO<B>> Fin) =>\n        M.BracketIO(Acq, Use, Catch, Fin);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RepeatIOMaybe<A>(K<M, A> ma) =>\n        M.RepeatIO(ma);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RepeatIOMaybe<A>(\n        K<M, A> ma,\n        Schedule schedule) =>\n        M.RepeatIO(ma, schedule);   \n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RepeatWhileIOMaybe<A>(\n        K<M, A> ma,\n        Func<A, bool> predicate) =>\n        M.RepeatWhileIO(ma, predicate);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RepeatWhileIOMaybe<A>(\n        K<M, A> ma,\n        Schedule schedule,\n        Func<A, bool> predicate) =>\n        M.RepeatWhileIO(ma, schedule, predicate);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RepeatUntilIOMaybe<A>(\n        K<M, A> ma,\n        Func<A, bool> predicate) =>\n        M.RepeatUntilIO(ma, predicate);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RepeatUntilIOMaybe<A>(\n        K<M, A> ma,\n        Schedule schedule,\n        Func<A, bool> predicate) =>\n        M.RepeatUntilIO(ma, schedule, predicate);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RetryIOMaybe<A>(K<M, A> ma) =>\n        M.RetryIO(ma);  \n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RetryIOMaybe<A>(\n        K<M, A> ma,\n        Schedule schedule) =>\n        M.RetryIO(ma, schedule);   \n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RetryWhileIOMaybe<A>(\n        K<M, A> ma,\n        Func<Error, bool> predicate) =>\n        M.RetryWhileIO(ma, predicate);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RetryWhileIOMaybe<A>(\n        K<M, A> ma,\n        Schedule schedule,\n        Func<Error, bool> predicate) =>\n        M.RetryWhileIO(ma, schedule, predicate);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RetryUntilIOMaybe<A>(\n        K<M, A> ma,\n        Func<Error, bool> predicate) =>\n        M.RetryUntilIO(ma, predicate);\n\n    static K<M, A> Maybe.MonadUnliftIO<M>.RetryUntilIOMaybe<A>(\n        K<M, A> ma,\n        Schedule schedule,\n        Func<Error, bool> predicate) =>\n        M.RetryUntilIO(ma, schedule, predicate);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldIOMaybe<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder) =>\n        M.FoldIO(ma, schedule, initialState, folder);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldIOMaybe<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder) =>\n        M.FoldIO(ma, initialState, folder);   \n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldWhileIOMaybe<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        M.FoldWhileIO(ma, schedule, initialState, folder, stateIs);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldWhileIOMaybe<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        M.FoldWhileIO(ma, initialState, folder, stateIs);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldWhileIOMaybe<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        M.FoldWhileIO(ma, schedule, initialState, folder, valueIs);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldWhileIOMaybe<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        M.FoldWhileIO(ma, initialState, folder, valueIs);   \n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldWhileIOMaybe<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        M.FoldWhileIO(ma, schedule, initialState, folder, predicate);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldWhileIOMaybe<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        M.FoldWhileIO(ma, initialState, folder, predicate);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldUntilIOMaybe<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        M.FoldUntilIO(ma, schedule, initialState, folder, stateIs);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldUntilIOMaybe<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<S, bool> stateIs) =>\n        M.FoldUntilIO(ma, initialState, folder, stateIs);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldUntilIOMaybe<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        M.FoldUntilIO(ma, schedule, initialState, folder, valueIs);\n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldUntilIOMaybe<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<A, bool> valueIs) =>\n        M.FoldUntilIO(ma, initialState, folder, valueIs);  \n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldUntilIOMaybe<S, A>(\n        K<M, A> ma,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        M.FoldUntilIO(ma, initialState, folder, predicate); \n\n    static K<M, S> Maybe.MonadUnliftIO<M>.FoldUntilIOMaybe<S, A>(\n        K<M, A> ma,\n        Schedule schedule,\n        S initialState,\n        Func<S, A, S> folder,\n        Func<(S State, A Value), bool> predicate) =>\n        M.FoldUntilIO(ma, schedule, initialState, folder, predicate);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monads/README.md",
    "content": "### Why do we even need monads?\n\n* Monads _encapsulate impure side effects and other effects_, making them pure.\n* Monads allow sequencing of operations without resorting to statements.\n* Monads (with LINQ) allow us to write _pure_ code that looks a lot like statements in imperative code.\n* Monads de-clutter your code making it more declarative. \n\n> **Quite simply**: _Monads are the 'statements' of pure functional programming and they encapsulate messy boilerplate and side-effects._\n\nFor a deeper dive into the 'why?' of monads, then check out [Paul Louth's Higher-Kinds series](https://paullouth.com/higher-kinds-in-csharp-with-language-ext-part-7-monads/).  \n\n* [Monad](Monad) is the home of the main `Monad<M>` trait as well as its extension methods and `Monad` module type.\n* [MonadIO](MonadIO) has the IO variant of the monad that allows lifting of the `IO<A>` monad into a monad-transformer stack.\n* [MonadT](MonadT) has the `MonadT<T, M>` monad-transformer trait, it allows the lifting of a monad `M` into a monad-transformer `T`. "
  },
  {
    "path": "LanguageExt.Core/Traits/Monoid/Monoid.Instance.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Contains the trait in record form.  This allows the trait to be passed\n/// around as a value rather than resolved as a type.  It helps us get around limitations\n/// in the C# constraint system.\n/// </summary>\n/// <param name=\"Empty\">Identity</param>\n/// <param name=\"Combine\">An associative binary operation.</param>\n/// <typeparam name=\"A\">Trait type</typeparam>\npublic record MonoidInstance<A>(A Empty, Func<A, A, A> Combine) :\n    SemigroupInstance<A>(Combine)\n{\n    /// <summary>\n    /// The `A` type should derive from `Monoid〈A〉`.  If so, we can get a `MonoidInstance〈A〉` that we can\n    /// pass around as a value.  If not, then we will get `None`, which means the type is not a monoid.\n    /// </summary>\n    public new static Option<MonoidInstance<A>> Instance { get; } =\n        // NOTE: I don't like this, but it's the only way I can think of to do ad hoc trait resolution\n        Try.lift(GetInstance)\n           .ToOption()\n           .Bind(x => x is null ? None : Some(x));\n\n    static MonoidInstance<A>? GetInstance()\n    {\n        var type = typeof(Monoid<>).MakeGenericType(typeof(A));\n        var prop = type.GetProperty(\"Instance\");\n        var value = prop?.GetValue(null);\n        return (MonoidInstance<A>?)value;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monoid/Monoid.Prelude.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static class Monoid\n{\n    /// <summary>\n    /// The identity of append\n    /// </summary>\n    [Pure]\n    public static A empty<A>() where A : Monoid<A> =>\n        A.Empty;\n\n    /// <summary>\n    /// Combine two structures\n    /// </summary>\n    [Pure]\n    public static A combine<A>(A x, A y)\n        where A : Monoid<A> =>\n        x.Combine(y);\n\n    /// <summary>\n    /// Fold a list using the monoid.\n    /// </summary>\n    [Pure]\n    public static A combine<A>(A mx, A my, A mz, params A[] xs)\n        where A : Monoid<A> =>\n        xs.AsIterable().Fold(combine(combine(mx, my), mz), combine);\n\n    /// <summary>\n    /// Fold a list using the monoid.\n    /// </summary>\n    [Pure]\n    public static A combine<A>(IEnumerable<A> xs)\n        where A : Monoid<A> =>\n        xs.AsIterable().Fold(A.Empty, combine);\n\n    /// <summary>\n    /// Fold a list using the monoid.\n    /// </summary>\n    [Pure]\n    public static A combine<A>(Seq<A> xs)\n        where A : Monoid<A> =>\n        xs.Fold(A.Empty, combine);\n\n    /// <summary>\n    /// Get a concrete monoid instance value from a monoid supporting trait-type\n    /// </summary>\n    /// <typeparam name=\"A\">Monoid type</typeparam>\n    /// <returns>Monoid instance that can be passed around as a value</returns>\n    [Pure]\n    public static MonoidInstance<A> instance<A>()\n        where A : Monoid<A> =>\n        A.Instance;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Monoid/Monoid.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Monoid trait\n/// <para>\n/// A monoid is a type with an identity and an associative binary operation.\n/// </para>\n/// </summary>\n/// <typeparam name=\"A\">The type being described as a monoid</typeparam>\npublic interface Monoid<A> : Semigroup<A>\n    where A : Monoid<A>\n{\n    /// <summary>\n    /// Identity\n    /// </summary>\n    [Pure]\n    public static abstract A Empty { get; }\n\n    /// <summary>\n    /// Property that contains the trait in record form.  This allows the trait to be passed\n    /// around as a value rather than resolved as a type.  It helps us get around limitations\n    /// in the C# constraint system.\n    /// </summary>\n    public new static virtual MonoidInstance<A> Instance { get; } =\n        new (Empty: A.Empty, Combine: Semigroup.combine);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/MonoidK/MonoidK.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A monoid on applicative functors\n/// </summary>\n/// <typeparam name=\"F\">Applicative functor</typeparam>\npublic static class MonoidKExtensions\n{\n    /// <summary>\n    /// Results in Empty if the predicate results in `false` \n    /// </summary>\n    public static K<M, A> Filter<M, A>(this K<M, A> ma, Func<A, bool> predicate)\n        where M : MonoidK<M>, Monad<M> =>\n        M.Bind(ma, a => predicate(a) ? M.Pure(a) : M.Empty<A>());\n    \n    /// <summary>\n    /// Results in Empty if the predicate results in `false` \n    /// </summary>\n    public static K<M, A> Where<M, A>(this K<M, A> ma, Func<A, bool> predicate)\n        where M : MonoidK<M>, Monad<M> =>\n        M.Bind(ma, a => predicate(a) ? M.Pure(a) : M.Empty<A>());\n\n    /// <summary>\n    /// Chooses whether an element of the structure should be propagated through and if so\n    /// maps the resulting value at the same time. \n    /// </summary>\n    public static K<M, B> Choose<M, A, B>(this K<M, A> ma, Func<A, Option<B>> selector)\n        where M : MonoidK<M>, Monad<M> =>\n        M.Bind(ma, a => selector(a).Match(Some: M.Pure, None: M.Empty<B>));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/MonoidK/MonoidK.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// A monoid on higher-kinds\n/// </summary>\npublic static partial class MonoidK\n{\n    /// <summary>\n    /// Identity\n    /// </summary>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, A> empty<F, A>()\n        where F : MonoidK<F> =>\n        F.Empty<A>();\n\n    /// <summary>\n    /// Associative binary operator\n    /// </summary>\n    [Pure]\n    public static K<F, A> combine<F, A>(K<F, A> ma, K<F, A> mb)\n        where F : MonoidK<F> =>\n        F.Combine(ma, mb);\n\n    /// <summary>\n    /// Fold a list using the monoid.\n    /// </summary>\n    [Pure]\n    public static K<M, A> combine<M, A>(K<M, A> mx, K<M, A> my, K<M, A> mz, params K<M, A>[] xs)\n        where M : MonoidK<M> =>\n        xs.AsIterable().Fold(combine(combine(mx, my), mz), combine);\n\n    /// <summary>\n    /// Fold a list using the monoid.\n    /// </summary>\n    [Pure]\n    public static K<M, A> combine<M, A>(IEnumerable<K<M, A>> xs)\n        where M : MonoidK<M> =>\n        xs.AsIterable().Fold(M.Empty<A>(), combine);\n\n    /// <summary>\n    /// Fold a list using the monoid.\n    /// </summary>\n    [Pure]\n    public static K<M, A> combine<M, A>(Seq<K<M, A>> xs)\n        where M : MonoidK<M> =>\n        xs.Fold(M.Empty<A>(), combine);\n    \n    /// <summary>\n    /// Results in Empty if the predicate results in `false` \n    /// </summary>\n    public static K<M, A> filter<M, A>(K<M, A> ma, Func<A, bool> predicate)\n        where M : MonoidK<M>, Monad<M> =>\n        M.Bind(ma, a => predicate(a) ? M.Pure(a) : M.Empty<A>());\n\n    /// <summary>\n    /// Chooses whether an element of the structure should be propagated through and if so\n    /// maps the resulting value at the same time. \n    /// </summary>\n    public static K<M, B> choose<M, A, B>(K<M, A> ma, Func<A, Option<B>> selector)\n        where M : MonoidK<M>, Monad<M> =>\n        M.Bind(ma, a => selector(a).Match(Some: M.Pure, None: M.Empty<B>));\n    \n    /// <summary>\n    /// Conditional failure of `Alternative` computations. Defined by\n    ///\n    ///     guard(true)  = Applicative.pure\n    ///     guard(false) = Alternative.empty\n    ///\n    /// </summary>\n    /// <param name=\"flag\"></param>\n    /// <typeparam name=\"F\"></typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<F, Unit> guard<F>(bool flag)\n        where F : MonoidK<F>, Applicative<F> =>\n        flag ? Applicative.pure<F, Unit>(default) : empty<F, Unit>();\n}\n\n\n"
  },
  {
    "path": "LanguageExt.Core/Traits/MonoidK/MonoidK.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// A monoid for higher-kinds\n/// </summary>\n/// <typeparam name=\"M\">Higher kind</typeparam>\npublic interface MonoidK<M> : SemigroupK<M>\n    where M : MonoidK<M>\n{\n    /// <summary>\n    /// Identity\n    /// </summary>\n    [Pure]\n    public static abstract K<M, A> Empty<A>();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/MonoidK/README.md",
    "content": "`MonoidK<F>` inherits `SemigroupK<F>`.\nThe way to think of `MonoidK<F>` is a monoid for higher-kinds (`K<F, A>` types, rather than `A` types).  \n\nWhat that means is that any type that implements the `MonoidK<F>` trait gains an `Empty()` (a 'zero'/identity element ) \nvalue as well as the ability to `Combine` two `K<F, A>` structures together into one.  Many implementations of \n`MonoidK<F>` use `Combine` to catch errors and propagate.  So, if the first `K<F, A>` argument to `Combine` fails, it \nsimply returns the second argument.  If it succeeds, then the result of the first is returned.  This works a bit like \n`null` propagation with the `??` operator.  And while this isn't always how `MonoidK` is implemented, it's useful to know.\n\nThe `MonoidK<F>` trait combines with `Applicative<F>` and `Monad<F>` traits to provide the following default \nfunctionality:\n\n* `Filter` | `filter` - if your type supports `Monad<F>` and `MonoidK<F>` you get free filtering and `Where` LINQ extension\n* `Choose` | `choose` - if your type supports `Monad<F>` and `MonoidK<F>` then `Choose` does filtering and mapping \n* `OneOf` | `oneOf` - takes a collection of `K<F, A>` structures, returns the first one to succeed.\n* `Some` | `some` - evaluates a `K<F, A>` structure repeatedly, collecting the `A` values, until it fails (at least one must succeed). Returns the `K<F, Seq<A>>`\n* `Many` | `many` - evaluates a `K<F, A>` structure repeatedly, collecting the `A` values, until it fails. Returns the `K<F, Seq<A>>`\n* `guard` - conditional failure \n\nSome of these you might recognise from the `Parsec` library.  This completely generalises the concept of alternative \nstructure coalescing. "
  },
  {
    "path": "LanguageExt.Core/Traits/Mutates/Mutates.Module.cs",
    "content": "using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Traits;\n\npublic static class Mutates\n{\n    /// <summary>\n    /// Mutate an atomic value in an environment\n    /// </summary>\n    /// <param name=\"f\">Function to mapping the value atomically</param>\n    /// <typeparam name=\"F\">Readable ＆ Monad trait</typeparam>\n    /// <typeparam name=\"Env\">Environment type</typeparam>\n    /// <typeparam name=\"A\">Type of the value to read from the environment</typeparam>\n    /// <returns>Result of mutation, or original value if the underlying Atom's validator failed</returns>\n    public static K<F, A> mutate<F, Env, A>(Func<A, A> f)\n        where F   : Functor<F>\n        where Env : Mutates<F, A> =>\n        Env.Mutable.Map(m => m.Swap(f));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Mutates/Mutates.Trait.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Makes an atomic value within an environment available for mutation \n/// </summary>\n/// <typeparam name=\"M\">Structure trait</typeparam>\n/// <typeparam name=\"InnerEnv\">The value extracted from an environment</typeparam>\npublic interface Mutates<in M, InnerEnv> : Has<M, InnerEnv>\n    where M : Functor<M>\n{\n    /// <summary>\n    /// Extracts the `A` from the `Env`, passes it to the `f`\n    /// mapping functions, and then wraps it back up into the generic `M〈Unit〉` type.\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <returns>Mapped value</returns>\n    public static abstract K<M, Atom<InnerEnv>> Mutable { get; }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Natural/CoNatural.Module.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class CoNatural\n{\n    /// <summary>\n    /// Co-natural transformation\n    /// </summary>\n    /// <remarks>\n    /// If functor `map` operations transform the bound-values within the structure, then\n    /// natural-transformations transform the structure itself.\n    /// </remarks>\n    /// <remarks>\n    /// Functors are referenced, because that's the true definition in category-theory, but\n    /// there is no requirement in language-ext for FA or GA to be functors.  It is just typically\n    /// true that FA and GA will also be functors.\n    /// </remarks>\n    /// <param name=\"fa\">Functor to transform</param>\n    /// <typeparam name=\"F\">Source functor type</typeparam>\n    /// <typeparam name=\"G\">Target functor type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Transformed functor</returns>\n    public static K<F, A> transform<F, G, A>(K<G, A> fa)\n        where F : CoNatural<F, G> =>\n        F.CoTransform(fa);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Natural/CoNatural.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Natural transformation \n/// </summary>\n/// <remarks>\n/// If functor `map` operations transform the bound-values within the structure, then\n/// natural-transformations transform the structure itself.\n/// </remarks>\n/// <remarks>\n/// Functors are referenced, because that's the true definition in category-theory, but\n/// there is no requirement in language-ext for FA or GA to be functors.  It is just typically\n/// true that FA and GA will also be functors.\n/// </remarks>\n/// <typeparam name=\"F\">From functor</typeparam>\n/// <typeparam name=\"G\">To functor</typeparam>\npublic interface CoNatural<in F, out G>\n{\n    /// <summary>\n    /// Perform a natural transformation from `FA -> GA`\n    /// </summary>\n    /// <remarks>\n    /// If functor `map` operations transform the bound-values within the structure, then\n    /// natural-transformations transform the structure itself.\n    /// </remarks>\n    /// <remarks>\n    /// Functors are referenced, because that's the true definition in category-theory, but\n    /// there is no requirement in language-ext for FA or GA to be functors.  It is just typically\n    /// true that FA and GA will also be functors.\n    /// </remarks>\n    /// <param name=\"fa\">Functor to transform</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Transformed functor</returns>\n    public static abstract K<F, A> CoTransform<A>(K<G, A> fa);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Natural/Natural.Module.cs",
    "content": "namespace LanguageExt.Traits;\n\npublic static class Natural\n{\n    /// <summary>\n    /// Natural transformation\n    /// </summary>\n    /// <remarks>\n    /// If functor `map` operations transform the bound-values within the structure, then\n    /// natural-transformations transform the structure itself.\n    /// </remarks>\n    /// <remarks>\n    /// Functors are referenced, because that's the true definition in category-theory, but\n    /// there is no requirement in language-ext for FA or GA to be functors.  It is just typically\n    /// true that FA and GA will also be functors.\n    /// </remarks>\n    /// <param name=\"fa\">Functor to transform</param>\n    /// <typeparam name=\"F\">Source functor type</typeparam>\n    /// <typeparam name=\"G\">Target functor type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Transformed functor</returns>\n    public static K<G, A> transform<F, G, A>(K<F, A> fa)\n        where F : Natural<F, G> =>\n        F.Transform(fa);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Natural/Natural.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Natural transformation \n/// </summary>\n/// <remarks>\n/// If functor `map` operations transform the bound-values within the structure, then\n/// natural-transformations transform the structure itself.\n/// </remarks>\n/// <remarks>\n/// Functors are referenced, because that's the true definition in category-theory, but\n/// there is no requirement in language-ext for FA or GA to be functors.  It is just typically\n/// true that FA and GA will also be functors.\n/// </remarks>\n/// <typeparam name=\"F\">From functor</typeparam>\n/// <typeparam name=\"G\">To functor</typeparam>\npublic interface Natural<out F, in G>\n{\n    /// <summary>\n    /// Perform a natural transformation from `FA -> GA`\n    /// </summary>\n    /// <remarks>\n    /// If functor `map` operations transform the bound-values within the structure, then\n    /// natural-transformations transform the structure itself.\n    /// </remarks>\n    /// <remarks>\n    /// Functors are referenced, because that's the true definition in category-theory, but\n    /// there is no requirement in language-ext for FA or GA to be functors.  It is just typically\n    /// true that FA and GA will also be functors.\n    /// </remarks>\n    /// <param name=\"fa\">Functor to transform</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Transformed functor</returns>\n    public static abstract K<G, A> Transform<A>(K<F, A> fa);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Natural/NaturalEpi.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Natural epimorphic transformation \n/// </summary>\n/// <remarks>\n/// Epimorphism is the dual of monomorphism.  So, `NaturalEpi` is the dual of `NaturalMono`. \n/// </remarks>\n/// <remarks>\n/// Functors are referenced, because that's the true definition in category-theory, but\n/// there is no requirement in language-ext for FA or GA to be functors.  It is just typically\n/// true that FA and GA will also be functors.\n/// </remarks>\n/// <typeparam name=\"F\">From functor</typeparam>\n/// <typeparam name=\"G\">To functor</typeparam>\npublic interface NaturalEpi<in F, out G> : CoNatural<F, G>, Natural<G, F>\n    where F : CoNatural<F, G> \n{\n    static K<F, A> Natural<G, F>.Transform<A>(K<G, A> fa) => \n        F.CoTransform(fa);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Natural/NaturalIso.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Natural isomorphism\n/// </summary>\n/// <typeparam name=\"F\">Functor</typeparam>\n/// <typeparam name=\"G\">Functor</typeparam>\npublic interface NaturalIso<F, G> : \n    Natural<F, G>, \n    CoNatural<F, G>;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Natural/NaturalMono.cs",
    "content": "namespace LanguageExt.Traits;\n\n/// <summary>\n/// Natural monomorphic transformation \n/// </summary>\n/// <remarks>\n/// Monomorphism means that there's one arrow between `F` and `G`.  Therefore, there's also a `CoNatural` between\n/// `G` and `F` (`CoNatural` is the dual of `Natural`, so its arrows are flipped, so a `CoNatural` between `G` and `F`\n/// is isomorphic to a `Natural` between `F` and `G`).  That's why `NaturalMono` derives from both `Natural` and\n/// `CoNatural` and can provide a default implementation for `CoTransform`.\n/// </remarks>\n/// <remarks>\n/// This type wouldn't need to exist is C# was better at type-unification.   Use this when you want a unidirectional\n/// natural-transformation.  Use `NaturalIso` when you want a bidirectional natural-transformation.\n/// </remarks>\n/// <remarks>\n/// Functors are referenced, because that's the true definition in category-theory, but\n/// there is no requirement in language-ext for FA or GA to be functors.  It is just typically\n/// true that FA and GA will also be functors.\n/// </remarks>\n/// <typeparam name=\"F\">From functor</typeparam>\n/// <typeparam name=\"G\">To functor</typeparam>\npublic interface NaturalMono<out F, in G> : Natural<F, G>, CoNatural<G, F>\n    where F : Natural<F, G> \n{\n    static K<G, A> CoNatural<G, F>.CoTransform<A>(K<F, A> fa) => \n        F.Transform(fa);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Natural/README.md",
    "content": "## Natural transformations\n\nNatural transformations are operations that transform the _structure_ of a type.  If `Functor` is \n_structure **preserving**_ then natural-transformations are _structure **transforming**_.\n\nA concrete example is that if we call `Map` on a `Seq〈A〉`, then the structure (the `Seq`) is \npreserved, but the values within the structure, `A`, are transformed: and that defines a `Functor`,\nwhereas with natural-transformations we could call `AsEnumerable()` on the `Seq〈A〉`.  The result\nwould preserve value-type, `A`, but transform the structure `Seq` to `IEnumerable`.\n\nThis common pattern of structure transformation is a natural-transformation. It is captured by the type `Natural〈F, G〉`.\n\n## `Natural`\n\n`Natural〈F, G〉` defines a single method, `Transform`, that maps a `K<F, A>` to a `K<G, A>`.  This could be `K<Try, A>` \nto `K<Option, A>` for example.\n\n## `CoNatural`\n\nThere is also `CoNatural〈F, G〉` which is the dual of `Natural〈F, G〉`.  It has the `Transform` arrow reversed, which \nmeans it maps a `K<G, A>` to a `K<F, A>`.\n\nIt is _functionally exactly the same_ as `Natural`.  The reason it exists is listed below.\n\n## `NaturalIso`\n\nA natural-isomorphism (`NaturalIso〈F, G〉`) is a natural-transformation that can map forwards and backwards:\n\n    F〈A〉-> G〈A〉\n\nAnd the dual:\n\n    G〈A〉-> F〈A〉\n\n`NaturalIso` derives from:\n\n    Natural〈F, G〉\n    CoNatural〈F, G〉\n\n> The reason it doesn't derive from `Natural〈F, G〉` and `Natural〈G, F〉` is because C# can't type-check when `F == G` and\nso the dual needs a separate type: `CoNatural〈F, G〉`.\n\n## `NaturalMono`\n\nA natural _monomorphic_ transformation means there's one arrow between `F` and `G`.  Therefore, there's also a `CoNatural` \nbetween `G` and `F` (`CoNatural` is the dual of `Natural`, so its arrows are flipped, so a `CoNatural` between `G` and `F`\nis isomorphic to a `Natural` between `F` and `G`).\n\n`NaturalMono` derives from:\n\n    Natural〈F, G〉\n    CoNatural〈G, F〉\n\nThe `CoTransform` method has a default implementation.\n\n## `NaturalEpi`\n\nAn _epimorphism_ is the _dual_ of a _monomorphism_.  So, `NaturalEpi` is the dual of `NaturalMono`.  \n\n`NaturalEpi` derives from:\n\n    Natural〈G, F〉\n    CoNatural〈F, G〉\n\nThe `Transform` method has a default implementation.\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Num/Num.Prelude.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Trait\n{\n    /// <summary>\n    /// Divide two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static A divide<NUM, A>(A x, A y) where NUM : Num<A> =>\n        NUM.Divide(x, y);\n\n\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static A abs<NUM, A>(A x) where NUM : Num<A> =>\n        NUM.Abs(x);\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static A signum<NUM, A>(A x) where NUM : Num<A> =>\n        NUM.Signum(x);\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static A fromInteger<NUM, A>(int x) where NUM : Num<A> =>\n        NUM.FromInteger(x);\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static A fromDecimal<NUM, A>(decimal x) where NUM : Num<A> =>\n        NUM.FromDecimal(x);\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static A fromFloat<NUM, A>(float x) where NUM : Num<A> =>\n        NUM.FromFloat(x);\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static A fromDouble<NUM, A>(double x) where NUM : Num<A> =>\n        NUM.FromDouble(x);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Num/Num.cs",
    "content": "﻿using System.Diagnostics.Contracts;\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Numerical value trait\n/// </summary>\n/// <typeparam name=\"A\">The type for which the number operations are\n/// defined.</typeparam>\n[Trait(\"Num*\")]\npublic interface Num<A> : Ord<A>, Arithmetic<A>\n{\n    /// <summary>\n    /// Find the absolute value of a number\n    /// </summary>\n    /// <param name=\"x\">The value to find the absolute value of</param>\n    /// <returns>The non-negative absolute value of x</returns>\n    [Pure]\n    public static abstract A Abs(A x);\n\n    /// <summary>\n    /// Find the sign of x\n    /// </summary>\n    /// <param name=\"x\">The value to find the sign of</param>\n    /// <returns>-1, 0, or +1</returns>\n    [Pure]\n    public static abstract A Signum(A x);\n\n    /// <summary>\n    /// Generate a numeric value from an integer\n    /// </summary>\n    /// <param name=\"x\">The integer to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static abstract A FromInteger(int x);\n\n    /// <summary>\n    /// Generate a numeric value from a decimal\n    /// </summary>\n    /// <param name=\"x\">The decimal to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static abstract A FromDecimal(decimal x);\n\n    /// <summary>\n    /// Generate a numeric value from a float\n    /// </summary>\n    /// <param name=\"x\">The float to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static abstract A FromFloat(float x);\n\n    /// <summary>\n    /// Generate a numeric value from a double\n    /// </summary>\n    /// <param name=\"x\">The double to use</param>\n    /// <returns>The equivalent of x in the Num〈A〉</returns>\n    [Pure]\n    public static abstract A FromDouble(double x);\n\n    /// <summary>\n    /// Divide two numbers\n    /// </summary>\n    /// <param name=\"x\">left hand side of the division operation</param>\n    /// <param name=\"y\">right hand side of the division operation</param>\n    /// <returns>x / y</returns>\n    [Pure]\n    public static abstract A Divide(A x, A y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Ord/Ord.Module.cs",
    "content": "﻿using LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic static partial class Ord\n{\n    /// <summary>\n    /// Returns true if x is greater than y\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>True if x is greater than y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool greaterThan<A>(A x, A y) where A : Ord<A> =>\n        A.Compare(x, y) > 0;\n\n    /// <summary>\n    /// Returns true if x is greater than or equal to y\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>True if x is greater than or equal to y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool greaterOrEq<A>(A x, A y) where A : Ord<A> =>\n        A.Compare(x, y) >= 0;\n\n    /// <summary>\n    /// Returns true if x is less than y\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>True if x is less than y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool lessThan<A>(A x, A y) where A : Ord<A> =>\n        A.Compare(x, y) < 0;\n\n    /// <summary>\n    /// Returns true if x is less than or equal to y\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>True if x is less than or equal to y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool lessOrEq<A>(A x, A y) where A : Ord<A> =>\n        A.Compare(x, y) <= 0;\n\n    /// <summary>\n    /// Compare one item to another to ascertain ordering\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>\n    ///  0 if x is equal to y\n    /// -1 if x greater than y\n    ///  1 if x less than y\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int compare<A>(A x, A y) where A : Ord<A> =>\n        A.Compare(x, y);\n\n    /// <summary>\n    /// Find the maximum value between any two values\n    /// </summary>\n    /// <param name=\"x\">First value</param>\n    /// <param name=\"y\">Second value</param>\n    /// <returns>When ordering the two values in ascending order, this is the last of those</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static A max<OrdA, A>(A x, A y) where OrdA : Ord<A> =>\n        OrdA.Compare(x, y) > 0\n            ? x\n            : y;\n\n    /// <summary>\n    /// Find the minimum value between any two values\n    /// </summary>\n    /// <param name=\"x\">First value</param>\n    /// <param name=\"y\">Second value</param>\n    /// <returns>When ordering the two values in ascending order, this is the first of those</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static A min<OrdA, A>(A x, A y) where OrdA : Ord<A> =>\n        OrdA.Compare(x, y) < 0\n            ? x\n            : y;\n\n    /// <summary>\n    /// Find the minimum value between a set of values\n    /// </summary>\n    /// <param name=\"x\">First value</param>\n    /// <param name=\"y\">Second value</param>\n    /// <param name=\"tail\">Remaining values</param>\n    /// <returns>When ordering the values in ascending order, this is the first of those</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static A min<OrdA, A>(A x, params A[] tail) where OrdA : Ord<A>\n    {\n        var min = x;\n        foreach (var v in tail)\n        {\n            if (OrdA.Compare(v, x) < 0)\n            {\n                min = v;\n            }\n        }\n        return min;\n    }\n\n    /// <summary>\n    /// Find the maximum value between a set of values\n    /// </summary>\n    /// <param name=\"x\">First value</param>\n    /// <param name=\"y\">Second value</param>\n    /// <param name=\"tail\">Remaining values</param>\n    /// <returns>When ordering the values in ascending order, this is the last of those</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static A max<OrdA, A>(A x, params A[] tail) where OrdA : Ord<A>\n    {\n        var max = x;\n        foreach (var v in tail)\n        {\n            if (OrdA.Compare(v, x) > 0)\n            {\n                max = v;\n            }\n        }\n        return max;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Ord/Ord.Prelude.cs",
    "content": "﻿using LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Returns true if x is greater than y\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>True if x is greater than y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool greaterThan<ORD, A>(A x, A y) where ORD : Ord<A> =>\n        ORD.Compare(x, y) > 0;\n\n    /// <summary>\n    /// Returns true if x is greater than or equal to y\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>True if x is greater than or equal to y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool greaterOrEq<ORD, A>(A x, A y) where ORD : Ord<A> =>\n        ORD.Compare(x, y) >= 0;\n\n    /// <summary>\n    /// Returns true if x is less than y\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>True if x is less than y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool lessThan<ORD, A>(A x, A y) where ORD : Ord<A> =>\n        ORD.Compare(x, y) < 0;\n\n    /// <summary>\n    /// Returns true if x is less than or equal to y\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>True if x is less than or equal to y</returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static bool lessOrEq<ORD, A>(A x, A y) where ORD : Ord<A> =>\n        ORD.Compare(x, y) <= 0;\n\n    /// <summary>\n    /// Compare one item to another to ascertain ordering\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>\n    ///  0 if x is equal to y\n    /// -1 if x greater than y\n    ///  1 if x less than y\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int compare<ORD, A>(A x, A y) where ORD : Ord<A> =>\n        ORD.Compare(x, y);\n\n    /// <summary>\n    /// Compare one item to another to ascertain ordering\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>\n    ///  0 if x is equal to y\n    /// -1 if x greater than y\n    ///  1 if x less than y\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int compare<ORD, A>(Option<A> x, Option<A> y) where ORD : Ord<A> =>\n        x.CompareTo<ORD>(y);\n\n    /// <summary>\n    /// Compare one item to another to ascertain ordering\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>\n    ///  0 if x is equal to y\n    /// -1 if x greater than y\n    ///  1 if x less than y\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int compare<ORDA, ORDB, A, B>(Either<A, B> x, Either<A, B> y)\n        where ORDA : Ord<A>\n        where ORDB : Ord<B> =>\n        x.CompareTo<ORDA, ORDB>(y);\n\n    /// <summary>\n    /// Compare one item to another to ascertain ordering\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>\n    ///  0 if x is equal to y\n    /// -1 if x greater than y\n    ///  1 if x less than y\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int compare<ORDA, ORDB, A, B>(Validation<A, B> x, Validation<A, B> y)\n        where A : Monoid<A>\n        where ORDA : Ord<A>, Eq<A>\n        where ORDB : Ord<B> =>\n        x.CompareTo<ORDA, ORDB>(y);\n\n    /// <summary>\n    /// Compare one item to another to ascertain ordering\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>\n    ///  0 if x is equal to y\n    /// -1 if x greater than y\n    ///  1 if x less than y\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int compare<ORD, A>(A[] x, A[] y)\n        where ORD : Ord<A> =>\n        OrdArray<ORD, A>.Compare(x, y);\n\n    /// <summary>\n    /// Compare one item to another to ascertain ordering\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>\n    ///  0 if x is equal to y\n    /// -1 if x greater than y\n    ///  1 if x less than y\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int compare<ORD, A>(Lst<A> x, Lst<A> y)\n        where ORD : Ord<A> =>\n        OrdLst<ORD, A>.Compare(x, y);\n\n    /// <summary>\n    /// Compare one item to another to ascertain ordering\n    /// </summary>\n    /// <param name=\"x\">The first item to compare</param>\n    /// <param name=\"y\">The second item to compare</param>\n    /// <returns>\n    ///  0 if x is equal to y\n    /// -1 if x greater than y\n    ///  1 if x less than y\n    /// </returns>\n    [Pure]\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static int compare<ORD, L, R>(Either<L, R> x, Either<L, R> y) where ORD : Ord<R> =>\n        x.CompareTo<ORD>(y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Ord/Ord.cs",
    "content": "﻿using LanguageExt.Attributes;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\n[Trait(\"Ord*\")]\npublic interface Ord<in A> : Eq<A> \n{\n    /// <summary>\n    /// Compare two values\n    /// </summary>\n    /// <param name=\"x\">Left hand side of the compare operation</param>\n    /// <param name=\"y\">Right hand side of the compare operation</param>\n    /// <returns>\n    /// if x greater than y : 1\n    /// \n    /// if x less than y    : -1\n    /// \n    /// if x equals y       : 0\n    /// </returns>\n    [Pure]\n    public static abstract int Compare(A x, A y);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Ord/OrdComparer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Hosts a standard .NET `IComparer` from an `Ord〈A〉` instance (in the static `Default` property)\n/// </summary>\npublic class OrdComparer<OrdA, A> : IComparer<A> where OrdA : Ord<A>\n{\n    public static readonly IComparer<A> Default = new OrdComparer<OrdA, A>(); \n\n    public int Compare(A? x, A? y) =>\n        (x, y) switch\n        {\n            (null, null) => 0,\n            (null, _)    => -1,\n            (_, null)    => 1,\n            var (x1, y1) => OrdA.Compare(x1, y1)\n        };\n}\n\ninternal class OrdComparer<A>(Func<A, A, int> Comparer) : IComparer<A>\n{\n    public int Compare(A? x, A? y) =>\n        (x, y) switch\n        {\n            (null, null) => 0,\n            (null, _)    => -1,\n            (_, null)    => 1,\n            var (x1, y1) => Comparer(x1, y1)\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Predicate/Predicate.cs",
    "content": "﻿#nullable enable\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Attributes;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Predicate trait\n/// </summary>\n/// <typeparam name=\"A\">Type of value to run the predication operation against</typeparam>\n[Trait(\"Pred*\")]\npublic interface Pred<in A> : Trait\n{\n    /// <summary>\n    /// The predicate operation.  Returns true if the source value\n    /// fits the predicate.\n    /// </summary>\n    /// <param name=\"value\"></param>\n    /// <returns></returns>\n    [Pure]\n    public static abstract bool True(A value);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/README.md",
    "content": "A recent C# feature is `static` interface members – this opens up some new possibilities for bending C# to make trait like functionality work.  You may have already seen the technique:\n\n```c#\npublic interface Addable<SELF> where SELF : Addable<SELF>\n{\n    public static abstract SELF Add(SELF x, SELF y);\n}\n```\n\nNote, how the Add member is `static abstract` and that the interface has a constraint that `SELF` is forced to inherit `Addable<SELF>`.\n\nWe can then create two distinct types that inherit the Addable trait:\n\n```c#\npublic record MyList<A>(A[] values) : Addable<MyList<A>>\n{\n    public static MyList<A> Add(MyList<A> x, MyList<A> y) =>\n        new (x.values.Append(y.values).ToArray());\n}\n\npublic record MyString(string value) : Addable<MyString>\n{\n    public static MyString Add(MyString x, MyString y) =>\n        new (x.value + y.value);\n}\n```\n\nLanguage-Ext takes this idea and uses it to implement 'higher-kinded traits' (with the `K<F, A>` type being the anchor for \nthem all).  \n\nTo continue reading about how this works, check out [Paul Louth's Higher-Kinds series](https://paullouth.com/higher-kinds-in-c-with-language-ext/). \n\n \n"
  },
  {
    "path": "LanguageExt.Core/Traits/Range/Range.Trait.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits.Range;\n\npublic interface Range<SELF, NumOrdA, A> : IEnumerable<A>, K<SELF, A>\n    where SELF : Range<SELF, NumOrdA, A>\n    where NumOrdA : Ord<A>, Num<A>\n{\n    public static abstract SELF New(A from, A to, A step);\n\n    /// <summary>\n    /// Zero range \n    /// </summary>\n    public static readonly SELF Zero = \n        FromMinMax(NumOrdA.FromInteger(0), NumOrdA.FromInteger(0), NumOrdA.FromInteger(0));\n\n    /// <summary>\n    /// First value in the range\n    /// </summary>\n    [Pure]\n    public A From { get; }\n\n    /// <summary>\n    /// Last (inclusive) value in the range\n    /// </summary>\n    [Pure]\n    public A To { get; }\n\n    /// <summary>\n    /// Step size to the next item in the range\n    /// </summary>\n    [Pure]\n    public A Step { get; }\n\n    /// <summary>\n    /// True if adding `Step` to `n` makes the resulting value greater than `n`\n    /// </summary>\n    [Pure]\n    public bool StepIsAscending => \n        NumOrdA.Compare(NumOrdA.Add(From, Step), From) >= 0;\n\n    /// <summary>\n    /// Reference version for use in pattern-matching\n    /// </summary>\n    [Pure]\n    public object? Case =>\n        Prelude.Seq(this).Case;\n\n    /// <summary>\n    /// Construct a new range\n    /// </summary>\n    /// <param name=\"from\">The minimum value in the range</param>\n    /// <param name=\"to\">The maximum value in the range</param>\n    /// <param name=\"step\">The size of each step in the range</param>\n    [Pure]\n    public static SELF FromMinMax(A min, A max, A step) =>\n        SELF.New(min, max, step);\n\n    /// <summary>\n    /// Construct a new range\n    /// </summary>\n    /// <param name=\"from\">The minimum value in the range</param>\n    /// <param name=\"count\">The number of items in the range</param>\n    /// <param name=\"step\">The size of each step in the range</param>\n    [Pure]\n    public static SELF FromCount(A min, A count, A step) =>\n        SELF.New(min, NumOrdA.Add(min, NumOrdA.Subtract(NumOrdA.Multiply(count, step), step)), step);\n\n    /// <summary>\n    /// Returns true if the value provided is in range\n    /// </summary>\n    /// <param name=\"value\">Value to test</param>\n    /// <returns>True if the value provided is in range</returns>\n    [Pure]\n    public bool InRange(A value)\n    {\n        var from = NumOrdA.Compare(From, To) > 0 ? To : From;\n        var to   = NumOrdA.Compare(From, To) > 0 ? From : To;\n\n        return NumOrdA.Compare(value, from) >= 0 &&\n               NumOrdA.Compare(value, to)   <= 0;\n    }\n\n    /// <summary>\n    /// Returns true if the range provided overlaps this range\n    /// </summary>\n    /// <param name=\"other\">The range to test</param>\n    /// <returns>True if the range provided overlaps this range</returns>\n    [Pure]\n    public bool Overlaps(SELF other)\n    {\n        var xfrom = NumOrdA.Compare(From, To)             > 0 ? To : From;\n        var xto   = NumOrdA.Compare(From, To)             > 0 ? From : To;\n        var yfrom = NumOrdA.Compare(other.From, other.To) > 0 ? other.To : other.From;\n        var yto   = NumOrdA.Compare(other.From, other.To) > 0 ? other.From : other.To;\n\n        return NumOrdA.Compare(xfrom, yto) < 0 &&\n               NumOrdA.Compare(yfrom, xto) < 0;\n    }\n\n    [Pure]\n    public Seq<A> ToSeq() =>\n        Prelude.toSeq(AsIterable());\n\n    [Pure]\n    public Iterable<A> AsIterable()\n    {\n        return Iterable.createRange(Go());\n        IEnumerable<A> Go()\n        {\n            if (StepIsAscending)\n            {\n                for (A x = From; NumOrdA.Compare(x, To) <= 0; x = NumOrdA.Add(x, Step))\n                {\n                    yield return x;\n                }\n            }\n            else\n            {\n                for (A x = From; NumOrdA.Compare(x, To) >= 0; x = NumOrdA.Add(x, Step))\n                {\n                    yield return x;\n                }\n            }\n        }\n    }\n\n    [Pure]\n    IEnumerator<A> IEnumerable<A>.GetEnumerator() => \n        // ReSharper disable once NotDisposedResourceIsReturned\n        AsIterable().GetEnumerator();\n\n    [Pure]\n    IEnumerator IEnumerable.GetEnumerator() =>\n        AsIterable().GetEnumerator();\n\n    [Pure]\n    public S Fold<S>(S state, Func<S, A, S> f)\n    {\n        foreach(var x in AsIterable())\n        {\n            state = f(state, x);\n        }\n        return state;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Readable/Readable.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class ReadableExtensions\n{\n    public static K<M, A> Local<M, Env, A>(this K<M, A> ma, Func<Env, Env> f)\n        where M : Readable<M, Env> =>\n        M.Local(f, ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Readable/Readable.Module.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Traits;\n\npublic static class Readable\n{\n    public static K<M, Env> ask<M, Env>()\n        where M : Readable<M, Env> =>\n        M.Ask;\n\n    public static K<M, A> asks<M, Env, A>(Func<Env, A> f)\n        where M : Readable<M, Env> =>\n        M.Asks(f);\n\n    public static K<M, A> asksM<M, Env, A>(Func<Env, K<M, A>> f)\n        where M : Readable<M, Env>, Monad<M> =>\n        M.Flatten(M.Asks(f));\n\n    public static K<M, A> local<M, Env, A>(Func<Env, Env> f, K<M, A> ma)\n        where M : Readable<M, Env> =>\n        M.Local(f, ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Readable/Readable.Prelude.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// Retrieves the reader monad environment.\n    /// </summary>\n    /// <typeparam name=\"Env\">Environment</typeparam>\n    /// <returns>Reader monad with the environment in as the bound value</returns>\n    [Pure]\n    public static Ask<Env, Env> ask<Env>() =>\n        new(identity);\n\n    /// <summary>\n    /// Retrieves a function of the current environment.\n    /// </summary>\n    /// <typeparam name=\"Env\">Environment</typeparam>\n    /// <typeparam name=\"A\">Bound and mapped value type</typeparam>\n    /// <returns>Reader monad with the mapped environment in as the bound value</returns>\n    [Pure]\n    public static Ask<Env, A> asks<Env, A>(Func<Env, A> f) =>\n        new(f);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Readable/Readable.Trait.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Traits;\n\npublic interface Readable<M, Env>\n    where M : Readable<M, Env>\n{\n    public static abstract K<M, A> Asks<A>(Func<Env, A> f);\n\n    public static virtual K<M, Env> Ask =>\n        M.Asks(Prelude.identity);\n\n    public static abstract K<M, A> Local<A>(\n        Func<Env, Env> f,\n        K<M, A> ma);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Resolve/EqResolver.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Reflection;\n\nnamespace LanguageExt.Traits.Resolve;\n\npublic static class EqResolve<A>\n{\n    public static string? ResolutionError;\n\n    public static Func<A, int> GetHashCodeFunc = null!;\n    public static MethodInfo GetHashCodeMethod = null!;\n    public static nint GetHashCodeMethodPtr;\n    \n    public static Func<A, A, bool> EqualsFunc = null!;\n    public static MethodInfo EqualsMethod = null!;\n    public static nint EqualsMethodPtr;\n    \n    public static int GetHashCode(A value) =>\n        GetHashCodeFunc(value);\n\n    public static bool Equals(A lhs, A rhs) =>\n        EqualsFunc(lhs, rhs);\n\n    public static bool Exists => \n        ResolutionError is null;\n\n    static EqResolve()\n    {\n        var source = typeof(A);\n        \n        var impl = Resolver.Find(source, \"Eq\");\n        if (impl is null)\n        {\n            ResolutionError = $\"Trait implementation not found for: {typeof(A).Name}\";\n            MakeDefault();\n            return;\n        }\n        \n        // Equals\n        \n        var m = Resolver.Method(impl, \"Equals\", source, source);\n        if (m is null)\n        {\n            ResolutionError = $\"`Equals` method not found for: {typeof(A).Name}\";\n            MakeDefault();\n            return;\n        }\n\n        EqualsMethod    = m;\n        EqualsMethodPtr = m.MethodHandle.GetFunctionPointer();\n        EqualsFunc      = (x, y) => (bool?)EqualsMethod.Invoke(null, [x, y]) ?? throw new InvalidOperationException();\n        \n        // GetHashCode\n        \n        m = Resolver.Method(impl, \"GetHashCode\", source);\n        if (m is null)\n        {\n            ResolutionError = $\"`GetHashCode` method not found for: {typeof(A).Name}\";\n            MakeDefault();\n            return;\n        }\n\n        GetHashCodeMethod    = m;\n        GetHashCodeMethodPtr = m.MethodHandle.GetFunctionPointer();\n        GetHashCodeFunc      = x => (int?)GetHashCodeMethod.Invoke(null, [x]) ?? throw new InvalidOperationException();\n    }\n\n    static void MakeDefault()\n    {\n        EqualsFunc      = EqualityComparer<A>.Default.Equals;\n        EqualsMethod    = EqualsFunc.Method;\n        EqualsMethodPtr = EqualsFunc.Method.MethodHandle.GetFunctionPointer();\n        \n        GetHashCodeFunc      = DefaultGetHashCode;\n        GetHashCodeMethod    = GetHashCodeFunc.Method;\n        GetHashCodeMethodPtr = GetHashCodeFunc.Method.MethodHandle.GetFunctionPointer();\n    }\n\n    static int DefaultGetHashCode(A value) =>\n        value is null ? 0 : value.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Resolve/HashableResolver.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Reflection;\n\nnamespace LanguageExt.Traits.Resolve;\n\npublic static class HashableResolve<A>\n{\n    public static string? ResolutionError;\n\n    public static Func<A, int> GetHashCodeFunc = null!;\n    public static MethodInfo GetHashCodeMethod = null!;\n    public static nint GetHashCodeMethodPtr;\n\n    public static int GetHashCode(A value) =>\n        GetHashCodeFunc(value);\n\n    public static bool Exists => \n        ResolutionError is null;\n    \n    static HashableResolve()\n    {\n        var source = typeof(A);\n        \n        var impl = Resolver.Find(source, \"Hashable\");\n        if (impl is null)\n        {\n            ResolutionError = $\"Trait implementation not found for: {typeof(A).Name}\";\n            MakeDefault();\n            return;\n        }\n        \n        var m = Resolver.Method(impl, \"GetHashCode\", source);\n        if (m is null)\n        {\n            ResolutionError = $\"`GetHashCode` method not found for: {typeof(A).Name}\";\n            MakeDefault();\n            return;\n        }\n\n        GetHashCodeMethod    = m;\n        GetHashCodeMethodPtr = m.MethodHandle.GetFunctionPointer();\n        GetHashCodeFunc      = x => (int?)GetHashCodeMethod.Invoke(null, [x]) ?? throw new InvalidOperationException();\n    }\n    \n    static void MakeDefault()\n    {\n        GetHashCodeFunc      = DefaultGetHashCode;\n        GetHashCodeMethod    = GetHashCodeFunc.Method;\n        GetHashCodeMethodPtr = GetHashCodeFunc.Method.MethodHandle.GetFunctionPointer();\n    }\n\n    static int DefaultGetHashCode(A value) =>\n        value is null ? 0 : value.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Resolve/OrdResolver.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace LanguageExt.Traits.Resolve;\n\npublic static class OrdResolve<A>\n{\n    public static string? ResolutionError;\n    \n    public static Func<A, int> GetHashCodeFunc = null!;\n    public static MethodInfo GetHashCodeMethod = null!;\n    public static nint GetHashCodeMethodPtr;\n    \n    public static Func<A, A, bool> EqualsFunc = null!;\n    public static MethodInfo EqualsMethod = null!;\n    public static nint EqualsMethodPtr;\n    \n    public static Func<A, A, int> CompareFunc = null!;\n    public static MethodInfo CompareMethod = null!;\n    public static nint CompareMethodPtr;\n    \n    public static int GetHashCode(A value) =>\n        GetHashCodeFunc(value);\n\n    public static bool Equals(A lhs, A rhs) =>\n        EqualsFunc(lhs, rhs);\n\n    public static int Compare(A lhs, A rhs) =>\n        CompareFunc(lhs, rhs);\n\n    public static bool Exists => \n        ResolutionError is null;\n\n    static OrdResolve()\n    {\n        var source = typeof(A);\n\n        if(source.FullName?.StartsWith(\"LanguageExt.Traits.K\") ?? false)\n        {\n            MakeTraitDefault();\n            return;\n        }\n        \n        if (typeof(Delegate).IsAssignableFrom(source))\n        {\n            MakeDelegateDefault();\n            return;\n        }\n\n        MakeComparer(source);\n    }\n    \n    static void MakeComparer(Type source)\n    {\n        var impl = Resolver.Find(source, \"Ord\");\n        if (impl is null)\n        {\n            ResolutionError = $\"Trait implementation not found for: {source.Name}\";\n            MakeDefault();\n            return;\n        }\n        \n        // Compare\n        \n        var m = Resolver.Method(impl, \"Compare\", source, source);\n        if (m is null)\n        {\n            ResolutionError = $\"`Compare` method not found for: {source.Name}\";\n            MakeDefault();\n            return;\n        }\n\n        CompareMethod    = m;\n        CompareMethodPtr = m.MethodHandle.GetFunctionPointer();\n        CompareFunc      = (x, y) => (int?)CompareMethod.Invoke(null, [x, y]) ?? throw new InvalidOperationException();\n\n        // Equals\n        \n        m = Resolver.Method(impl, \"Equals\", source, source);\n        if (m is null)\n        {\n            ResolutionError = $\"`Equals` method not found for: {source.Name}\";\n            MakeDefault();\n            return;\n        }\n\n        EqualsMethod    = m;\n        EqualsMethodPtr = m.MethodHandle.GetFunctionPointer();\n        EqualsFunc      = (x, y) => (bool?)EqualsMethod.Invoke(null, [x, y]) ?? throw new InvalidOperationException();\n        \n        // GetHashCode\n        \n        m = Resolver.Method(impl, \"GetHashCode\", source);\n        if (m is null)\n        {\n            ResolutionError = $\"`GetHashCode` method not found for: {source.Name}\";\n            MakeDefault();\n            return;\n        }\n\n        GetHashCodeMethod    = m;\n        GetHashCodeMethodPtr = m.MethodHandle.GetFunctionPointer();\n        GetHashCodeFunc      = x => (int?)GetHashCodeMethod.Invoke(null, [x]) ?? throw new InvalidOperationException();\n    }\n    \n    static void MakeDefault()\n    {\n        CompareFunc      = Comparer<A>.Default.Compare;\n        CompareMethod    = CompareFunc.Method;\n        CompareMethodPtr = CompareFunc.Method.MethodHandle.GetFunctionPointer();\n        \n        EqualsFunc      = EqualityComparer<A>.Default.Equals;\n        EqualsMethod    = EqualsFunc.Method;\n        EqualsMethodPtr = EqualsFunc.Method.MethodHandle.GetFunctionPointer();\n        \n        GetHashCodeFunc      = DefaultGetHashCode;\n        GetHashCodeMethod    = GetHashCodeFunc.Method;\n        GetHashCodeMethodPtr = GetHashCodeFunc.Method.MethodHandle.GetFunctionPointer();\n    }\n\n    static void MakeDelegateDefault()\n    {\n        CompareFunc = (x, y) => ((object?)x, (object?)y) switch\n                                {\n                                    (Delegate dx, Delegate dy) => dx.Method.MetadataToken.CompareTo(dy.Method.MetadataToken),\n                                    _                          => -1\n                                };\n        CompareMethod    = CompareFunc.Method;\n        CompareMethodPtr = CompareFunc.Method.MethodHandle.GetFunctionPointer();\n        \n        EqualsFunc = (x, y) => ((object?)x, (object?)y) switch\n                               {\n                                   (Delegate dx, Delegate dy) => dx.Method.MetadataToken == dy.Method.MetadataToken,\n                                   _                          => false\n                               };\n        EqualsMethod    = EqualsFunc.Method;\n        EqualsMethodPtr = EqualsFunc.Method.MethodHandle.GetFunctionPointer();\n        \n        GetHashCodeFunc      = DefaultGetHashCode;\n        GetHashCodeMethod    = GetHashCodeFunc.Method;\n        GetHashCodeMethodPtr = GetHashCodeFunc.Method.MethodHandle.GetFunctionPointer();\n    }\n\n    static void MakeTraitDefault()\n    {\n        var gens = typeof(A).GetGenericArguments();\n\n        var fname = gens[0].FullName;\n        var tick  = fname?.IndexOf('`') ?? -1; \n        var iname = tick >= 0 ? fname?.Substring(0, tick) ?? \"\" : fname;\n\n        var tgens = gens[0].GetGenericArguments();\n        var gtype = gens[0].Assembly.GetType($\"{iname}`{tgens.Length + 1}\");\n\n        var ngens = tgens.Concat([gens[1]]).ToArray();\n        var type  = gtype!.MakeGenericType(ngens);\n\n        var resolver = typeof(OrdResolve<>).MakeGenericType(type);\n\n        var getHashCodeObj = ((Delegate?)resolver.GetField(\"GetHashCodeFunc\")?.GetValue(null) ?? throw new InvalidOperationException()).Target;\n        var equalsObj      = ((Delegate?)resolver.GetField(\"EqualsFunc\")?.GetValue(null)      ?? throw new InvalidOperationException()).Target;\n        var compareObj     = ((Delegate?)resolver.GetField(\"CompareFunc\")?.GetValue(null)     ?? throw new InvalidOperationException()).Target;\n\n        var getHashCodeMethod = (MethodInfo?)resolver.GetField(\"GetHashCodeMethod\")?.GetValue(null) ?? throw new InvalidOperationException();\n        var equalsMethod      = (MethodInfo?)resolver.GetField(\"EqualsMethod\")?.GetValue(null)      ?? throw new InvalidOperationException();\n        var compareMethod     = (MethodInfo?)resolver.GetField(\"CompareMethod\")?.GetValue(null)     ?? throw new InvalidOperationException();\n\n        GetHashCodeFunc      = x => (int?)getHashCodeMethod.Invoke(getHashCodeObj, [x]) ?? throw new InvalidOperationException(); \n        GetHashCodeMethod    = GetHashCodeFunc.Method;\n        GetHashCodeMethodPtr = GetHashCodeFunc.Method.MethodHandle.GetFunctionPointer();\n        \n        EqualsFunc      = (x, y) => (bool?)equalsMethod.Invoke(equalsObj, [x, y]) ?? throw new InvalidOperationException();\n        EqualsMethod    = EqualsFunc.Method;\n        EqualsMethodPtr = EqualsFunc.Method.MethodHandle.GetFunctionPointer();\n        \n        CompareFunc      = (x, y) => (int?)compareMethod.Invoke(compareObj, [x, y]) ?? throw new InvalidOperationException();\n        CompareMethod    = CompareFunc.Method;\n        CompareMethodPtr = CompareFunc.Method.MethodHandle.GetFunctionPointer();\n    }\n    \n    static int DefaultGetHashCode(A value) =>\n        value is null ? 0 : value.GetHashCode();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Resolve/Resolver.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace LanguageExt.Traits.Resolve;\n\ninternal static class Resolver\n{\n    \n    public static MethodInfo? Method(Type? type, string name, params Type[] types) =>\n        type?.GetMethod(name, BindingFlags.Static | BindingFlags.Public, types);\n    \n    public static Type? Find(Type type, string prefix = \"\")\n    {\n        var n = $\"{prefix}{type.Name}\";\n\n        var t = FindType(type.Assembly, n);\n        if (t is not null) return MakeGeneric(t, type);\n        var typeAsmName = type.Assembly.GetName();\n        \n        foreach (var name in GetAssemblies().Where(asm => asm != typeAsmName))\n        {\n            t = FindType(LoadAssembly(name), n);\n            if (t != null) return MakeGeneric(t, type);\n        }\n        return null;\n    }\n\n    static Type MakeGeneric(Type generic, Type concrete) =>\n        generic.IsGenericType\n            ? generic.MakeGenericType(concrete.GetGenericArguments())\n            : concrete;\n\n    static Type? FindType(Assembly? asm, string name)\n    {\n        if (asm is null) return null;\n        var types = asm.DefinedTypes\n                       .Where(t => t.IsClass || t.IsValueType)\n                       .Where(t => t.Name == name)\n                       .ToArray();\n\n        return types.Length switch\n               {\n                   0 => null,\n                   1 => types[0],\n                   _ => null\n               };\n    }\n\n    static Assembly? LoadAssembly(AssemblyName name)\n    {\n        try\n        {\n            return Assembly.Load(name);\n        }\n        catch\n        {\n            return null;\n        }\n    }\n\n    static IEnumerable<AssemblyName> GetAssemblies()\n    {\n        var asmNames = Assembly.GetExecutingAssembly().GetReferencedAssemblies()\n                               .Concat(Assembly.GetCallingAssembly().GetReferencedAssemblies())\n                               .Concat(Assembly.GetEntryAssembly()?.GetReferencedAssemblies() ?? [])\n                               .Distinct();\n\n        var init = new[]\n                   {\n                       Assembly.GetExecutingAssembly().GetName(),\n                       Assembly.GetCallingAssembly().GetName(),\n                       Assembly.GetEntryAssembly()?.GetName()\n                   };\n\n        foreach (var asm in init.Concat(asmNames).Where(n => n is not null).Distinct())\n        {\n            if (asm is not null) yield return asm;\n        }\n    }\n    \n        public static MethodInfo? GetHashCodeMethod(Type type)\n    {\n        Type[] traits = [typeof(HashableResolve<>), typeof(EqResolve<>), typeof(OrdResolve<>)];\n        foreach (var trait in traits)\n        {\n            var impl   = trait.MakeGenericType(type);\n            var exists = (bool?)impl.GetProperty(\"Exists\")?.GetValue(null) ?? false;\n            if (exists)\n            {\n                var method = impl.GetMethod(\"GetHashCode\", BindingFlags.Static | BindingFlags.Public, [type]);\n                if (method is not null) return method;\n            }\n        }\n        return null;\n    }\n\n    public static MethodInfo GetHashCodeMethodAlways(Type type)\n    {\n        Type[] traits = [typeof(HashableResolve<>), typeof(EqResolve<>), typeof(OrdResolve<>)];\n        foreach (var trait in traits)\n        {\n            var impl   = trait.MakeGenericType(type);\n            var exists = (bool?)impl.GetProperty(\"Exists\")?.GetValue(null) ?? false;\n            if (exists)\n            {\n                var method = impl.GetMethod(\"GetHashCode\", BindingFlags.Static | BindingFlags.Public, [type]);\n                if (method is not null) return method;\n            }\n        }\n        \n        var impl2   = typeof(HashableResolve<>).MakeGenericType(type);\n        return impl2.GetMethod(\"GetHashCode\", BindingFlags.Static | BindingFlags.Public, [type]) ?? throw new InvalidOperationException();\n    }\n\n    public static MethodInfo? GetEqualsMethod(Type type)\n    {\n        Type[] traits = [typeof(EqResolve<>), typeof(OrdResolve<>)];\n        foreach (var trait in traits)\n        {\n            var impl   = trait.MakeGenericType(type);\n            var exists = (bool?)impl.GetProperty(\"Exists\")?.GetValue(null) ?? false;\n            if (exists)\n            {\n                var method = impl.GetMethod(\"Equals\", BindingFlags.Static | BindingFlags.Public, [type, type]);\n                if (method is not null) return method;\n            }\n        }\n        return null;\n    }\n\n    public static MethodInfo GetEqualsMethodAlways(Type type)\n    {\n        Type[] traits = [typeof(EqResolve<>), typeof(OrdResolve<>)];\n        foreach (var trait in traits)\n        {\n            var impl   = trait.MakeGenericType(type);\n            var exists = (bool?)impl.GetProperty(\"Exists\")?.GetValue(null) ?? false;\n            if (exists)\n            {\n                var method = impl.GetMethod(\"Equals\", BindingFlags.Static | BindingFlags.Public, [type, type]);\n                if (method is not null) return method;\n            }\n        }\n        \n        var impl2 = typeof(EqResolve<>).MakeGenericType(type);\n        return impl2.GetMethod(\"Equals\", BindingFlags.Static | BindingFlags.Public, [type, type]) ?? throw new InvalidOperationException();\n    }\n    \n    public static MethodInfo? GetCompareMethod(Type type)\n    {\n        Type[] traits = [typeof(OrdResolve<>)];\n        foreach (var trait in traits)\n        {\n            var impl   = trait.MakeGenericType(type);\n            var exists = (bool?)impl.GetProperty(\"Exists\")?.GetValue(null) ?? false;\n            if (exists)\n            {\n                var method = impl.GetMethod(\"Compare\", BindingFlags.Static | BindingFlags.Public, [type, type]);\n                if (method is not null) return method;\n            }\n        }\n        return null;\n    }    \n    \n    public static MethodInfo GetCompareMethodAlways(Type type)\n    {\n        var impl   = typeof(OrdResolve<>).MakeGenericType(type);\n        var method = impl.GetMethod(\"Compare\", BindingFlags.Static | BindingFlags.Public, [type, type]);\n        return method ?? throw new InvalidOperationException();\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Semigroup/Semigroup.Instance.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Contains the trait in record form.  This allows the trait to be passed\n/// around as a value rather than resolved as a type.  It helps us get around limitations\n/// in the C# constraint system.\n/// </summary>\n/// <param name=\"Combine\">An associative binary operation.</param>\n/// <typeparam name=\"A\">Trait type</typeparam>\npublic record SemigroupInstance<A>(Func<A, A, A> Combine)\n{\n    /// <summary>\n    /// The `A` type should derive from `Semigroup〈A〉`.  If so, we can get a `SemigroupInstance〈A〉` that we can\n    /// pass around as a value.  If not, then we will get `None`, which means the type is not a semigroup.\n    /// </summary>\n    public static Option<SemigroupInstance<A>> Instance { get; } =\n        // NOTE: I don't like this, but it's the only way I can think of to do ad hoc trait resolution\n        Try.lift(GetInstance)\n           .ToOption()\n           .Bind(x => x is null ? None : Some(x));\n    \n    static SemigroupInstance<A>? GetInstance()\n    {\n        var type  = typeof(Semigroup<>).MakeGenericType(typeof(A));\n        var prop  = type.GetProperty(\"Instance\");\n        var value = prop?.GetValue(null);\n        return (SemigroupInstance<A>?)value;\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Semigroup/Semigroup.Module.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Semigroup\n{\n    /// <summary>\n    /// An associative binary operation\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the operation</param>\n    /// <param name=\"y\">The right hand side of the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static A combine<A>(A x, A y) where A : Semigroup<A> =>\n        x + y;\n    \n    /// <summary>\n    /// Get a concrete semigroup instance value from a semigroup supporting trait-type\n    /// </summary>\n    /// <typeparam name=\"A\">Semigroup type</typeparam>\n    /// <returns>Semigroup instance that can be passed around as a value</returns>\n    [Pure]\n    public static SemigroupInstance<A> instance<A>()\n        where A : Semigroup<A> =>\n        A.Instance;    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Semigroup/Semigroup.Operators.cs",
    "content": "using LanguageExt.Traits;\nnamespace LanguageExt;\n\npublic static class SemigroupExtensions\n{\n    extension<A>(A _) \n        where A : Semigroup<A>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static A operator +(A lhs, A rhs) =>\n            lhs.Combine(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Semigroup/Semigroup.Prelude.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// An associative binary operation\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the operation</param>\n    /// <param name=\"y\">The right hand side of the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static A combine<A>(A x, A y) where A : Semigroup<A> =>\n        x + y;\n\n    /// <summary>\n    /// An associative binary operation\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side of the operation</param>\n    /// <param name=\"rhs\">Right-hand side of the operation</param>\n    /// <returns>lhs + rhs</returns>\n    [Pure]\n    public static Either<L, R> combine<L, R>(Either<L, R> lhs, Either<L, R> rhs) \n        where R : Semigroup<R> =>\n        from x in lhs\n        from y in rhs\n        select x + y;\n\n    /// <summary>\n    /// An associative binary operation\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the operation</param>\n    /// <param name=\"y\">The right hand side of the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static Option<A> combine<A>(Option<A> x, Option<A> y) \n        where A : Semigroup<A> =>\n        from a in x\n        from b in y\n        select a + b;\n\n    /// <summary>\n    /// An associative binary operation\n    /// </summary>\n    /// <param name=\"x\">The left hand side of the operation</param>\n    /// <param name=\"y\">The right hand side of the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static IEnumerable<A> combine<A>(IEnumerable<A> x, IEnumerable<A> y) \n        where A : Semigroup<A>\n    {\n        foreach (var a in x)\n        foreach (var b in y)\n            yield return a + b;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Semigroup/Semigroup.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\npublic interface Semigroup<A>\n    where A : Semigroup<A>\n{\n    /// <summary>\n    /// An associative binary operation.\n    /// </summary>\n    /// <param name=\"this\">The first operand to the operation</param>\n    /// <param name=\"rhs\">The second operand to the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public A Combine(A rhs);\n    \n    /// <summary>\n    /// An associative binary operation.\n    /// </summary>\n    /// <param name=\"lhs\">The first operand to the operation</param>\n    /// <param name=\"rhs\">The second operand to the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static virtual A operator +(A lhs, A rhs) =>\n        lhs.Combine(rhs);\n\n    /// <summary>\n    /// Property that contains the trait in record form.  This allows the trait to be passed\n    /// around as a value rather than resolved as a type.  It helps us get around limitations\n    /// in the C# constraint system.\n    /// </summary>\n    [Pure]\n    public static virtual SemigroupInstance<A> Instance { get; } =\n        new(Combine: Semigroup.combine);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/SemigroupK/SemigroupK.Extensions.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class SemigroupKExtensions\n{\n    /// <summary>\n    /// An associative binary operation\n    /// </summary>\n    /// <param name=\"mx\">The left-hand side of the operation</param>\n    /// <param name=\"my\">The right-hand side of the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static K<M, A> Combine<M, A>(this K<M, A> mx, K<M, A> my)\n        where M : SemigroupK<M> =>\n        M.Combine(mx, my);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/SemigroupK/SemigroupK.Module.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class SemigroupK\n{\n    /// <summary>\n    /// An associative binary operation\n    /// </summary>\n    /// <param name=\"mx\">The left-hand side of the operation</param>\n    /// <param name=\"my\">The right-hand side of the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static K<M, A> combine<M, A>(K<M, A> mx, K<M, A> my)\n        where M : SemigroupK<M> =>\n        M.Combine(mx, my);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/SemigroupK/SemigroupK.Operators.cs",
    "content": "using LanguageExt.Traits;\nnamespace LanguageExt;\n\npublic static partial class SemigroupKExtensions\n{\n    extension<F, A>(K<F, A> _) \n        where F : SemigroupK<F>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static K<F, A> operator +(K<F, A> lhs, K<F, A> rhs) =>\n            lhs.Combine(rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/SemigroupK/SemigroupK.Prelude.cs",
    "content": "﻿using LanguageExt.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\n\nnamespace LanguageExt;\n\npublic static partial class Prelude\n{\n    /// <summary>\n    /// An associative binary operation\n    /// </summary>\n    /// <param name=\"mx\">The left hand side of the operation</param>\n    /// <param name=\"my\">The right hand side of the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static K<M, A> combine<M, A>(K<M, A> mx, K<M, A> my) where M : SemigroupK<M> =>\n        M.Combine(mx, my);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/SemigroupK/SemigroupK.cs",
    "content": "﻿using System.Diagnostics.Contracts;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Equivalent of semigroups for working with higher-kinded types\n/// </summary>\n/// <typeparam name=\"M\">Higher kind</typeparam>\npublic interface SemigroupK<M>\n    where M : SemigroupK<M>\n{\n    /// <summary>\n    /// An associative binary operation.\n    /// </summary>\n    /// <param name=\"lhs\">The first operand to the operation</param>\n    /// <param name=\"rhs\">The second operand to the operation</param>\n    /// <returns>The result of the operation</returns>\n    [Pure]\n    public static abstract K<M, A> Combine<A>(K<M, A> lhs, K<M, A> rhs);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Stateful/Stateful.Extensions.cs",
    "content": "﻿using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class StatefulExtensions\n{\n    /// <summary>\n    /// Runs the `stateSetter` to update the state-monad's inner state.  Then runs the\n    /// `operation`.  And finally, resets the state to how it was before running `stateSetter`.\n    /// </summary>\n    /// <returns>\n    /// The result of `operation`\n    /// </returns>\n    public static K<M, A> Local<M, S, A>(this K<M, Unit> stateSetter, K<M, A> operation)\n        where M : Stateful<M, S>, Monad<M> =>\n        from s in M.Get\n        from _ in stateSetter\n        from r in operation\n        from u in M.Put(s)\n        select r;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Stateful/Stateful.Module.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Stateful\n{\n    public static K<M, Unit> put<M, S>(S value)\n        where M : Stateful<M, S> =>\n        M.Put(value);\n\n    public static  K<M, Unit> modify<M, S>(Func<S, S> modify)\n        where M : Stateful<M, S> =>\n        M.Modify(modify);\n\n    public static  K<M, Unit> modifyM<M, S>(Func<S, K<M, S>> modify)\n        where M : Stateful<M, S>, Monad<M> =>\n        from s in M.Get\n        from t in modify(s)\n        from _ in M.Put(t)\n        select default(Unit);    \n\n    public static K<M, S> get<M, S>()\n        where M : Stateful<M, S> =>\n        M.Get;\n\n    public static K<M, A> gets<M, S, A>(Func<S, A> f)\n        where M : Stateful<M, S> =>\n        M.Gets(f);\n\n    public static K<M, A> getsM<M, S, A>(Func<S, K<M, A>> f)\n        where M : Stateful<M, S>, Monad<M> =>\n        M.Flatten(M.Gets(f));\n\n    public static K<M, A> state<M, S, A>(Func<S, (A Value, S State)> f)\n        where M : Stateful<M, S>, Monad<M> =>\n        from s in M.Get\n        let r = f(s)\n        from _ in M.Put(r.State)\n        select r.Value;\n\n    /// <summary>\n    /// Runs the `stateSetter` to update the state-monad's inner state.  Then runs the\n    /// `operation`.  And finally, resets the state to how it was before running `stateSetter`.\n    /// </summary>\n    /// <returns>\n    /// The result of `operation`\n    /// </returns>\n    public static K<M, A> local<M, S, A>(K<M, Unit> stateSetter, K<M, A> operation)\n        where M : Stateful<M, S>, Monad<M> =>\n        from s in M.Get\n        from _ in stateSetter\n        from r in operation\n        from u in M.Put(s)\n        select r;\n\n    /// <summary>\n    /// Runs the `stateSetter` to update the state-monad's inner state.  Then runs the\n    /// `operation`.  And finally, resets the state to how it was before running `stateSetter`.\n    /// </summary>\n    /// <returns>\n    /// The result of `operation`\n    /// </returns>\n    public static K<M, A> local<M, S, A>(Func<S, S> stateSetter, K<M, A> operation)\n        where M : Stateful<M, S>, Monad<M> =>\n        from s in M.Get\n        from _ in M.Put(stateSetter(s))\n        from r in operation\n        from u in M.Put(s)\n        select r;    \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Stateful/Stateful.Trait.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Traits;\n\npublic interface Stateful<in M, S>  \n    where M : Stateful<M, S>\n{\n    public static abstract K<M, Unit> Put(S value);\n\n    public static abstract K<M, Unit> Modify(Func<S, S> modify) ;\n\n    public static abstract K<M, A> Gets<A>(Func<S, A> f);\n\n    public static virtual K<M, S> Get =>\n        Stateful.gets<M, S, S>(identity);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/TokenStream/TokenStream.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class TokenStream\n{\n    /// <summary>\n    /// Lift a single token to chunk of the stream\n    /// </summary>\n    public static S tokenToChunk<S, A>(in A token) \n        where S : TokenStream<S, A> =>\n        S.TokenToChunk(token);\n\n    /// <summary>\n    /// Lift many tokens to chunk of the stream\n    /// </summary>\n    public static S tokensToChunk<S, A>(in ReadOnlySpan<A> token)\n        where S : TokenStream<S, A> =>\n        S.TokensToChunk(token);\n\n    /// <summary>\n    /// Turn a chunk into a sequence of tokens\n    /// </summary>\n    public static ReadOnlySpan<A> chunkToTokens<S, A>(in S tokens)\n        where S : TokenStream<S, A> =>\n        S.ChunkToTokens(tokens);\n\n    /// <summary>\n    /// Get the length of a chunk\n    /// </summary>\n    public static int chunkLength<S, A>(in S tokens)\n        where S : TokenStream<S, A> =>\n        S.ChunkLength(tokens);\n\n    /// <summary>\n    /// Is the chunk empty?\n    /// </summary>\n    public static bool chunkEmpty<S, A>(in S tokens)\n        where S : TokenStream<S, A> =>\n        S.ChunkLength(tokens) <= 0;\n\n    /// <summary>\n    /// Take the first element of the stream if it exists.\n    /// </summary>\n    /// <param name=\"stream\">Stream</param>\n    /// <returns>Head element taken from the stream and a Tail of remaining stream items</returns>\n    public static bool take1<S, A>(in S stream, out A head, out S tail) \n        where S : TokenStream<S, A> =>\n        S.Take1(stream, out head, out tail);\n    \n    /// <summary>\n    /// `Take` should try to extract a chunk of length `amount`, or if the\n    /// stream is too short, the rest of the stream. Valid implementation\n    /// should follow the rules:\n    /// \n    /// * If the requested length `amount` is `0` (or less), `None` should never be returned, instead `Some([], s)`\n    /// should be returned, where `[]` stands for the empty chunk, and `s` is the original stream (second argument).\n    /// * If the requested length is greater than `0` and the stream is empty, `None` should be returned indicating end-of-input.\n    /// * In other cases, take chunk of length `amount` (or shorter if the   stream is not long enough) from the input\n    /// stream and return the chunk along with the rest of the stream.\n    /// </summary>\n    /// <param name=\"amount\">Number of elements to take</param>\n    /// <param name=\"stream\">Stream</param>\n    /// <returns>Head element taken from the stream and a Tail of remaining stream items</returns>\n    public static bool take<S, A>(int amount, in S stream, out S head, out S tail)\n        where S : TokenStream<S, A> =>\n        S.Take(amount, stream, out head, out tail);\n    \n    /// <summary>\n    /// Extract chunk of the stream taking tokens while the supplied predicate returns 'True'. Return the chunk and the\n    /// rest of the stream.\n    /// \n    /// For many types of streams, the method allows for significant performance improvements, although it is not\n    /// strictly necessary from a conceptual point-of-view.\n    /// </summary>\n    /// <param name=\"predicate\">Token testing predicate</param>\n    /// <param name=\"stream\">Stream to read from</param>\n    /// <returns></returns>\n    public static void takeWhile<S, A>(Func<A, bool> predicate, in S stream, out S head, out S tail) \n        where S : TokenStream<S, A> =>\n        S.TakeWhile(predicate, stream, out head, out tail); \n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/TokenStream/TokenStream.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Low-level streaming trait.  Used primarily by Megaparsec.\n/// </summary>\n/// <typeparam name=\"S\">Token type</typeparam>\npublic interface TokenStream<TOKENS, TOKEN>\n    where TOKENS : TokenStream<TOKENS, TOKEN>\n{\n    /// <summary>\n    /// If the stream supports the concept of tabs, then this function\n    /// should return true if the token is a tab.\n    /// </summary>\n    /// <param name=\"token\">Token to test</param>\n    /// <returns>True if a tab</returns>\n    public static abstract bool IsTab(TOKEN token);\n\n    /// <summary>\n    /// If the stream supports the concept of newlines, then this function\n    /// should return true if the token is a newline.\n    /// </summary>\n    /// <param name=\"token\">Token to test</param>\n    /// <returns>True if a newline</returns>\n    public static abstract bool IsNewline(TOKEN token);\n\n    /// <summary>\n    /// Create a textual respresentation of the token\n    /// </summary>\n    /// <param name=\"token\">Token</param>\n    /// <returns>Text</returns>\n    public static abstract ReadOnlySpan<char> TokenToString(TOKEN token);\n    \n    /// <summary>\n    /// Lift a single token to chunk of the stream\n    /// </summary>\n    public static abstract TOKENS TokenToChunk(in TOKEN token);\n\n    /// <summary>\n    /// Lift many tokens to chunk of the stream\n    /// </summary>\n    public static abstract TOKENS TokensToChunk(in ReadOnlySpan<TOKEN> token);\n    \n    /// <summary>\n    /// Turn a chunk into a sequence of tokens\n    /// </summary>\n    public static abstract ReadOnlySpan<TOKEN> ChunkToTokens(in TOKENS tokens);\n\n    /// <summary>\n    /// Get the length of a chunk\n    /// </summary>\n    public static abstract int ChunkLength(in TOKENS tokens);\n\n    /// <summary>\n    /// Take the first element of the stream if it exists.\n    /// </summary>\n    /// <param name=\"stream\">Stream</param>\n    /// <returns>Head element taken from the stream and a Tail of remaining stream items</returns>\n    public static abstract bool Take1(in TOKENS stream, out TOKEN head, out TOKENS tail);\n    \n    /// <summary>\n    /// `Take` should try to extract a chunk of length `amount`, or if the\n    /// stream is too short, the rest of the stream. Valid implementation\n    /// should follow the rules:\n    /// \n    /// * If the requested length `amount` is `0` (or less), `None` should never be returned, instead `Some([], s)`\n    /// should be returned, where `[]` stands for the empty chunk, and `s` is the original stream (second argument).\n    /// * If the requested length is greater than `0` and the stream is empty, `None` should be returned indicating end-of-input.\n    /// * In other cases, take chunk of length `amount` (or shorter if the   stream is not long enough) from the input\n    /// stream and return the chunk along with the rest of the stream.\n    /// </summary>\n    /// <param name=\"amount\">Number of elements to take</param>\n    /// <param name=\"stream\">Stream</param>\n    /// <returns>Head element taken from the stream and a Tail of remaining stream items</returns>\n    public static abstract bool Take(int amount, in TOKENS stream, out TOKENS head, out TOKENS tail);\n    \n    /// <summary>\n    /// Extract chunk of the stream taking tokens while the supplied predicate returns 'True'. Return the chunk and the\n    /// rest of the stream.\n    /// \n    /// For many types of streams, the method allows for significant performance improvements, although it is not\n    /// strictly necessary from a conceptual point-of-view.\n    /// </summary>\n    /// <param name=\"predicate\">Token testing predicate</param>\n    /// <param name=\"stream\">Stream to read from</param>\n    /// <returns></returns>\n    public static abstract void TakeWhile(Func<TOKEN, bool> predicate, in TOKENS stream, out TOKENS head, out TOKENS tail);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Trait.cs",
    "content": "﻿namespace LanguageExt.Traits;\n\npublic interface Trait;\n"
  },
  {
    "path": "LanguageExt.Core/Traits/TraitAttribute.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Attributes;\n\n[AttributeUsage(AttributeTargets.Interface)]\npublic class TraitAttribute : Attribute\n{\n    public readonly string NameFormat;\n    public TraitAttribute(string nameFormat) =>\n        NameFormat = nameFormat;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Traversable/README.md",
    "content": "Traversable structures support element-wise sequencing of `Applicative` effects (thus also `Monad` effects) \nto construct new structures of the same shape as the input.\n\nTo illustrate what is meant by same shape, if the input structure is `[a]`, each output structure is a list `[b]` of \nthe same length as the input. If the input is a `Tree<A>`, each output `Tree<B>` has the same graph of intermediate \nnodes and leaves. Similarly, if the input is a tuple `(x, a)`, each output is a tuple `(x, b)`, and so forth.\n\nEvery Traversable structure is both a `Functor` and `Foldable`."
  },
  {
    "path": "LanguageExt.Core/Traits/Traversable/Traversable.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Functors representing data structures that can be transformed to structures of the same\n/// shape by performing an `Applicative` (or, therefore, `Monad`) action on each element from\n/// left to right.\n///\n/// A more detailed description of what same shape means, the various methods, how traversals\n/// are constructed, and example advanced use-cases can be found in the Overview section of Data.Traversable.\n/// </summary>\n/// <typeparam name=\"T\"></typeparam>\npublic static partial class TraversableExtensions\n{\n    public static K<F, K<T, B>> Traverse<T, F, A, B>(\n        this K<T, A> ta,\n        Func<A, K<F, B>> f)\n        where T : Traversable<T>\n        where F : Applicative<F> =>\n        Traversable.traverse(f, ta);\n\n    public static K<F, K<T, A>> Sequence<T, F, A>(\n        this K<T, K<F, A>> ta)\n        where T : Traversable<T>\n        where F : Applicative<F> =>\n        Traversable.sequence(ta);\n\n    public static K<M, K<T, B>> TraverseM<M, T, A, B>(\n        this Func<A, K<M, B>> f,\n        K<T, A> ta)\n        where T : Traversable<T>\n        where M : Monad<M> =>\n        Traversable.traverseM(f, ta);\n\n    public static K<F, K<T, A>> SequenceM<T, F, A>(\n        this K<T, K<F, A>> ta)\n        where T : Traversable<T>\n        where F : Monad<F> =>\n        Traversable.sequenceM(ta);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Traversable/Traversable.Module.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Traversable \n{\n    /// <summary>\n    /// Map each element of a structure to an action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <remarks>\n    /// This version of `traverse` works with the lifted `K` types which are\n    /// sometimes difficult to work with when nested.  If you need to get concrete\n    /// types out of your traversal operation then use `traverse2` - it needs more\n    /// generic parameters but it retains the concrete types.\n    /// </remarks>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"T\">Traversable trait</typeparam>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"A\">Bound value (input)</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    /// <returns></returns>\n    public static K<F, K<T, B>> traverse<T, F, A, B>(\n        Func<A, K<F, B>> f,\n        K<T, A> ta)\n        where T : Traversable<T>\n        where F : Applicative<F> =>\n        T.Traverse(f, ta);\n\n    /// <summary>\n    /// Evaluate each action in the structure from left to right, and collect the results. \n    /// </summary>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"T\">Traversable trait</typeparam>\n    /// <typeparam name=\"F\">Applicative functor trait</typeparam>\n    /// <typeparam name=\"A\">Bound value (input)</typeparam>\n    /// <returns></returns>\n    public static K<F, K<T, A>> sequence<T, F, A>(\n        K<T, K<F, A>> ta)\n        where T : Traversable<T>\n        where F : Applicative<F> =>\n        T.Sequence(ta);\n\n    /// <summary>\n    /// Map each element of a structure to a monadic action, evaluate these actions from\n    /// left to right, and collect the results.\n    /// </summary>\n    /// <param name=\"f\"></param>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"T\">Traversable trait</typeparam>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"A\">Bound value (input)</typeparam>\n    /// <typeparam name=\"B\">Bound value (output)</typeparam>\n    /// <returns></returns>\n    public static K<M, K<T, B>> traverseM<T, M, A, B>(\n        Func<A, K<M, B>> f,\n        K<T, A> ta)\n        where T : Traversable<T>\n        where M : Monad<M> =>\n        T.TraverseM(f, ta);\n\n    /// <summary>\n    /// Evaluate each monadic action in the structure from left to right, and collect the results. \n    /// </summary>\n    /// <param name=\"ta\">Traversable structure</param>\n    /// <typeparam name=\"T\">Traversable trait</typeparam>\n    /// <typeparam name=\"M\">Monad trait</typeparam>\n    /// <typeparam name=\"A\">Bound value (input)</typeparam>\n    /// <returns></returns>\n    public static K<M, K<T, A>> sequenceM<T, M, A>(\n        K<T, K<M, A>> ta)\n        where T : Traversable<T>\n        where M : Monad<M> =>\n        T.SequenceM(ta);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Traversable/Traversable.Trait.cs",
    "content": "using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// Functors representing data structures that can be transformed to structures of the same\n/// shape by performing an `Applicative` (or, therefore, `Monad`) action on each element from\n/// left to right.\n///\n/// A more detailed description of what same shape means, the various methods, how traversals\n/// are constructed, and example advanced use-cases can be found in the Overview section of Data.Traversable.\n/// </summary>\n/// <typeparam name=\"T\"></typeparam>\npublic interface Traversable<T> : Functor<T>, Foldable<T> \n    where T : Traversable<T>, Functor<T>, Foldable<T>\n{\n    public static abstract K<F, K<T, B>> Traverse<F, A, B>(\n        Func<A, K<F, B>> f,\n        K<T, A> ta)\n        where F : Applicative<F>;\n\n    public static virtual K<F, K<T, A>> Sequence<F, A>(\n        K<T, K<F, A>> ta)\n        where F : Applicative<F> =>\n        Traversable.traverse(x => x, ta);\n\n    public static virtual K<M, K<T, B>> TraverseM<M, A, B>(\n        Func<A, K<M, B>> f,\n        K<T, A> ta)\n        where M : Monad<M> =>\n        Traversable.traverse(f, ta);\n\n    public static virtual K<F, K<T, A>> SequenceM<F, A>(\n        K<T, K<F, A>> ta)\n        where F : Monad<F> =>\n        Traversable.traverseM(x => x, ta);\n    \n    public static virtual K<F, K<T, B>> TraverseDefault<F, A, B>(\n        Func<A, K<F, B>> f,\n        K<T, A> ta)\n        where F : Applicative<F> =>\n        Traversable.sequence(T.Map(f, ta));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Writable/Writable.Extensions.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class WritableExtensions\n{\n    /// <summary>\n    /// `pass` is an action that executes the `action`, which returns a value and a\n    /// function; it then returns the value with the output having been applied to\n    /// the function.\n    /// </summary>\n    public static K<M, A> Pass<M, W, A>(this K<M, (A Value, Func<W, W> Function)> action)\n        where M : Writable<M, W>\n        where W : Monoid<W> =>\n        M.Pass(action);\n\n    /// <summary>\n    /// `listens` executes the action @m@ and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static K<M, (A Value, B Output)> Listens<M, W, A, B>(this Func<W, B> f, K<M, A> ma)\n        where M : Writable<M, W>, Monad<M>\n        where W : Monoid<W> =>\n        M.Bind(M.Listen(ma), aw => M.Pure((aw.Value, f(aw.Output))));\n\n    /// <summary>\n    /// `listens` executes the action @m@ and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static K<M, (A Value, B Output)> Listens<M, W, A, B>(this K<M, A> ma, Func<W, B> f)\n        where M : Writable<M, W>, Monad<M>\n        where W : Monoid<W> =>\n        M.Bind(M.Listen(ma), aw => M.Pure((aw.Value, f(aw.Output))));\n\n    /// <summary>\n    /// `censor` executes the action `ma` and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public static K<M, A> Censor<M, W, A>(this K<M, A> ma, Func<W, W> f)\n        where M : Writable<M, W>, Monad<M>\n        where W : Monoid<W> =>\n        M.Pass(M.Bind(ma, a => M.Pure((a, f))));\n\n    /// <summary>\n    /// `censor` executes the action `ma` and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public static K<M, A> Censor<M, W, A>(this Func<W, W> f, K<M, A> ma)\n        where M : Writable<M, W>, Monad<M>\n        where W : Monoid<W> =>\n        M.Pass(M.Bind(ma, a => M.Pure((a, f))));}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Writable/Writable.Module.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Traits;\n\npublic static partial class Writable\n{\n    /// <summary>\n    /// Tell is an action that produces the writer output\n    /// </summary>\n    /// <param name=\"item\">Item to tell</param>\n    /// <typeparam name=\"W\">Writer type</typeparam>\n    /// <returns>Structure with the told item</returns>\n    public static K<M, Unit> tell<M, W>(W item)\n        where M : Writable<M, W>\n        where W : Monoid<W> =>\n        M.Tell(item);\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static K<M, A> write<W, M, A>((A, W) item)\n        where M : Writable<M, W>, Monad<M>\n        where W : Monoid<W> =>\n        M.Bind(M.Tell(item.Item2), _ => M.Pure(item.Item1));\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static K<M, A> write<W, M, A>(A value, W item)\n        where M : Writable<M, W>, Monad<M>\n        where W : Monoid<W> =>\n        M.Bind(M.Tell(item), _ => M.Pure(value));\n\n    /// <summary>\n    /// `pass` is an action that executes the `action`, which returns a value and a\n    /// function; it then returns the value with the output having been applied to\n    /// the function.\n    /// </summary>\n    public static K<M, A> pass<W, M, A>(K<M, (A Value, Func<W, W> Function)> action)\n        where M : Writable<M, W>\n        where W : Monoid<W> =>\n        M.Pass(action);\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static K<M, (A Value, W Output)> listen<W, M, A>(K<M, A> ma)\n        where M : Writable<M, W>\n        where W : Monoid<W> =>\n        M.Listen(ma);\n\n    /// <summary>\n    /// `listens` executes the action `ma` and adds the result of applying `f` to the\n    /// output to the value of the computation.\n    /// </summary>\n    public static K<M, (A Value, B Output)> listens<W, M, A, B>(Func<W, B> f, K<M, A> ma)\n        where M : Writable<M, W>, Monad<M>\n        where W : Monoid<W> =>\n        M.Bind(M.Listen(ma), aw => M.Pure((aw.Value, f(aw.Output))));\n\n    /// <summary>\n    /// `censor` executes the action `ma` and applies the function `f` to its output,\n    /// leaving the return value unchanged.\n    /// </summary>\n    public static K<M, A> censor<W, M, A>(Func<W, W> f, K<M, A> ma)\n        where M : Writable<M, W>, Monad<M>\n        where W : Monoid<W> =>\n        M.Pass(M.Bind(ma, a => M.Pure((a, f))));\n}\n"
  },
  {
    "path": "LanguageExt.Core/Traits/Writable/Writable.Trait.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Traits;\n\n/// <summary>\n/// WriterM trait\n/// \n/// `Tell` is how you log to the writer's output. The `WriterM` carries\n/// this 'packet' upwards, merging it if needed (hence the `Monoid`\n/// requirement).\n///\n/// `Listen` listens to a monad acting, and returns what the monad \"said\".\n///\n/// `Pass` lets you provide a writer transformer which changes internals of\n/// the written object.\n/// </summary>\n/// <typeparam name=\"M\">Writer self trait</typeparam>\n/// <typeparam name=\"W\">Monoidal output type</typeparam>\npublic interface Writable<M, W>  \n    where M : Writable<M, W>\n    where W : Monoid<W>\n{\n    /// <summary>\n    /// Tell is an action that produces the writer output\n    /// </summary>\n    /// <param name=\"item\">Item to tell</param>\n    /// <typeparam name=\"W\">Writer type</typeparam>\n    /// <returns>Structure with the told item</returns>\n    public static abstract K<M, Unit> Tell(W item);\n\n    /// <summary>\n    /// Writes an item and returns a value at the same time\n    /// </summary>\n    public static abstract K<M, (A Value, W Output)> Listen<A>(K<M, A> ma);\n\n    /// <summary>\n    /// `Pass` is an action that executes the `action`, which returns a value and a\n    /// function; it then returns the value with the output having been applied to\n    /// the function.\n    /// </summary>\n    /// <remarks>\n    /// For usage, see `Writer.censor` for how it's used to filter the output.\n    /// </remarks>\n    public static abstract K<M, A> Pass<A>(K<M, (A Value, Func<W, W> Function)> action);\n\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/Accel.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Numeric acceleration value\n/// Handles unit conversions automatically\n/// Internally all speeds are stored as metres per-second squared\n/// All standard arithmetic operators work on the Accel\n/// type.  So keep all accelerations wrapped until you need the\n/// value, then extract using various unit-of-measure\n/// accessors (MetresPerSecond2, etc.) or divide by 1.MetresPerSecond2()\n/// </summary>\npublic readonly struct Accel :\n    IComparable<Accel>,\n    IEquatable<Accel>,\n    IComparable\n{\n    readonly double Value;\n\n    internal Accel(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        Value + \" m/s²\";\n\n    public bool Equals(Accel other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(Accel other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is Accel accel && Equals(accel);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null        => 1,\n            Accel other => CompareTo(other),\n            _           => throw new ArgumentException($\"must be of type {nameof(Accel)}\")\n        };\n\n    public int CompareTo(Accel other) =>\n        Value.CompareTo(other.Value);\n\n    public Accel Add(Accel rhs) =>\n        new (Value + rhs.Value);\n\n    public Accel Subtract(Accel rhs) =>\n        new (Value - rhs.Value);\n\n    public Accel Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public Accel Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static Accel operator *(Accel lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static Accel operator *(double lhs, Accel rhs) =>\n        rhs.Multiply(lhs);\n\n    public static Velocity operator *(Accel lhs, Time rhs) =>\n        new (lhs.Value * rhs.Seconds);\n\n    public static Velocity operator *(Time lhs, Accel rhs) =>\n        new (lhs.Seconds * rhs.Value);\n\n    public static VelocitySq operator *(Accel lhs, Length rhs) =>\n        new (lhs.Value * rhs.Metres);\n\n    public static VelocitySq operator *(Length lhs, Accel rhs) =>\n        new (rhs.Value * lhs.Metres);\n\n    public static Length operator *(Accel lhs, TimeSq rhs) =>\n        new (lhs.Value * rhs.Seconds2);\n\n    public static Length operator *(TimeSq lhs, Accel rhs) =>\n        new (rhs.Value * lhs.Seconds2);\n\n    public static Accel operator +(Accel lhs, Accel rhs) =>\n        lhs.Add(rhs);\n\n    public static Accel operator -(Accel lhs, Accel rhs) =>\n        lhs.Subtract(rhs);\n\n    public static Accel operator /(Accel lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static double operator /(Accel lhs, Accel rhs) =>\n        lhs.Value / rhs.Value;\n\n    public static bool operator ==(Accel lhs, Accel rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(Accel lhs, Accel rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(Accel lhs, Accel rhs) =>\n        lhs.Value > rhs.Value;\n\n    public static bool operator <(Accel lhs, Accel rhs) =>\n        lhs.Value < rhs.Value;\n\n    public static bool operator >=(Accel lhs, Accel rhs) =>\n        lhs.Value >= rhs.Value;\n\n    public static bool operator <=(Accel lhs, Accel rhs) =>\n        lhs.Value <= rhs.Value;\n\n    public Accel Pow(double power) =>\n        new (Math.Pow(Value,power));\n\n    public Accel Round() =>\n        new (Math.Round(Value));\n\n    public Accel Sqrt() =>\n        new (Math.Sqrt(Value));\n\n    public Accel Abs() =>\n        new (Math.Abs(Value));\n\n    public Accel Min(Accel rhs) =>\n        new (Math.Min(Value, rhs.Value));\n\n    public Accel Max(Accel rhs) =>\n        new (Math.Max(Value, rhs.Value));\n\n    public double MetresPerSecond2 => Value;\n}\n\npublic static class UnitsAccelExtensions\n{\n    public static Accel MetresPerSecond2(this int self) =>\n        new (self);\n\n    public static Accel MetresPerSecond2(this float self) =>\n        new (self);\n\n    public static Accel MetresPerSecond2(this double self) =>\n        new (self);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/Area.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Numeric area value\n/// Handles unit conversions automatically\n/// Internally all areas are stored as metres^2\n/// All standard arithmetic operators work on the Area\n/// type.  So keep all Areas wrapped until you need the\n/// value, then extract using various unit-of-measure\n/// accessors (SqMetres, SqCentimetres, etc.) or divide by 1.SqMetre()\n/// </summary>\npublic readonly struct Area :\n    IComparable<Area>,\n    IEquatable<Area>,\n    IComparable\n{\n    readonly double Value;\n\n    internal Area(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        Value + \" m²\";\n\n    public bool Equals(Area other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(Area other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is Area area && Equals(area);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) => \n        obj switch\n        {\n            null       => 1,\n            Area other => CompareTo(other),\n            _          => throw new ArgumentException($\"must be of type {nameof(Area)}\")\n        };\n\n    public int CompareTo(Area other) =>\n        Value.CompareTo(other.Value);\n\n    public Area Add(Area rhs) =>\n        new (Value + rhs.Value);\n\n    public Area Subtract(Area rhs) =>\n        new (Value - rhs.Value);\n\n    public Area Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public Area Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static Area operator *(Area lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static Area operator *(double lhs, Area rhs) =>\n        rhs.Multiply(lhs);\n\n    public static Area operator /(Area lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static Area operator +(Area lhs, Area rhs) =>\n        lhs.Add(rhs);\n\n    public static Area operator -(Area lhs, Area rhs) =>\n        lhs.Subtract(rhs);\n\n    public static Length operator /(Area lhs, Length rhs) =>\n        new Length(lhs.Value / rhs.Metres);\n\n    public static double operator /(Area lhs, Area rhs) =>\n        lhs.Value / rhs.Value;\n\n    public static bool operator ==(Area lhs, Area rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(Area lhs, Area rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(Area lhs, Area rhs) =>\n        lhs.Value > rhs.Value;\n\n    public static bool operator <(Area lhs, Area rhs) =>\n        lhs.Value < rhs.Value;\n\n    public static bool operator >=(Area lhs, Area rhs) =>\n        lhs.Value >= rhs.Value;\n\n    public static bool operator <=(Area lhs, Area rhs) =>\n        lhs.Value <= rhs.Value;\n\n    public Area Pow(double power) =>\n        new Area(Math.Pow(Value,power));\n\n    public Area Round() =>\n        new Area(Math.Round(Value));\n\n    public Area Sqrt() =>\n        new Area(Math.Sqrt(Value));\n\n    public Length Abs() =>\n        new Length(Math.Abs(Value));\n\n    public Area Min(Area rhs) =>\n        new Area(Math.Min(Value, rhs.Value));\n\n    public Area Max(Area rhs) =>\n        new Area(Math.Max(Value, rhs.Value));\n\n    public double SqKilometres  => Value * 0.000001;\n    public double SqMetres      => Value;\n    public double SqCentimetres => Value * 10000.0;\n    public double SqMillimetres => Value * 1000000.0;\n}\n\npublic static class UnitsAreaExtensions\n{\n    public static Area SqKilometres(this int self) =>\n        new (self / 0.000001);\n\n    public static Area SqKilometres(this float self) =>\n        new (self / 0.000001);\n\n    public static Area SqKilometres(this double self) =>\n        new (self / 0.000001);\n\n    public static Area SqMetres(this int self) =>\n        new (self);\n\n    public static Area SqMetres(this float self) =>\n        new (self);\n\n    public static Area SqMetres(this double self) =>\n        new (self);\n\n    public static Area SqCentimetres(this int self) =>\n        new (self / 10000.0);\n\n    public static Area SqCentimetres(this float self) =>\n        new (self / 10000.0);\n\n    public static Area SqCentimetres(this double self) =>\n        new (self / 10000.0);\n\n    public static Area SqMillimetres(this int self) =>\n        new (self / 1000000.0);\n\n    public static Area SqMillimetres(this float self) =>\n        new (self / 1000000.0);\n\n    public static Area SqMillimetres(this double self) =>\n        new (self / 1000000.0);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/Length.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits.Domain;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Numeric length value\n/// Handles unit conversions automatically\n/// Internally all lengths are stored as metres\n/// All standard arithmetic operators work on the Length\n/// type.  So keep all Lengths wrapped until you need the\n/// value, then extract using various unit-of-measure\n/// accessors (Metres, Centimetres, etc.) or divide by 1.Metre()\n/// </summary>\npublic readonly struct Length :\n    IComparable,\n    DomainType<Length, double>,\n    Amount<Length, double> \n{\n    readonly double Value;\n\n    internal Length(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        Value + \" m\";\n\n    public bool Equals(Length other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(Length other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is Length length && Equals(length);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null         => 1,\n            Length other => CompareTo(other),\n            _            => throw new ArgumentException($\"must be of type {nameof(Length)}\")\n        };\n\n    public int CompareTo(Length other) =>\n        Value.CompareTo(other.Value);\n\n    public Length Add(Length rhs) =>\n        new (Value + rhs.Value);\n\n    public Length Subtract(Length rhs) =>\n        new (Value - rhs.Value);\n\n    public Length Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public Length Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static Area operator *(Length lhs, Length rhs) =>\n        new (lhs.Value * rhs.Value);\n\n    public static Length operator *(Length lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static Length operator *(double lhs, Length rhs) =>\n        rhs.Multiply(lhs);\n\n    public static Length operator -(Length self) =>\n        new (-self.Value);\n\n    public static Length operator +(Length lhs, Length rhs) =>\n        lhs.Add(rhs);\n\n    public static Length operator -(Length lhs, Length rhs) =>\n        lhs.Subtract(rhs);\n\n    public static Length operator /(Length lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static double operator /(Length lhs, Length rhs) =>\n        lhs.Value / rhs.Value;\n\n    public static Accel operator /(Length lhs, TimeSq rhs) =>\n        new Accel(lhs.Value / rhs.Seconds2);\n\n    public static Time operator /(Length lhs, Velocity rhs) =>\n        new Time(lhs.Metres / rhs.MetresPerSecond);\n\n    public static Velocity operator /(Length lhs, Time rhs) =>\n        new Velocity(lhs.Value / rhs.Seconds);\n\n    public static bool operator ==(Length lhs, Length rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(Length lhs, Length rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(Length lhs, Length rhs) =>\n        lhs.Value > rhs.Value;\n\n    public static bool operator <(Length lhs, Length rhs) =>\n        lhs.Value < rhs.Value;\n\n    public static bool operator >=(Length lhs, Length rhs) =>\n        lhs.Value >= rhs.Value;\n\n    public static bool operator <=(Length lhs, Length rhs) =>\n        lhs.Value <= rhs.Value;\n\n    public Length Pow(double power) =>\n        new (Math.Pow(Value,power));\n\n    public Length Round() =>\n        new (Math.Round(Value));\n\n    public Length Sqrt() =>\n        new (Math.Sqrt(Value));\n\n    public Length Abs() =>\n        new (Math.Abs(Value));\n\n    public Length Min(Length rhs) =>\n        new (Math.Min(Value, rhs.Value));\n\n    public Length Max(Length rhs) =>\n        new (Math.Max(Value, rhs.Value));\n\n    public double Miles         => Value * 6.2137119223484848484848484848485e-4;\n    public double NauticalMiles => Value * 1852.0;\n    public double Yards         => Value * 1.0936132983333333333333333333333;\n    public double Feet          => Value * 3.280839895;\n    public double Inches        => Value * 39.37007874;\n    public double Kilometres    => Value / 1000.0;\n    public double Hectometres   => Value / 100.0;\n    public double Decametres    => Value / 10.0;\n    public double Metres        => Value;\n    public double Centimetres   => Value * 100.0;\n    public double Millimetres   => Value * 1000.0;\n    public double Micrometres   => Value * 1000000.0;\n    public double Nanometres    => Value * 1000000000.0;\n    public double Angstroms     => Value * 10000000000.0;\n    \n    static Fin<Length> DomainType<Length, double>.From(double repr) =>\n        new Length(repr);\n\n    public static Length From(double repr) => \n        new (repr);\n    \n    public double To() =>\n        Value;\n}\n\npublic static class UnitsLengthExtensions\n{\n    public static Length Miles(this int self) =>\n        new (1609.344000006437376000025749504 * self);\n\n    public static Length Miles(this float self) =>\n        new (1609.344000006437376000025749504 * self);\n\n    public static Length Miles(this double self) =>\n        new (1609.344000006437376000025749504 * self);\n\n    public static Length NauticalMiles(this int self) =>\n        new (self / 1852.0);\n\n    public static Length NauticalMiles(this float self) =>\n        new (self / 1852.0);\n\n    public static Length NauticalMiles(this double self) =>\n        new (self / 1852.0);\n\n    public static Length Yards(this int self) =>\n        new (0.9144000000036576000000146304 * self);\n\n    public static Length Yards(this float self) =>\n        new (0.9144000000036576000000146304 * self);\n\n    public static Length Yards(this double self) =>\n        new (0.9144000000036576000000146304 * self);\n\n    public static Length Feet(this int self) =>\n        new (0.3048000000012192000000048768 * self);\n\n    public static Length Feet(this float self) =>\n        new (0.3048000000012192000000048768 * self);\n\n    public static Length Feet(this double self) =>\n        new (0.3048000000012192000000048768 * self);\n\n    public static Length Inches(this int self) =>\n        new (0.0254000000001016000000004064 * self);\n\n    public static Length Inches(this float self) =>\n        new (0.0254000000001016000000004064 * self);\n\n    public static Length Inches(this double self) =>\n        new (0.0254000000001016000000004064 * self);\n\n    public static Length Kilometres(this int self) =>\n        new (1000.0 * self);\n\n    public static Length Kilometres(this float self) =>\n        new (1000.0 * self);\n\n    public static Length Kilometres(this double self) =>\n        new (1000.0 * self);\n\n    public static Length Metres(this int self) =>\n        new (self);\n\n    public static Length Metres(this float self) =>\n        new (self);\n\n    public static Length Metres(this double self) =>\n        new (self);\n\n    public static Length Centimetres(this int self) =>\n        new (self / 100.0);\n\n    public static Length Centimetres(this float self) =>\n        new (self / 100.0);\n\n    public static Length Centimetres(this double self) =>\n        new (self / 100.0);\n\n    public static Length Millimetres(this int self) =>\n        new (self / 1000.0);\n\n    public static Length Millimetres(this float self) =>\n        new (self / 1000.0);\n\n    public static Length Millimetres(this double self) =>\n        new (self / 1000.0);\n\n    public static Length Micrometres(this int self) =>\n        new (self / 1000000.0);\n\n    public static Length Micrometres(this float self) =>\n        new (self / 1000000.0);\n\n    public static Length Micrometres(this double self) =>\n        new (self / 1000000.0);\n\n    public static Length Nanometres(this int self) =>\n        new (self / 1000000000.0);\n\n    public static Length Nanometres(this float self) =>\n        new (self / 1000000000.0);\n\n    public static Length Nanometres(this double self) =>\n        new (self / 1000000000.0);\n\n    public static Length Angstroms(this int self) =>\n        new (self / 10000000000.0);\n\n    public static Length Angstroms(this float self) =>\n        new (self / 10000000000.0);\n\n    public static Length Angstroms(this double self) =>\n        new (self / 10000000000.0);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/Mass.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\npublic readonly struct Mass : \n    IComparable<Mass>, \n    IEquatable<Mass>, \n    IComparable\n{\n    readonly double Value;\n\n    internal Mass(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        Kilograms + \" kg\";\n\n    public int CompareTo(object? obj) =>\n        obj is null         ? 1\n        : obj is Mass other ? CompareTo(other)\n                              : throw new ArgumentException($\"must be of type {nameof(Mass)}\");\n\n    public int CompareTo(Mass other) =>\n        Kilograms.CompareTo(other.Kilograms);\n\n    public bool Equals(Mass other) =>\n        Kilograms.Equals(other.Kilograms);\n\n    public bool Equals(Mass other, double epsilon) =>\n        Math.Abs(other.Kilograms - Kilograms) < epsilon;\n\n    public override bool Equals(object?  obj) =>\n        obj is Mass m && Equals(m);\n\n    public override int GetHashCode() =>\n        Kilograms.GetHashCode();\n\n    public Mass Add(Mass rhs) =>\n        new (Kilograms + rhs.Kilograms);\n\n    public Mass Subtract(Mass rhs) =>\n        new (Kilograms - rhs.Kilograms);\n\n    public Mass Multiply(double rhs) =>\n        new (Kilograms * rhs);\n\n    public Mass Divide(double rhs) =>\n        new (Kilograms / rhs);\n\n    public static Mass operator *(Mass lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static Mass operator *(double lhs, Mass rhs) =>\n        rhs.Multiply(lhs);\n\n    public static Mass operator +(Mass lhs, Mass rhs) =>\n        lhs.Add(rhs);\n\n    public static Mass operator -(Mass lhs, Mass rhs) =>\n        lhs.Subtract(rhs);\n\n    public static Mass operator /(Mass lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static double operator /(Mass lhs, Mass rhs) =>\n        lhs.Kilograms / rhs.Kilograms;\n\n    public static bool operator ==(Mass lhs, Mass rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(Mass lhs, Mass rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(Mass lhs, Mass rhs) =>\n        lhs.Kilograms > rhs.Kilograms;\n\n    public static bool operator <(Mass lhs, Mass rhs) =>\n        lhs.Kilograms < rhs.Kilograms;\n\n    public static bool operator >=(Mass lhs, Mass rhs) =>\n        lhs.Kilograms >= rhs.Kilograms;\n\n    public static bool operator <=(Mass lhs, Mass rhs) =>\n        lhs.Kilograms <= rhs.Kilograms;\n\n    public Mass Round() =>\n        new (Math.Round(Kilograms));\n\n    public Mass Sqrt() =>\n        new (Math.Sqrt(Kilograms));\n\n    public Mass Abs() =>\n        new (Math.Abs(Kilograms));\n\n    public Mass Min(Mass rhs) =>\n        new (Math.Min(Kilograms, rhs.Kilograms));\n\n    public Mass Max(Mass rhs) =>\n        new (Math.Max(Kilograms, rhs.Kilograms));\n\n    public double Grams => Value * 1000.0;\n    public double Kilograms => Value;\n    public double Tonnes => Value / 1000.0;\n\n    public double Ounces => Pounds      * 16.0;\n    public double Pounds => Value       * 2.2046226;\n    public double Stones => Pounds      / 14.0;\n    public double ImperialTons => Value / 0.000984207;\n    public double ShortTons => Value    / 0.00110231;\n}\n\npublic static class UnitsMassExtensions\n{\n    public static Mass Grams(this int self) =>\n        new (self / 1000.0);\n\n    public static Mass Grams(this double self) =>\n        new (self / 1000.0);\n\n    public static Mass Grams(this float self) =>\n        new (self / 1000.0);\n\n    public static Mass Kilograms(this int self) =>\n        new (self);\n\n    public static Mass Kilograms(this double self) =>\n        new (self);\n\n    public static Mass Kilograms(this float self) =>\n        new (self);\n\n    public static Mass Tonnes(this int self) =>\n        new (self * 1000.0);\n\n    public static Mass Tonnes(this double self) =>\n        new (self * 1000.0);\n\n    public static Mass Tonnes(this float self) =>\n        new (self * 1000.0);\n\n    public static Mass Ounces(this int self) =>\n        new (self / 35.273961949);\n\n    public static Mass Ounces(this double self) =>\n        new (self / 35.273961949);\n\n    public static Mass Ounces(this float self) =>\n        new (self / 35.273961949);\n\n    public static Mass Pounds(this int self) =>\n        new (self / 2.2046226219);\n\n    public static Mass Pounds(this double self) =>\n        new (self / 2.2046226219);\n\n    public static Mass Pounds(this float self) =>\n        new (self / 2.2046226219);\n\n    public static Mass Stones(this int self) =>\n        new (self / 0.157473044418);\n\n    public static Mass Stones(this double self) =>\n        new (self / 0.157473044418);\n\n    public static Mass Stones(this float self) =>\n        new (self / 0.157473044418);\n\n    public static Mass ImperialTons(this int self) =>\n        new (self / 0.0009842065277);\n\n    public static Mass ImperialTons(this double self) =>\n        new (self / 0.0009842065277);\n\n    public static Mass ImperialTons(this float self) =>\n        new (self / 0.0009842065277);\n\n    public static Mass ShortTon(this int self) =>\n        new (self / 0.00110231131093);\n\n    public static Mass ShortTon(this double self) =>\n        new (self / 0.00110231131093);\n\n    public static Mass ShortTon(this float self) =>\n        new (self / 0.00110231131093);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/Module.cs",
    "content": "﻿namespace LanguageExt;\n\npublic class UnitsOfMeasure\n{\n    /// <summary>\n    /// Millimetre\n    /// </summary>\n    /// <example>\n    ///     Length x = 10*mm;\n    /// </example>\n    public static readonly Length mm = 1.Millimetres();\n\n    /// <summary>\n    /// Millimetre\n    /// </summary>\n    /// <example>\n    ///     Length x = 1*millimetre;\n    /// </example>\n    public static readonly Length millimetre = 1.Millimetres();\n\n    /// <summary>\n    /// Millimetre\n    /// </summary>\n    /// <example>\n    ///     Length x = 10*millimetres;\n    /// </example>\n    public static readonly Length millimetres = 1.Millimetres();\n\n    /// <summary>\n    /// Millimeter\n    /// </summary>\n    /// <example>\n    ///     Length x = 1*millimeter;\n    /// </example>\n    public static readonly Length millimeter = 1.Millimetres();\n\n    /// <summary>\n    /// Millimeters\n    /// </summary>\n    /// <example>\n    ///     Length x = 10*millimeters;\n    /// </example>\n    public static readonly Length millimeters = 1.Millimetres();\n\n    /// <summary>\n    /// Centimetre\n    /// </summary>\n    /// <example>\n    ///     Length x = 100*cm;\n    /// </example>\n    public static readonly Length cm = 1.Centimetres();\n\n    /// <summary>\n    /// Centimetre\n    /// </summary>\n    /// <example>\n    ///     Length x = 1*centimetre;\n    /// </example>\n    public static readonly Length centimetre = 1.Centimetres();\n\n    /// <summary>\n    /// Centimetres\n    /// </summary>\n    /// <example>\n    ///     Length x = 100*centimetres\n    /// </example>\n    public static readonly Length centimetres = 1.Centimetres();\n\n    /// <summary>\n    /// Centimeter\n    /// </summary>\n    /// <example>\n    ///     Length x = 1*centimeter;\n    /// </example>\n    public static readonly Length centimeter = 1.Centimetres();\n\n    /// <summary>\n    /// Centimeters\n    /// </summary>\n    /// <example>\n    ///     Length x = 100*centimeters;\n    /// </example>\n    public static readonly Length centimeters = 1.Centimetres();\n\n    /// <summary>\n    /// Metre\n    /// </summary>\n    /// <example>\n    ///     Length x = 10*m;\n    /// </example>\n    public static readonly Length m = 1.Metres();\n\n    /// <summary>\n    /// Metre\n    /// </summary>\n    /// <example>\n    ///     Length x = 1*metre;\n    /// </example>\n    public static readonly Length metre = 1.Metres();\n\n    /// <summary>\n    /// Metres\n    /// </summary>\n    /// <example>\n    ///     Length x = 10*metres;\n    /// </example>\n    public static readonly Length metres = 1.Metres();\n\n    /// <summary>\n    /// Meter\n    /// </summary>\n    /// <example>\n    ///     Length x = 1*meter;\n    /// </example>\n    public static readonly Length meter = 1.Metres();\n\n    /// <summary>\n    /// Meters\n    /// </summary>\n    /// <example>\n    ///     Length x = 10*meters;\n    /// </example>\n    public static readonly Length meters = 1.Metres();\n\n    /// <summary>\n    /// Kilometre\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*km;\n    /// </example>\n    public static readonly Length km = 1.Kilometres();\n\n    /// <summary>\n    /// Kilometre\n    /// </summary>\n    /// <example>\n    ///     Length x = 1*kilometre;\n    /// </example>\n    public static readonly Length kilometre = 1.Kilometres();\n\n    /// <summary>\n    /// Kilometres\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*kilometres;\n    /// </example>\n    public static readonly Length kilometres = 1.Kilometres();\n\n    /// <summary>\n    /// Kilometer\n    /// </summary>\n    /// <example>\n    ///     Length x = 1*kilometer;\n    /// </example>\n    public static readonly Length kilometer = 1.Kilometres();\n\n    /// <summary>\n    /// Kilometers\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*kilometers;\n    /// </example>\n    public static readonly Length kilometers = 1.Kilometres();\n    /// <summary>\n    /// Inch\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*inch;\n    /// </example>\n    public static readonly Length inch = 1.Inches();\n\n    /// <summary>\n    /// Inch\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*inches;\n    /// </example>\n    public static readonly Length inches = 1.Inches();\n\n    /// <summary>\n    /// Feet\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*ft;\n    /// </example>\n    public static readonly Length ft = 1.Feet();\n\n    /// <summary>\n    /// Feet\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*foot;\n    /// </example>\n    public static readonly Length foot = 1.Feet();\n\n    /// <summary>\n    /// Feet\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*feet;\n    /// </example>\n    public static readonly Length feet = 1.Feet();\n\n    /// <summary>\n    /// Yard\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*yd;\n    /// </example>\n    public static readonly Length yd = 1.Yards();\n\n    /// <summary>\n    /// Yard\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*yard;\n    /// </example>\n    public static readonly Length yard = 1.Yards();\n\n    /// <summary>\n    /// Yard\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*yards;\n    /// </example>\n    public static readonly Length yards = 1.Yards();\n\n    /// <summary>\n    /// Mile\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*mile;\n    /// </example>\n    public static readonly Length mile = 1.Miles();\n\n    /// <summary>\n    /// Mile\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*miles;\n    /// </example>\n    public static readonly Length miles = 1.Miles();\n\n    /// <summary>\n    /// NauticalMile\n    /// </summary>\n    /// <example>\n    ///     Length x = 7*nauticalMile;\n    /// </example>\n    public static readonly Length nauticalMile = 1.NauticalMiles();\n\n    /// <summary>\n    /// Millimetre squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 10*mm2;\n    /// </example>\n    public static readonly Area mm2 = 1.SqMillimetres();\n\n    /// <summary>\n    /// Millimetre squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 1*millimetre2;\n    /// </example>\n    public static readonly Area millimetre2 = 1.SqMillimetres();\n\n    /// <summary>\n    /// Millimeter squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 10*millimeter2;\n    /// </example>\n    public static readonly Area millimeter2 = 1.SqMillimetres();\n\n    /// <summary>\n    /// Centimetre squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 100*cm2;\n    /// </example>\n    public static readonly Area cm2 = 1.SqCentimetres();\n\n    /// <summary>\n    /// Centimetre squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 100*centimetre2;\n    /// </example>\n    public static readonly Area centimetre2 = 1.SqCentimetres();\n\n    /// <summary>\n    /// Centimeter squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 100*centimeter2;\n    /// </example>\n    public static readonly Area centimeter2 = 1.SqCentimetres();\n\n    /// <summary>\n    /// Metre squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 10*m2;\n    /// </example>\n    public static readonly Area m2 = 1.SqMetres();\n\n    /// <summary>\n    /// Metre squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 10*metre2;\n    /// </example>\n    public static readonly Area metre2 = 1.SqMetres();\n\n    /// <summary>\n    /// Meter squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 10*meter2;\n    /// </example>\n    public static readonly Area meter2 = 1.SqMetres();\n\n    /// <summary>\n    /// Kilometre squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 7*km2;\n    /// </example>\n    public static readonly Area km2 = 1.SqKilometres();\n\n    /// <summary>\n    /// Kilometre squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 7*kilometre2;\n    /// </example>\n    public static readonly Area kilometre2 = 1.SqKilometres();\n\n    /// <summary>\n    /// Kilometer squared\n    /// </summary>\n    /// <example>\n    ///     Area x = 7*kilometer2;\n    /// </example>\n    public static readonly Area kilometer2 = 1.SqKilometres();\n\n    /// <summary>\n    /// Second\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*s;\n    /// </example>\n    public static readonly Time s = 1.Seconds();\n\n    /// <summary>\n    /// Second\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*sec;\n    /// </example>\n    public static readonly Time sec = 1.Seconds();\n\n    /// <summary>\n    /// Second\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*second;\n    /// </example>\n    public static readonly Time second = 1.Seconds();\n\n    /// <summary>\n    /// Second\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*seconds;\n    /// </example>\n    public static readonly Time seconds = 1.Seconds();\n\n    /// <summary>\n    /// Minute\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*min;\n    /// </example>\n    public static readonly Time min = 1.Minutes();\n\n    /// <summary>\n    /// Minute\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*mins;\n    /// </example>\n    public static readonly Time mins = 1.Minutes();\n\n    /// <summary>\n    /// Minute\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*minute;\n    /// </example>\n    public static readonly Time minute = 1.Minutes();\n\n    /// <summary>\n    /// Minute\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*minutes;\n    /// </example>\n    public static readonly Time minutes = 1.Minutes();\n\n    /// <summary>\n    /// Hour\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*hr;\n    /// </example>\n    public static readonly Time hr = 1.Hours();\n\n    /// <summary>\n    /// Hour\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*hrs;\n    /// </example>\n    public static readonly Time hrs = 1.Hours();\n\n    /// <summary>\n    /// Hour\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*hour;\n    /// </example>\n    public static readonly Time hour = 1.Hours();\n\n    /// <summary>\n    /// Hour\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*hours;\n    /// </example>\n    public static readonly Time hours = 1.Hours();\n\n    /// <summary>\n    /// Day\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*day;\n    /// </example>\n    public static readonly Time day = 1.Days();\n\n    /// <summary>\n    /// Day\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*days;\n    /// </example>\n    public static readonly Time days = 1.Days();\n\n    /// <summary>\n    /// Millisecond\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*ms;\n    /// </example>\n    public static readonly Time ms = 1.Milliseconds();\n\n    /// <summary>\n    /// Millisecond\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*millisecond;\n    /// </example>\n    public static readonly Time millisecond = 1.Milliseconds();\n\n    /// <summary>\n    /// Millisecond\n    /// </summary>\n    /// <example>\n    ///     Time x = 7*milliseconds;\n    /// </example>\n    public static readonly Time milliseconds = 1.Milliseconds();\n\n    /// <summary>\n    /// Miles per hour\n    /// </summary>\n    public static readonly Velocity mph = miles /hour;\n\n    /// <summary>\n    /// Kilometres per hour\n    /// </summary>\n    public static readonly Velocity kph = km /hour;\n\n    /// <summary>\n    /// Metres per-second squared\n    /// </summary>\n    public static readonly Accel ms2 = m /s /s;\n\n    /// <summary>\n    /// Degrees Celsius\n    /// </summary>\n    public static readonly Temperature degC = new (Temperature.UnitType.C, 1);\n\n    /// <summary>\n    /// Degrees Fahrenheit\n    /// </summary>\n    public static readonly Temperature degF = new (Temperature.UnitType.F, 1);\n\n    /// <summary>\n    /// kelvin\n    /// </summary>\n    public static readonly Temperature K = new (Temperature.UnitType.K, 1);\n\n    /// <summary>\n    /// Gram\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*g;\n    /// </example>\n    public static readonly Mass g = 1.Grams();\n\n    /// <summary>\n    /// Gram\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*gram;\n    /// </example>\n    public static readonly Mass gram = 1.Grams();\n\n    /// <summary>\n    /// Kilogram\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*kg;\n    /// </example>\n    public static readonly Mass kg = 1.Kilograms();\n\n    /// <summary>\n    /// Kilogram\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*kilogram;\n    /// </example>\n    public static readonly Mass kilogram = 1.Kilograms();\n\n    /// <summary>\n    /// Tonne\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*tonne;\n    /// </example>\n    public static readonly Mass tonne = 1.Tonnes();\n\n    /// <summary>\n    /// Ounce\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*oz;\n    /// </example>\n    public static readonly Mass oz = 1.Ounces();\n\n    /// <summary>\n    /// Ounce\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*ounce;\n    /// </example>\n    public static readonly Mass ounce = 1.Ounces();\n\n    /// <summary>\n    /// Pound\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*lb;\n    /// </example>\n    public static readonly Mass lb = 1.Pounds();\n\n    /// <summary>\n    /// Pound\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*pound;\n    /// </example>\n    public static readonly Mass pound = 1.Pounds();\n\n    /// <summary>\n    /// Stone\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*st;\n    /// </example>\n    public static readonly Mass st = 1.Stones();\n\n    /// <summary>\n    /// Stone\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*stone;\n    /// </example>\n    public static readonly Mass stone = 1.Stones();\n\n    /// <summary>\n    /// ImperialTons\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*ton;\n    /// </example>\n    public static readonly Mass ton = 1.ImperialTons();\n\n    /// <summary>\n    /// ShortTon\n    /// </summary>\n    /// <example>\n    ///    Mass x = 10*shortTon;\n    /// </example>\n    public static readonly Mass shortTon = 1.ShortTon();\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/Temperature.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic readonly struct Temperature :\n    IComparable<Temperature>,\n    IEquatable<Temperature>,\n    IComparable\n{\n    internal enum UnitType\n    {\n        K, C, F\n    }\n\n    readonly UnitType Type;\n    readonly double Value;\n\n    public static Temperature AbsoluteZero = default;\n    public static Temperature ZeroCelsius = new (UnitType.C, 0.0);\n    public static Temperature ZeroFahrenheit = new (UnitType.F, 0.0);\n\n    internal Temperature(UnitType type, double value)\n    {\n        Type  = type;\n        Value = value;\n\n        if (this < AbsoluteZero) throw new ArgumentOutOfRangeException(nameof(value), $\"{value} [{type}]\", \"Less than absolute zero\");\n    }\n    \n    public static Temperature FromCelcius(double value) =>\n        new (UnitType.C, value);\n    \n    public static Temperature FromFahrenheit(double value) =>\n        new (UnitType.F, value);\n    \n    public static Temperature FromKelvin(double value) =>\n        new (UnitType.K, value);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static double CtoK(double x) => x + 273.15;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static double KtoC(double x) => x - 273.15;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static double FtoK(double x) => (x + 459.67) * 5.0 / 9.0;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static double KtoF(double x) => (x * 1.8) - 459.67;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static double CtoF(double x) => (x * 1.8) + 32.0;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    static double FtoC(double x) => (x - 32.0) * 5.0 / 9.0;\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public override bool Equals(object? obj) =>\n        obj is Temperature t && Equals(t);\n\n    public bool Equals(Temperature rhs) =>\n        Value.Equals(rhs.Value);\n\n    public override string ToString() =>\n        Type switch\n        {\n            UnitType.K => $\"{Value} K\",\n            UnitType.C => $\"{Value} °C\",\n            UnitType.F => $\"{Value} °F\",\n            _          => throw new NotSupportedException(Type.ToString())\n        };\n\n    public Temperature Kelvin =>\n        Type switch\n        {\n            UnitType.K => this,\n            UnitType.C => new Temperature(UnitType.K, CtoK(Value)),\n            UnitType.F => new Temperature(UnitType.K, FtoK(Value)),\n            _          => throw new NotSupportedException(Type.ToString())\n        };\n\n    public double KValue =>\n        Type switch\n        {\n            UnitType.K => Value,\n            UnitType.C => CtoK(Value),\n            UnitType.F => FtoK(Value),\n            _          => throw new NotSupportedException(Type.ToString())\n        };\n\n    public Temperature Celsius =>\n        Type switch\n        {\n            UnitType.K => new Temperature(UnitType.C, KtoC(Value)),\n            UnitType.C => this,\n            UnitType.F => new Temperature(UnitType.C, FtoC(Value)),\n            _          => throw new NotSupportedException(Type.ToString())\n        };\n\n    public Temperature Fahrenheit =>\n        Type switch\n        {\n            UnitType.K => new Temperature(UnitType.F, KtoF(Value)),\n            UnitType.C => new Temperature(UnitType.F, CtoF(Value)),\n            UnitType.F => this,\n            _          => throw new NotSupportedException(Type.ToString())\n        };\n\n    public bool Equals(Temperature rhs, double epsilon) =>\n        Type switch\n        {\n            UnitType.K => rhs.Type switch\n                          {\n                              UnitType.K => Math.Abs(rhs.Value       - Value) < epsilon,\n                              UnitType.C => Math.Abs(CtoK(rhs.Value) - Value) < epsilon,\n                              UnitType.F => Math.Abs(FtoK(rhs.Value) - Value) < epsilon,\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.C => rhs.Type switch\n                          {\n                              UnitType.K => Math.Abs(KtoC(rhs.Value) - Value) < epsilon,\n                              UnitType.C => Math.Abs(rhs.Value       - Value) < epsilon,\n                              UnitType.F => Math.Abs(FtoC(rhs.Value) - Value) < epsilon,\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.F => rhs.Type switch\n                          {\n                              UnitType.K => Math.Abs(KtoF(rhs.Value) - Value) < epsilon,\n                              UnitType.C => Math.Abs(CtoF(rhs.Value) - Value) < epsilon,\n                              UnitType.F => Math.Abs(rhs.Value       - Value) < epsilon,\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            _ => throw new NotSupportedException(Type.ToString())\n        };\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null              => 1,\n            Temperature other => CompareTo(other),\n            _                 => throw new ArgumentException($\"must be of type {nameof(Temperature)}\")\n        };\n\n    public int CompareTo(Temperature rhs) =>\n        Type switch\n        {\n            UnitType.K => rhs.Type switch\n                          {\n                              UnitType.K => Value.CompareTo(rhs.Value),\n                              UnitType.C => Value.CompareTo(CtoK(rhs.Value)),\n                              UnitType.F => Value.CompareTo(FtoK(rhs.Value)),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.C => rhs.Type switch\n                          {\n                              UnitType.K => Value.CompareTo(KtoC(rhs.Value)),\n                              UnitType.C => Value.CompareTo(rhs.Value),\n                              UnitType.F => Value.CompareTo(FtoC(rhs.Value)),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.F => rhs.Type switch\n                          {\n                              UnitType.K => Value.CompareTo(KtoF(rhs.Value)),\n                              UnitType.C => Value.CompareTo(CtoF(rhs.Value)),\n                              UnitType.F => Value.CompareTo(rhs.Value),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            _ => throw new NotSupportedException(Type.ToString())\n        };\n\n    public Temperature Add(Temperature rhs) =>\n        Type switch\n        {\n            UnitType.K => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.K, Value + rhs.Value),\n                              UnitType.C => new Temperature(UnitType.K, Value + CtoK(rhs.Value)),\n                              UnitType.F => new Temperature(UnitType.K, Value + FtoK(rhs.Value)),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.C => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.C, Value + KtoC(rhs.Value)),\n                              UnitType.C => new Temperature(UnitType.C, Value + rhs.Value),\n                              UnitType.F => new Temperature(UnitType.C, Value + FtoC(rhs.Value)),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.F => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.F, Value + KtoF(rhs.Value)),\n                              UnitType.C => new Temperature(UnitType.F, Value + CtoF(rhs.Value)),\n                              UnitType.F => new Temperature(UnitType.F, Value + rhs.Value),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            _ => throw new NotSupportedException(Type.ToString())\n        }; \n\n    public Temperature Add(double rhs) =>\n        new (Type, Value + rhs);\n    \n    public Temperature Subtract(Temperature rhs) =>\n        Type switch\n        {\n            UnitType.K => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.K, Value - rhs.Value),\n                              UnitType.C => new Temperature(UnitType.K, Value - CtoK(rhs.Value)),\n                              UnitType.F => new Temperature(UnitType.K, Value - FtoK(rhs.Value)),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.C => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.C, Value - KtoC(rhs.Value)),\n                              UnitType.C => new Temperature(UnitType.C, Value - rhs.Value),\n                              UnitType.F => new Temperature(UnitType.C, Value - FtoC(rhs.Value)),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.F => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.F, Value - KtoF(rhs.Value)),\n                              UnitType.C => new Temperature(UnitType.F, Value - CtoF(rhs.Value)),\n                              UnitType.F => new Temperature(UnitType.F, Value - rhs.Value),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            _ => throw new NotSupportedException(Type.ToString())\n        };\n\n    public Temperature Subtract(double rhs) =>\n        new (Type, Value + rhs);\n\n    public Temperature Multiply(double rhs) =>\n        new (Type, Value * rhs);\n\n    public Temperature Divide(double rhs) =>\n        new (Type, Value / rhs);\n\n    public static Temperature operator *(Temperature lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static Temperature operator *(double lhs, Temperature rhs) =>\n        rhs.Multiply(lhs);\n\n    public static Temperature operator +(Temperature lhs, Temperature rhs) =>\n        lhs.Add(rhs);\n\n    public static Temperature operator +(Temperature lhs, double rhs) =>\n        lhs.Add(rhs);\n\n    public static Temperature operator -(Temperature lhs, Temperature rhs) =>\n        lhs.Subtract(rhs);\n\n    public static Temperature operator -(Temperature lhs, double rhs) =>\n        lhs.Subtract(rhs);\n\n    public static Temperature operator /(Temperature lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static bool operator ==(Temperature lhs, Temperature rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(Temperature lhs, Temperature rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(Temperature lhs, Temperature rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    public static bool operator <(Temperature lhs, Temperature rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    public static bool operator >=(Temperature lhs, Temperature rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    public static bool operator <=(Temperature lhs, Temperature rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    public Temperature Round() =>\n        new (Type, Math.Round(Value));\n\n    public Temperature Abs() =>\n        new (Type, Math.Abs(Value));\n\n    public Temperature Min(Temperature rhs) =>\n        Type switch\n        {\n            UnitType.K => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.K, Math.Min(Value, rhs.Value)),\n                              UnitType.C => new Temperature(UnitType.K, Math.Min(Value, CtoK(rhs.Value))),\n                              UnitType.F => new Temperature(UnitType.K, Math.Min(Value, FtoK(rhs.Value))),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.C => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.C, Math.Min(Value, KtoC(rhs.Value))),\n                              UnitType.C => new Temperature(UnitType.C, Math.Min(Value, rhs.Value)),\n                              UnitType.F => new Temperature(UnitType.C, Math.Min(Value, FtoC(rhs.Value))),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.F => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.F, Math.Min(Value, KtoF(rhs.Value))),\n                              UnitType.C => new Temperature(UnitType.F, Math.Min(Value, CtoF(rhs.Value))),\n                              UnitType.F => new Temperature(UnitType.F, Math.Min(Value, rhs.Value)),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            _ => throw new NotSupportedException(Type.ToString())\n        };\n    \n    public Temperature Max(Temperature rhs) =>\n        Type switch\n        {\n            UnitType.K => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.K, Math.Max(Value, rhs.Value)),\n                              UnitType.C => new Temperature(UnitType.K, Math.Max(Value, CtoK(rhs.Value))),\n                              UnitType.F => new Temperature(UnitType.K, Math.Max(Value, FtoK(rhs.Value))),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.C => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.C, Math.Max(Value, KtoC(rhs.Value))),\n                              UnitType.C => new Temperature(UnitType.C, Math.Max(Value, rhs.Value)),\n                              UnitType.F => new Temperature(UnitType.C, Math.Max(Value, FtoC(rhs.Value))),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            UnitType.F => rhs.Type switch\n                          {\n                              UnitType.K => new Temperature(UnitType.F, Math.Max(Value, KtoF(rhs.Value))),\n                              UnitType.C => new Temperature(UnitType.F, Math.Max(Value, CtoF(rhs.Value))),\n                              UnitType.F => new Temperature(UnitType.F, Math.Max(Value, rhs.Value)),\n                              _          => throw new NotSupportedException(Type.ToString())\n                          },\n            _ => throw new NotSupportedException(Type.ToString())\n        };\n}\n\npublic static class UnitsTemperatureExtensions\n{\n    public static Temperature Celsius(this int self) =>\n        new (Temperature.UnitType.C, self);\n\n    public static Temperature Celsius(this float self) =>\n        new (Temperature.UnitType.C, self);\n\n    public static Temperature Celsius(this double self) =>\n        new (Temperature.UnitType.C, self);\n\n    public static Temperature Fahrenheit(this int self) =>\n        new (Temperature.UnitType.F, self);\n\n    public static Temperature Fahrenheit(this float self) =>\n        new (Temperature.UnitType.F, self);\n\n    public static Temperature Fahrenheit(this double self) =>\n        new (Temperature.UnitType.F, self);\n\n    public static Temperature Kelvin(this int self) =>\n        new (Temperature.UnitType.K, self);\n\n    public static Temperature Kelvin(this float self) =>\n        new (Temperature.UnitType.K, self);\n\n    public static Temperature Kelvin(this double self) =>\n        new (Temperature.UnitType.K, self);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/Time.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Numeric time-span value\n/// Handles unit conversions automatically\n/// All standard arithmetic operators work on the Time\n/// type.  So keep all Times wrapped until you need the\n/// value, then extract using various unit-of-measure\n/// accessors (Milliseconds, Seconds, etc.) or divide by 1.Second()\n/// Implicitly convertible to TimeSpan\n/// </summary>\npublic readonly struct Time :\n    IComparable<Time>,\n    IEquatable<Time>,\n    IComparable\n{\n    readonly double Value;\n\n    internal Time(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        Value + \" s\";\n\n    public bool Equals(Time other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(Time other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is Time time && Equals(time);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null       => 1,\n            Time other => CompareTo(other),\n            _          => throw new ArgumentException($\"must be of type {nameof(Time)}\")\n        };\n\n    public int CompareTo(Time other) =>\n        Value.CompareTo(other.Value);\n\n    public Time Add(Time rhs) =>\n        new (Value + rhs.Value);\n\n    public Time Subtract(Time rhs) =>\n        new (Value - rhs.Value);\n\n    public Time Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public Time Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static Time operator *(Time lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static Time operator *(double lhs, Time rhs) =>\n        rhs.Multiply(lhs);\n\n    public static TimeSq operator *(Time lhs, Time rhs) =>\n        new (lhs.Value * rhs.Value);\n\n    public static TimeSq operator ^(Time lhs, int power) =>\n        power == 2\n            ? new TimeSq(lhs.Value * lhs.Value)\n            : raise<TimeSq>(new NotSupportedException(\"Time can only be raised to the power of 2\"));\n\n    public static Time operator /(Time lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static Time operator +(Time lhs, Time rhs) =>\n        lhs.Add(rhs);\n\n    public static DateTime operator +(DateTime lhs, Time rhs) =>\n        lhs.AddSeconds(rhs.Seconds);\n\n    public static Time operator -(Time lhs, Time rhs) =>\n        lhs.Subtract(rhs);\n\n    public static DateTime operator -(DateTime lhs, Time rhs) =>\n        lhs.AddSeconds(-rhs.Seconds);\n\n    public static double operator /(Time lhs, Time rhs) =>\n        lhs.Value / rhs.Value;\n\n    public static bool operator ==(Time lhs, Time rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(Time lhs, Time rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(Time lhs, Time rhs) =>\n        lhs.Value > rhs.Value;\n\n    public static bool operator <(Time lhs, Time rhs) =>\n        lhs.Value < rhs.Value;\n\n    public static bool operator >=(Time lhs, Time rhs) =>\n        lhs.Value >= rhs.Value;\n\n    public static bool operator <=(Time lhs, Time rhs) =>\n        lhs.Value <= rhs.Value;\n\n    public Time Pow(double power) =>\n        new (Math.Pow(Value, power));\n\n    public Time Round() =>\n        new (Math.Round(Value));\n\n    public Time Sqrt() =>\n        new (Math.Sqrt(Value));\n\n    public Time Abs() =>\n        new (Math.Abs(Value));\n\n    public Time Min(Time rhs) =>\n        new (Math.Min(Value, rhs.Value));\n\n    public Time Max(Time rhs) =>\n        new (Math.Max(Value, rhs.Value));\n\n    public TimeSpan ToTimeSpan() =>\n        TimeSpan.FromSeconds(Value);\n\n    public static implicit operator TimeSpan(Time value) =>\n        value.ToTimeSpan();\n\n    public static implicit operator Time(TimeSpan value) =>\n        new (value.TotalSeconds);\n\n    public double Seconds       => Value;\n    public double Milliseconds  => Value * 1000.0;\n    public double Minutes       => Value / 60.0;\n    public double Hours         => Value / 3600.0;\n    public double Days          => Value / 86400.0;\n}\n\npublic static class UnitsTimeExtensions\n{\n    public static Time Milliseconds(this int self) =>\n        new (self / 1000.0);\n\n    public static Time Milliseconds(this float self) =>\n        new (self / 1000.0);\n\n    public static Time Milliseconds(this double self) =>\n        new (self / 1000.0);\n\n    public static Time Seconds(this int self) =>\n        new (self);\n\n    public static Time Seconds(this float self) =>\n        new (self);\n\n    public static Time Seconds(this double self) =>\n        new (self);\n\n    public static Time Minutes(this int self) =>\n        new (self * 60.0);\n\n    public static Time Minutes(this float self) =>\n        new (self * 60.0);\n\n    public static Time Minutes(this double self) =>\n        new (self * 60.0);\n\n    public static Time Hours(this int self) =>\n        new (self * 3600.0);\n\n    public static Time Hours(this float self) =>\n        new (self * 3600.0);\n\n    public static Time Hours(this double self) =>\n        new (self * 3600.0);\n\n    public static Time Days(this int self) =>\n        new (self * 86400.0);\n\n    public static Time Days(this float self) =>\n        new (self * 86400.0);\n\n    public static Time Days(this double self) =>\n        new (self * 86400.0);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/TimeSq.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Numeric time-span squared value\n/// </summary>\npublic readonly struct TimeSq :\n    IComparable<TimeSq>,\n    IEquatable<TimeSq>,\n    IComparable\n{\n    readonly double Value;\n\n    internal TimeSq(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        Value + \" s²\";\n\n    public bool Equals(TimeSq other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(TimeSq other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is TimeSq sq && Equals(sq);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null         => 1,\n            TimeSq other => CompareTo(other),\n            _            => throw new ArgumentException($\"must be of type {nameof(TimeSq)}\")\n        };\n\n    public int CompareTo(TimeSq other) =>\n        Value.CompareTo(other.Value);\n\n    public TimeSq Add(TimeSq rhs) =>\n        new (Value + rhs.Value);\n\n    public TimeSq Subtract(TimeSq rhs) =>\n        new (Value - rhs.Value);\n\n    public TimeSq Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public TimeSq Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static TimeSq operator *(TimeSq lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static TimeSq operator *(double lhs, TimeSq rhs) =>\n        rhs.Multiply(lhs);\n\n    public static TimeSq operator /(TimeSq lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static TimeSq operator +(TimeSq lhs, TimeSq rhs) =>\n        lhs.Add(rhs);\n\n    public static TimeSq operator -(TimeSq lhs, TimeSq rhs) =>\n        lhs.Subtract(rhs);\n\n    public static double operator /(TimeSq lhs, TimeSq rhs) =>\n        lhs.Value / rhs.Value;\n\n    public static bool operator ==(TimeSq lhs, TimeSq rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(TimeSq lhs, TimeSq rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(TimeSq lhs, TimeSq rhs) =>\n        lhs.Value > rhs.Value;\n\n    public static bool operator <(TimeSq lhs, TimeSq rhs) =>\n        lhs.Value < rhs.Value;\n\n    public static bool operator >=(TimeSq lhs, TimeSq rhs) =>\n        lhs.Value >= rhs.Value;\n\n    public static bool operator <=(TimeSq lhs, TimeSq rhs) =>\n        lhs.Value <= rhs.Value;\n\n    public TimeSq Round() =>\n        new (Math.Round(Value));\n\n    public Time Sqrt() =>\n        new (Math.Sqrt(Value));\n\n    public TimeSq Abs() =>\n        new (Math.Abs(Value));\n\n    public TimeSq Min(TimeSq rhs) =>\n        new (Math.Min(Value, rhs.Value));\n\n    public TimeSq Max(TimeSq rhs) =>\n        new (Math.Max(Value, rhs.Value));\n\n    public double Seconds2 => Value;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/Velocity.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Numeric velocity value\n/// Handles unit conversions automatically\n/// Internally all speeds are stored as metres per second\n/// All standard arithmetic operators work on the Velocity\n/// type.  So keep all velocities wrapped until you need the\n/// value, then extract using various unit-of-measure\n/// accessors (MetresPerSecond, etc.) or divide by 1.MetrePerSecond()\n/// </summary>\npublic readonly struct Velocity :\n    IComparable<Velocity>,\n    IEquatable<Velocity>,\n    IComparable\n{\n    readonly double Value;\n\n    internal Velocity(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        $\"{Value} m/s\";\n\n    public bool Equals(Velocity other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(Velocity other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is Velocity velocity && Equals(velocity);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null           => 1,\n            Velocity other => CompareTo(other),\n            _              => throw new ArgumentException($\"must be of type {nameof(Velocity)}\")\n        };\n\n    public int CompareTo(Velocity other) =>\n        Value.CompareTo(other.Value);\n\n    public Velocity Add(Velocity rhs) =>\n        new (Value + rhs.Value);\n\n    public Velocity Subtract(Velocity rhs) =>\n        new (Value - rhs.Value);\n\n    public Velocity Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public Velocity Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static Velocity operator *(Velocity lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static Velocity operator *(double lhs, Velocity rhs) =>\n        rhs.Multiply(lhs);\n\n    public static Length operator *(Velocity lhs, Time rhs) =>\n        new (lhs.Value * rhs.Seconds);\n\n    public static Length operator *(Time lhs, Velocity rhs) =>\n        new (lhs.Seconds * rhs.Value);\n\n    public static VelocitySq operator *(Velocity lhs, Velocity rhs) =>\n        new (lhs.Value * rhs.Value);\n\n    public static VelocitySq operator ^(Velocity lhs, int power) =>\n        power == 2\n            ? new VelocitySq(lhs.Value * lhs.Value)\n            : raise<VelocitySq>(new NotSupportedException(\"Velocity can only be raised to the power of 2\"));\n\n    public static Velocity operator +(Velocity lhs, Velocity rhs) =>\n        lhs.Add(rhs);\n\n    public static Velocity operator -(Velocity lhs, Velocity rhs) =>\n        lhs.Subtract(rhs);\n\n    public static Velocity operator /(Velocity lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static double operator /(Velocity lhs, Velocity rhs) =>\n        lhs.Value / rhs.Value;\n\n    public static Accel operator /(Velocity lhs, Time rhs) =>\n        new (lhs.Value / rhs.Seconds);\n\n    public static Time operator /(Velocity lhs, Accel rhs) =>\n        new (lhs.Value / rhs.MetresPerSecond2);\n\n    public static bool operator ==(Velocity lhs, Velocity rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(Velocity lhs, Velocity rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(Velocity lhs, Velocity rhs) =>\n        lhs.Value > rhs.Value;\n\n    public static bool operator <(Velocity lhs, Velocity rhs) =>\n        lhs.Value < rhs.Value;\n\n    public static bool operator >=(Velocity lhs, Velocity rhs) =>\n        lhs.Value >= rhs.Value;\n\n    public static bool operator <=(Velocity lhs, Velocity rhs) =>\n        lhs.Value <= rhs.Value;\n\n    public Velocity Round() =>\n        new (Math.Round(Value));\n\n    public Velocity Abs() =>\n        new (Math.Abs(Value));\n\n    public Velocity Min(Velocity rhs) =>\n        new (Math.Min(Value, rhs.Value));\n\n    public Velocity Max(Velocity rhs) =>\n        new (Math.Max(Value, rhs.Value));\n\n    public double MetresPerSecond     => Value;\n    public double KilometresPerSecond => Value                                    / 1000.0;\n    public double KilometresPerHour   => Value / 1000.0                           * 3600.0;\n    public double MilesPerSecond      => Value                                    / 1609.344000006437376000025749504;\n    public double MilesPerHour        => Value / 1609.344000006437376000025749504 * 3600.0;\n    public double Knots               => Value                                    / 0.51444444444444;\n}\n\npublic static class UnitsVelocityExtensions\n{\n    public static Velocity MetresPerSecond(this int self) =>\n        new (self);\n\n    public static Velocity MetresPerSecond(this float self) =>\n        new (self);\n\n    public static Velocity MetresPerSecond(this double self) =>\n        new (self);\n\n    public static Velocity KilometresPerSecond(this int self) =>\n        new (self * 1000.0);\n\n    public static Velocity KilometresPerSecond(this float self) =>\n        new (self * 1000.0);\n\n    public static Velocity KilometresPerSecond(this double self) =>\n        new (self * 1000.0);\n\n    public static Velocity KilometresPerHour(this int self) =>\n        new (self * 1000.0 / 3600.0);\n\n    public static Velocity KilometresPerHour(this float self) =>\n        new (self * 1000.0 / 3600.0);\n\n    public static Velocity KilometresPerHour(this double self) =>\n        new (self * 1000.0 / 3600.0);\n\n    public static Velocity MilesPerSecond(this int self) =>\n        new (self * 1609.344000006437376000025749504);\n\n    public static Velocity MilesPerSecond(this float self) =>\n        new (self * 1609.344000006437376000025749504);\n\n    public static Velocity MilesPerSecond(this double self) =>\n        new (self * 1609.344000006437376000025749504);\n\n    public static Velocity MilesPerHour(this int self) =>\n        new (self * 1609.344000006437376000025749504 / 3600.0);\n\n    public static Velocity MilesPerHour(this float self) =>\n        new (self * 1609.344000006437376000025749504 / 3600.0);\n\n    public static Velocity MilesPerHour(this double self) =>\n        new (self * 1609.344000006437376000025749504 / 3600.0);\n\n    public static Velocity Knots(this int self) =>\n        new (self * 0.51444444444444);\n\n    public static Velocity Knots(this float self) =>\n        new(self * 0.51444444444444);\n\n    public static Velocity Knots(this double self) =>\n        new(self * 0.51444444444444);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Units of Measure/VelocitySq.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Numeric VelocitySquared value\n/// Handles unit conversions automatically\n/// </summary>\npublic readonly struct VelocitySq :\n    IComparable<VelocitySq>,\n    IEquatable<VelocitySq>,\n    IComparable\n{\n    readonly double Value;\n\n    internal VelocitySq(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        Value + \" m/s²\";\n\n    public bool Equals(VelocitySq other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(VelocitySq other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is VelocitySq sq && Equals(sq);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null             => 1,\n            VelocitySq other => CompareTo(other),\n            _                => throw new ArgumentException($\"must be of type {nameof(VelocitySq)}\")\n        };\n\n    public int CompareTo(VelocitySq other) =>\n        Value.CompareTo(other.Value);\n\n    public VelocitySq Add(VelocitySq rhs) =>\n        new (Value + rhs.Value);\n\n    public VelocitySq Subtract(VelocitySq rhs) =>\n        new (Value - rhs.Value);\n\n    public VelocitySq Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public VelocitySq Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static VelocitySq operator *(VelocitySq lhs, double rhs) =>\n        lhs.Multiply(rhs);\n\n    public static VelocitySq operator *(double lhs, VelocitySq rhs) =>\n        rhs.Multiply(lhs);\n\n    public static VelocitySq operator +(VelocitySq lhs, VelocitySq rhs) =>\n        lhs.Add(rhs);\n\n    public static VelocitySq operator -(VelocitySq lhs, VelocitySq rhs) =>\n        lhs.Subtract(rhs);\n\n    public static VelocitySq operator /(VelocitySq lhs, double rhs) =>\n        lhs.Divide(rhs);\n\n    public static double operator /(VelocitySq lhs, VelocitySq rhs) =>\n        lhs.Value / rhs.Value;\n\n    public static bool operator ==(VelocitySq lhs, VelocitySq rhs) =>\n        lhs.Equals(rhs);\n\n    public static bool operator !=(VelocitySq lhs, VelocitySq rhs) =>\n        !lhs.Equals(rhs);\n\n    public static bool operator >(VelocitySq lhs, VelocitySq rhs) =>\n        lhs.Value > rhs.Value;\n\n    public static bool operator <(VelocitySq lhs, VelocitySq rhs) =>\n        lhs.Value < rhs.Value;\n\n    public static bool operator >=(VelocitySq lhs, VelocitySq rhs) =>\n        lhs.Value >= rhs.Value;\n\n    public static bool operator <=(VelocitySq lhs, VelocitySq rhs) =>\n        lhs.Value <= rhs.Value;\n\n    public Velocity Sqrt() =>\n        new (Math.Sqrt(Value));\n\n    public VelocitySq Round() =>\n        new (Math.Round(Value));\n\n    public VelocitySq Abs() =>\n        new (Math.Abs(Value));\n\n    public VelocitySq Min(VelocitySq rhs) =>\n        new (Math.Min(Value, rhs.Value));\n\n    public VelocitySq Max(VelocitySq rhs) =>\n        new (Math.Max(Value, rhs.Value));\n\n    public double MetresPerSecond2 => Value;\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/AsyncEnumerableEx.cs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT License.\n// See the LICENSE file in the project root for more information. \n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Async.Linq;\n\nnamespace LanguageExt.LinqExtensionInternal;\n\npublic static class AsyncEnumerableEx\n{\n    /// <summary>\n    /// Merges elements from all the specified async-enumerable sequences into a single async-enumerable sequence.\n    /// </summary>\n    /// <typeparam name=\"TSource\">The type of the elements in the source sequences.</typeparam>\n    /// <param name=\"sources\">Async-enumerable sequences.</param>\n    /// <returns>The async-enumerable sequence that merges the elements of the async-enumerable sequences.</returns>\n    /// <exception cref=\"ArgumentNullException\"><paramref name=\"sources\"/> is null.</exception>\n    public static IAsyncEnumerable<TSource> Merge<TSource>(params IAsyncEnumerable<TSource>[] sources)\n    {\n        return Core(sources);\n\n        static async IAsyncEnumerable<TSource> Core(IAsyncEnumerable<TSource>[] sources,\n                                                    [System.Runtime.CompilerServices.EnumeratorCancellation]\n                                                    CancellationToken cancellationToken = default)\n        {\n            var count = sources.Length;\n\n            var enumerators   = new IAsyncEnumerator<TSource>[count];\n            var moveNextTasks = new ValueTask<bool>[count];\n\n            try\n            {\n                for (var i = 0; i < count; i++)\n                {\n                    var enumerator = sources[i].GetAsyncEnumerator(cancellationToken);\n                    enumerators[i] = enumerator;\n                    moveNextTasks[i] = enumerator.MoveNextAsync();\n                }\n\n                var whenAny = TaskExt.WhenAny(moveNextTasks);\n\n                int active = count;\n\n                while (active > 0)\n                {\n                    int index = await whenAny;\n\n                    var enumerator   = enumerators[index];\n                    var moveNextTask = moveNextTasks[index];\n\n                    if (!await moveNextTask.ConfigureAwait(false))\n                    {\n                        moveNextTasks[index] = new ValueTask<bool>();\n                        enumerators[index] = null!;\n                        await enumerator.DisposeAsync().ConfigureAwait(false);\n\n                        active--;\n                    }\n                    else\n                    {\n                        TSource item = enumerator.Current;\n\n                        whenAny.Replace(index, enumerator.MoveNextAsync());\n\n                        yield return item;\n                    }\n                }\n            }\n            finally\n            {\n\n                var errors = default(List<Exception>);\n\n                for (var i = count - 1; i >= 0; i--)\n                {\n                    var moveNextTask = moveNextTasks[i];\n                    var enumerator   = enumerators[i];\n\n                    try\n                    {\n                        try\n                        {\n                            _ = await moveNextTask.ConfigureAwait(false);\n                        }\n                        finally\n                        {\n                            if (enumerator != null!)\n                            {\n                                await enumerator.DisposeAsync().ConfigureAwait(false);\n                            }\n                        }\n                    }\n                    catch (Exception ex)\n                    {\n                        if (errors == null)\n                        {\n                            errors = new List<Exception>();\n                        }\n\n                        errors.Add(ex);\n                    }\n                }\n\n                if (errors != null)\n                {\n                    throw new AggregateException(errors);\n                }\n            }\n        }\n\n    }\n\n    /// <summary>\n    /// Merges elements from all inner async-enumerable sequences into a single async-enumerable sequence.\n    /// </summary>\n    /// <typeparam name=\"TSource\">The type of the elements in the source sequences.</typeparam>\n    /// <param name=\"sources\">Async-enumerable sequence of inner async-enumerable sequences.</param>\n    /// <returns>The async-enumerable sequence that merges the elements of the inner sequences.</returns>\n    /// <exception cref=\"ArgumentNullException\"><paramref name=\"sources\"/> is null.</exception>\n    public static IAsyncEnumerable<TSource> Merge<TSource>(\n        this IAsyncEnumerable<IAsyncEnumerable<TSource>> sources) =>\n        sources.SelectMany(source => source);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/Box.cs",
    "content": "﻿using System;\nusing System.Reflection.Emit;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Represents a boxed value, if and only if `A` is a `struct`.  This can be used\n    /// to stop unnecessary allocations when using generic types cast to `object`: the \n    /// Box isn't allocated for reference types and is for value-types.  Then access\n    /// is transparent via `GetValue`.\n    /// </summary>\n    internal class Box<A>\n    {\n        public readonly A Value;\n\n        public Box(A value) =>\n            Value = value;\n\n        public static readonly Func<A, object> New;\n        public static readonly Func<object, A> GetValue;\n\n        static Box()\n        {\n            New = typeof(A).IsValueType\n                ? MakeNewStruct()\n                : MakeNewClass();\n\n            GetValue = typeof(A).IsValueType\n                ? GetValueStruct()\n                : GetValueClass();\n        }\n\n        static Func<object, A> GetValueClass()\n        {\n            if (ILCapability.Available)\n            {\n                var dynamic = new DynamicMethod(\"GetValue_Class\", typeof(A), [typeof(object)], typeof(A).Module, true);\n                var il      = dynamic.GetILGenerator();\n\n                il.Emit(OpCodes.Ldarg_0);\n                il.Emit(OpCodes.Ret);\n\n                return (Func<object, A>)dynamic.CreateDelegate(typeof(Func<object, A>));\n            }\n            else\n            {\n                return x => (A)x;\n            }\n        }\n\n        static Func<object, A> GetValueStruct()\n        {\n            if (ILCapability.Available)\n            {\n                var field   = typeof(Box<A>).GetField(\"Value\");\n                var dynamic = new DynamicMethod(\"GetValue_Struct\", typeof(A), new[] { typeof(object) }, typeof(A).Module, true);\n                var il      = dynamic.GetILGenerator();\n\n                il.Emit(OpCodes.Ldarg_0);\n                il.Emit(OpCodes.Castclass, typeof(Box<A>));\n                il.Emit(OpCodes.Ldfld, field!);\n                il.Emit(OpCodes.Ret);\n\n                return (Func<object, A>)dynamic.CreateDelegate(typeof(Func<object, A>));\n            }\n            else\n            {\n                return (object x) => ((Box<A>)x).Value;\n            }\n        }\n\n        static Func<A, object> MakeNewClass()\n        {\n            if (ILCapability.Available)\n            {\n                var dynamic = new DynamicMethod(\"New_Class\", typeof(object), new[] {typeof(A)}, typeof(A).Module, true);\n                var il      = dynamic.GetILGenerator();\n\n                il.Emit(OpCodes.Ldarg_0);\n                il.Emit(OpCodes.Ret);\n\n                return (Func<A, object>)dynamic.CreateDelegate(typeof(Func<A, object>));\n            }\n            else\n            {\n                return static (A x) => (object?)x ?? throw new NullReferenceException();\n            }\n        }\n\n        static Func<A, object> MakeNewStruct()\n        {\n            if (ILCapability.Available)\n            {\n                var ctor    = typeof(Box<A>).GetConstructor(new[] {typeof(A)});\n                var dynamic = new DynamicMethod(\"New_Struct\", typeof(object), new[] {typeof(A)}, typeof(A).Module, true);\n                var il      = dynamic.GetILGenerator();\n\n                il.Emit(OpCodes.Ldarg_0);\n                il.Emit(OpCodes.Newobj, ctor!);\n                il.Emit(OpCodes.Ret);\n\n                return (Func<A, object>)dynamic.CreateDelegate(typeof(Func<A, object>));\n            }\n            else\n            {\n                return static (A x) => new Box<A>(x);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/Check.cs",
    "content": "﻿namespace LanguageExt\n{\n    internal static class Check\n    {\n        internal static T NullReturn<T>(T value) =>\n            Prelude.isnull(value)\n                ? Prelude.raise<T>(new ResultIsNullException())\n                : value;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/CollectionFormat.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\n\nnamespace LanguageExt\n{\n    public static class CollectionFormat\n    {\n        /// <summary>\n        /// Application wide setting for the maximum number of items \n        /// shown in a call to the `ToString` method of any LanguageExt \n        /// collection type.\n        /// </summary>\n        public static int MaxShortItems = 50;\n\n        internal static string ToShortString<A>(IEnumerable<A> ma, string separator = \", \")\n        {\n            var items = ma.Take(MaxShortItems).ToList();\n\n            return items.Count < MaxShortItems\n                ? $\"{String.Join(separator, items)}\"\n                : $\"{String.Join(separator, items)} ...\";\n        }\n\n        internal static string ToShortString<A>(IEnumerable<A> ma, int count, string separator = \", \") =>\n            count <= MaxShortItems\n                ? $\"{String.Join(separator, ma)}\"\n                : $\"{String.Join(separator, ma.Take(MaxShortItems))} ... {count - MaxShortItems} more\";\n\n        internal static string ToShortArrayString<A>(IEnumerable<A> ma, string separator = \", \") =>\n            $\"[{ToShortString(ma, separator)}]\";\n\n        internal static string ToShortArrayString<A>(IEnumerable<A> ma, int count, string separator = \", \") =>\n            $\"[{ToShortString(ma, count, separator)}]\";\n\n        internal static string ToFullString<A>(IEnumerable<A> ma, string separator = \", \") =>\n            $\"{String.Join(separator, ma)}\";\n\n        internal static string ToFullArrayString<A>(IEnumerable<A> ma, string separator = \", \") =>\n            $\"[{ToFullString(ma, separator)}]\";\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/Disposable.cs",
    "content": "using System;\n\nnamespace LanguageExt\n{\n    internal static class Disposable<A>\n    {\n        public static bool IsDisposable = typeof(IDisposable).IsAssignableFrom(typeof(A));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/EnumerableOptimal.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class EnumerableOptimal\n{\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static IEnumerable<A> ConcatFast<A>(this IEnumerable<A> ma, IEnumerable<A> mb) =>\n        ma is ConcatEnum<A> ca\n            ? ca.Concat(mb)\n            : new ConcatEnum<A>(Seq(ma, mb));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Iterable<A> ConcatFast<A>(this Iterable<A> ma, IEnumerable<A> mb) =>\n        ma.Concat(Iterable.createRange(mb));\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static IEnumerable<B> BindFast<A, B>(this IEnumerable<A>? ma, Func<A, IEnumerable<B>> f) =>\n        ma is null\n            ? System.Linq.Enumerable.Empty<B>()\n            : new BindEnum<A, B>(ma, f);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    internal static IEnumerable<B> BindFast<A, B>(this IEnumerable<A> ma, Func<A, Lst<B>> f) =>\n        ma == null\n            ? System.Linq.Enumerable.Empty<B>()\n            : new BindEnum<A, B>(ma, a => f(a).AsIterable());\n\n    internal class ConcatEnum<A>(Seq<IEnumerable<A>> ms) : IEnumerable<A>\n    {\n        internal readonly Seq<IEnumerable<A>> ms = ms;\n\n        public ConcatIter<A> GetEnumerator() => \n            new(ms);\n\n        public ConcatEnum<A> Concat(IEnumerable<A> cb) => \n            new(ms.Add(cb));\n\n        IEnumerator<A> IEnumerable<A>.GetEnumerator() =>\n            new ConcatIter<A>(ms);\n\n        IEnumerator IEnumerable.GetEnumerator() =>\n            new ConcatIter<A>(ms);\n    }\n\n    internal class BindEnum<A, B> : IEnumerable<B>\n    {\n        readonly IEnumerable<A> ma;\n        readonly Func<A, IEnumerable<B>> f;\n\n        public BindEnum(IEnumerable<A> ma, Func<A, IEnumerable<B>> f)\n        {\n            this.ma = ma;\n            this.f = f;\n        }\n\n        public BindIter<A, B> GetEnumerator() =>\n            new BindIter<A, B>(ma, f);\n\n        IEnumerator<B> IEnumerable<B>.GetEnumerator() =>\n            new BindIter<A, B>(ma, f);\n\n        IEnumerator IEnumerable.GetEnumerator() =>\n            new BindIter<A, B>(ma, f);\n    }\n\n    internal struct ConcatIter<A> : IEnumerator<A>\n    {\n        Seq<IEnumerable<A>> ms;\n        IEnumerator<A> iter;\n        int index;\n        A current;\n\n        public ConcatIter(Seq<IEnumerable<A>> ms)\n        {\n            this.ms = ms;\n            this.index = 0;\n            this.iter = ms[0].GetEnumerator();\n            current = default!;\n        }\n\n        public readonly A Current => \n            current;\n\n        readonly object IEnumerator.Current => \n            current!;\n\n        public void Dispose() =>\n            iter?.Dispose();\n\n        public bool MoveNext()\n        {\n            if (iter.MoveNext())\n            {\n                current = iter.Current;\n                return true;\n            }\n            else\n            {\n                current = default!;\n                index++;\n                while(index < ms.Count)\n                {\n                    iter.Dispose();\n                    iter = ms[index].GetEnumerator();\n                    if (iter.MoveNext())\n                    {\n                        current = iter.Current;\n                        return true;\n                    }\n                    else\n                    {\n                        index++;\n                        continue;\n                    }\n                }\n                iter.Dispose();\n                return false;\n            }\n        }\n\n        public void Reset()\n        {\n            Dispose();\n            index = 0;\n            iter = ms[0].GetEnumerator();\n        }\n    }\n\n    internal struct BindIter<A, B> : IEnumerator<B>\n    {\n        readonly Func<A, IEnumerable<B>> f;\n        readonly IEnumerable<A> ema;\n        IEnumerator<A>? ma;\n        IEnumerator<B>? mb;\n        B current;\n\n        public BindIter(IEnumerable<A> ma, Func<A, IEnumerable<B>> f)\n        {\n            this.ema = ma;\n            this.ma = ema.GetEnumerator();\n            this.mb = default!;\n            this.f = f;\n            current = default!;\n        }\n\n        public B Current =>\n            current;\n\n        object IEnumerator.Current =>\n            current!;\n\n        public void Dispose()\n        {\n            ma?.Dispose();\n            mb?.Dispose();\n        }\n\n        public bool MoveNext()\n        {\n            if (ma == null) return false;\n            if (mb == null)\n            {\n                while (ma.MoveNext())\n                {\n                    mb = f(ma.Current).GetEnumerator();\n                    if (mb.MoveNext())\n                    {\n                        current = mb.Current;\n                        return true;\n                    }\n                    else\n                    {\n                        continue;\n                    }\n                }\n                ma.Dispose();\n                ma = null;\n                return false;\n            }\n            else\n            {\n                if (mb.MoveNext())\n                {\n                    current = mb.Current;\n                    return true;\n                }\n                else\n                {\n                    mb.Dispose();\n                    mb = null;\n                    while (ma.MoveNext())\n                    {\n                        mb = f(ma.Current).GetEnumerator();\n                        if (mb.MoveNext())\n                        {\n                            current = mb.Current;\n                            return true;\n                        }\n                        else\n                        {\n                            continue;\n                        }\n                    }\n                    ma.Dispose();\n                    ma = null;\n                    return false;\n                }\n            }\n        }\n\n        public void Reset()\n        {\n            Dispose();\n            ma = ema.GetEnumerator();\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/Fnv.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Fowler–Noll–Vo 32bit hash function\n    /// </summary>\n    /// <remarks>\n    /// [Fowler–Noll–Vo hash function](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function)\n    /// </remarks>\n    internal static class FNV32\n    {\n        /// <summary>\n        /// Offset basis for a FNV-1 or FNV-1a 32 bit hash\n        /// </summary>\n        public const int OffsetBasis = -2128831035;\n\n        /// <summary>\n        /// Prime for FNV-1 or FNV-1a 32 bit hash\n        /// </summary>\n        public const int Prime = 16777619;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public static int Next(int hashA, int hashB)\n        {\n            unchecked\n            {\n                return (hashA ^ hashB) * Prime;\n            }\n        }\n\n        /// <summary>\n        /// Calculate the hash code for an array\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public static int Hash<HashA, A>(A[]? items, int offsetBasis = OffsetBasis) where HashA : Hashable<A>\n        {\n            int hash = offsetBasis;\n            if (items == null) return hash;\n\n            unchecked\n            {\n                Span<A> span = items;\n                foreach (var item in span)\n                {\n                    hash = Next(HashA.GetHashCode(item), hash);\n                }\n                return hash;\n            }\n        }\n\n        /// <summary>\n        /// Calculate the hash code for an array slice\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public static int Hash<HashA, A>(A[]? items, int start, int length, int offsetBasis = OffsetBasis) where HashA : Hashable<A>\n        {\n            int hash = offsetBasis;\n            if (items == null) return hash;\n\n            unchecked\n            {\n                var span = new Span<A>(items, start, length);\n                foreach (var item in span)\n                {\n                    hash = Next(HashA.GetHashCode(item), hash);\n                }\n                return hash;\n            }\n        }\n\n        /// <summary>\n        /// Calculate the hash code for an enumerable\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public static int Hash<HashA, A>(IEnumerable<A>? items, int offsetBasis = OffsetBasis) where HashA : Hashable<A>\n        {\n            int hash = offsetBasis;\n            if (items == null) return hash;\n\n            unchecked\n            {\n                foreach (var item in items)\n                {\n                    hash = Next(HashA.GetHashCode(item), hash);\n                }\n                return hash;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/IL.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing System.Reflection;\nusing System.Reflection.Emit;\nusing System.Runtime.Serialization;\nusing System.Text;\nusing LanguageExt.Traits.Resolve;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Reflect;\n\nnamespace LanguageExt;\n\npublic static class IL\n{\n    /// <summary>\n    /// Emits the IL to instantiate a type of R with a single argument to \n    /// the constructor\n    /// </summary>\n    public static Func<R> Ctor<R>()\n    {\n        var ctorInfo = GetConstructor<R>()\n           .IfNone(() => throw new ArgumentException($\"Constructor not found for type {typeof(R).FullName}\"));\n\n        var dynamic = new DynamicMethod(\"CreateInstance\",\n                                        ctorInfo.DeclaringType,\n                                        Type.EmptyTypes,\n                                        typeof(R).Module,\n                                        true);\n\n        var il = dynamic.GetILGenerator();\n        il.Emit(OpCodes.Newobj, ctorInfo);\n        il.Emit(OpCodes.Ret);\n\n        return (Func<R>)dynamic.CreateDelegate(typeof(Func<R>));\n    }\n\n    /// <summary>\n    /// Emits the IL to instantiate a type of R with a single argument to \n    /// the constructor\n    /// </summary>\n    public static Func<A, R> Ctor<A, R>()\n    {\n        var ctorInfo = GetConstructor<R, A>()\n           .IfNone(() => throw new ArgumentException($\"Constructor not found for type {typeof(R).FullName}\"));\n\n        var ctorParams = ctorInfo.GetParameters();\n\n        if (ILCapability.Available)\n        {\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            ctorInfo.DeclaringType,\n                                            ctorParams.Select(p => p.ParameterType).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Newobj, ctorInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, R>)dynamic.CreateDelegate(typeof(Func<A, R>));\n        }\n        else\n        {\n            var arg0 = Expression.Parameter(typeof(A), \"arg0\");\n            var expr = Expression.New(ctorInfo, arg0);\n            var lambda = Expression.Lambda<Func<A, R>>(expr, arg0);\n            return lambda.Compile();   \n        }\n    }\n\n    /// <summary>\n    /// Emits the IL to instantiate a type of R with two arguments to \n    /// the constructor\n    /// </summary>\n    public static Func<A, B, R> Ctor<A, B, R>()\n    {\n        var ctorInfo = GetConstructor<R, A, B>()\n           .IfNone(() => throw new ArgumentException($\"Constructor not found for type {typeof(R).FullName}\"));\n\n        var ctorParams = ctorInfo.GetParameters();\n\n        if (ILCapability.Available)\n        {\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            ctorInfo.DeclaringType,\n                                            ctorParams.Select(p => p.ParameterType).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Ldarg_1);\n            il.Emit(OpCodes.Newobj, ctorInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, B, R>)dynamic.CreateDelegate(typeof(Func<A, B, R>));\n        }\n        else\n        {\n            var arg0   = Expression.Parameter(typeof(A), \"arg0\");\n            var arg1   = Expression.Parameter(typeof(B), \"arg1\");\n            var expr   = Expression.New(ctorInfo, arg0, arg1);\n            var lambda = Expression.Lambda<Func<A, B, R>>(expr, arg0, arg1);\n            return lambda.Compile();   \n        }\n    }\n\n    /// <summary>\n    /// Emits the IL to instantiate a type of R with three arguments to \n    /// the constructor\n    /// </summary>\n    public static Func<A, B, C, R> Ctor<A, B, C, R>()\n    {\n        var ctorInfo = GetConstructor<R, A, B, C>()\n           .IfNone(() => throw new ArgumentException($\"Constructor not found for type {typeof(R).FullName}\"));\n\n        var ctorParams = ctorInfo.GetParameters();\n\n        if (ILCapability.Available)\n        {\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            ctorInfo.DeclaringType,\n                                            ctorParams.Select(p => p.ParameterType).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Ldarg_1);\n            il.Emit(OpCodes.Ldarg_2);\n            il.Emit(OpCodes.Newobj, ctorInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, B, C, R>)dynamic.CreateDelegate(typeof(Func<A, B, C, R>));\n        }\n        else\n        {\n            var arg0   = Expression.Parameter(typeof(A), \"arg0\");\n            var arg1   = Expression.Parameter(typeof(B), \"arg1\");\n            var arg2   = Expression.Parameter(typeof(C), \"arg2\");\n            var expr   = Expression.New(ctorInfo, arg0, arg1, arg2);\n            var lambda = Expression.Lambda<Func<A, B, C, R>>(expr, arg0, arg1, arg2);\n            return lambda.Compile();   \n        }\n    }\n\n    /// <summary>\n    /// Emits the IL to instantiate a type of R with four arguments to \n    /// the constructor\n    /// </summary>\n    public static Func<A, B, C, D, R> Ctor<A, B, C, D, R>()\n    {\n        var ctorInfo = GetConstructor<R, A, B, C, D>()\n           .IfNone(() => throw new ArgumentException($\"Constructor not found for type {typeof(R).FullName}\"));\n\n        if (ctorInfo == null) throw new ArgumentException($\"Constructor not found for type {typeof(R).FullName}\");\n\n        if (ILCapability.Available)\n        {\n            var ctorParams = ctorInfo.GetParameters();\n\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            ctorInfo.DeclaringType,\n                                            ctorParams.Select(p => p.ParameterType).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Ldarg_1);\n            il.Emit(OpCodes.Ldarg_2);\n            il.Emit(OpCodes.Ldarg_3);\n            il.Emit(OpCodes.Newobj, ctorInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, B, C, D, R>)dynamic.CreateDelegate(typeof(Func<A, B, C, D, R>));\n        }\n        else\n        {\n            var arg0   = Expression.Parameter(typeof(A), \"arg0\");\n            var arg1   = Expression.Parameter(typeof(B), \"arg1\");\n            var arg2   = Expression.Parameter(typeof(C), \"arg2\");\n            var arg3   = Expression.Parameter(typeof(D), \"arg3\");\n            var expr   = Expression.New(ctorInfo, arg0, arg1, arg2, arg3);\n            var lambda = Expression.Lambda<Func<A, B, C, D, R>>(expr, arg0, arg1, arg2, arg3);\n            return lambda.Compile();   \n        }\n    }\n\n    /// <summary>\n    /// Emits the IL to invoke a static method\n    /// </summary>\n    public static Option<Func<object, R>> Func1<TYPE, R>(Type arg1, Func<MethodInfo, bool>? methodPred = null)\n    {\n        methodPred ??= _ => true;\n\n        var methodInfo = typeof(TYPE)\n                        .GetTypeInfo()\n                        .GetAllMethods(true)\n                        .Where(x =>\n                         {\n                             if (!x.IsStatic) return false;\n                             var ps = x.GetParameters();\n                             if (ps.Length           != 1) return false;\n                             if (ps[0].ParameterType != arg1) return false;\n                             return methodPred(x);\n                         })\n                        .FirstOrDefault();\n\n        if (methodInfo == null) return None;\n\n        var methodParams = methodInfo.GetParameters();\n\n        if (ILCapability.Available)\n        {\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            typeof(R),\n                                            methodParams.Select(_ => typeof(object)).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.DeclareLocal(typeof(R));\n            il.Emit(OpCodes.Ldarg_0);\n            if (arg1.GetTypeInfo().IsValueType)\n            {\n                il.Emit(OpCodes.Unbox_Any, arg1);\n            }\n            else\n            {\n                il.Emit(OpCodes.Castclass, arg1);\n            }\n\n            il.Emit(OpCodes.Call, methodInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<object, R>)dynamic.CreateDelegate(typeof(Func<object, R>));\n        }\n        else\n        {\n            var larg1  = Expression.Parameter(typeof(object), \"arg1\");\n            var expr   = Expression.Call(methodInfo, Expression.Convert(larg1, arg1));\n            var lambda = Expression.Lambda<Func<object, R>>(expr, larg1);\n            return lambda.Compile();   \n        }\n    }\n\n    /// <summary>\n    /// Emits the IL to invoke a static method with one argument\n    /// </summary>\n    public static Option<Func<A, R>> Func1<TYPE, A, R>(Func<MethodInfo, bool>? methodPred = null)\n    {\n        methodPred ??= _ => true;\n\n        var methodInfo = typeof(TYPE)\n                        .GetTypeInfo()\n                        .GetAllMethods(true)\n                        .Where(x =>\n                         {\n                             if (!x.IsStatic) return false;\n                             var ps = x.GetParameters();\n                             if (ps.Length           != 1) return false;\n                             if (ps[0].ParameterType != typeof(A)) return false;\n                             return methodPred(x);\n                         })\n                        .FirstOrDefault();\n\n        if (methodInfo == null) return None;\n\n        if (ILCapability.Available)\n        {\n            var methodParams = methodInfo.GetParameters();\n\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            typeof(R),\n                                            methodParams.Select(p => p.ParameterType).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Call, methodInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, R>)dynamic.CreateDelegate(typeof(Func<A, R>));\n        }\n        else\n        {\n            var larg0  = Expression.Parameter(typeof(A), \"arg0\");\n            var expr   = Expression.Call(methodInfo, larg0);\n            var lambda = Expression.Lambda<Func<A, R>>(expr, larg0);\n            return lambda.Compile();\n        }\n    }\n\n    /// <summary>\n    /// Emits the IL to invoke a static method with two arguments\n    /// </summary>\n    public static Option<Func<A, B, R>> Func2<TYPE, A, B, R>(Func<MethodInfo, bool>? methodPred = null)\n    {\n        methodPred ??= _ => true;\n\n        var methodInfo = typeof(TYPE)\n                        .GetTypeInfo()\n                        .GetAllMethods(true)\n                        .Where(x =>\n                         {\n                             if (!x.IsStatic) return false;\n                             var ps = x.GetParameters();\n                             if (ps.Length           != 2) return false;\n                             if (ps[0].ParameterType != typeof(A)) return false;\n                             if (ps[1].ParameterType != typeof(B)) return false;\n                             return methodPred(x);\n                         })\n                        .FirstOrDefault();\n\n        if (methodInfo == null) return None;\n\n        if (ILCapability.Available)\n        {\n            var methodParams = methodInfo.GetParameters();\n\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            typeof(R),\n                                            methodParams.Select(p => p.ParameterType).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Ldarg_1);\n            il.Emit(OpCodes.Call, methodInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, B, R>)dynamic.CreateDelegate(typeof(Func<A, B, R>));\n        }\n        else\n        {\n            var larg0  = Expression.Parameter(typeof(A), \"arg0\");\n            var larg1  = Expression.Parameter(typeof(B), \"arg1\");\n            var expr   = Expression.Call(methodInfo, larg0, larg1);\n            var lambda = Expression.Lambda<Func<A, B, R>>(expr, larg0, larg1);\n            return lambda.Compile();\n        }\n    }\n\n    /// <summary>\n    /// Emits the IL to invoke a static method with three arguments\n    /// </summary>\n    public static Option<Func<A, B, C, R>> Func3<TYPE, A, B, C, R>(Func<MethodInfo, bool>? methodPred = null)\n    {\n        methodPred ??= _ => true;\n\n        var methodInfo = typeof(TYPE)\n                        .GetTypeInfo()\n                        .GetAllMethods(true)\n                        .Where(x =>\n                         {\n                             if (!x.IsStatic) return false;\n                             var ps = x.GetParameters();\n                             if (ps.Length           != 3) return false;\n                             if (ps[0].ParameterType != typeof(A)) return false;\n                             if (ps[1].ParameterType != typeof(B)) return false;\n                             if (ps[2].ParameterType != typeof(C)) return false;\n                             return methodPred(x);\n                         })\n                        .FirstOrDefault();\n\n        if (methodInfo == null) return None;\n\n        if(ILCapability.Available)\n        {\n            var methodParams = methodInfo.GetParameters();\n\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            typeof(R),\n                                            methodParams.Select(p => p.ParameterType).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Ldarg_1);\n            il.Emit(OpCodes.Ldarg_2);\n            il.Emit(OpCodes.Call, methodInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, B, C, R>)dynamic.CreateDelegate(typeof(Func<A, B, C, R>));\n        }\n        else\n        {\n            var larg0  = Expression.Parameter(typeof(A), \"arg0\");\n            var larg1  = Expression.Parameter(typeof(B), \"arg1\");\n            var larg2  = Expression.Parameter(typeof(C), \"arg2\");\n            var expr   = Expression.Call(methodInfo, larg0, larg1, larg2);\n            var lambda = Expression.Lambda<Func<A, B, C, R>>(expr, larg0, larg1, larg2);\n            return lambda.Compile();\n        }\n    }\n\n    /// <summary>\n    /// Emits the IL to invoke a static method with four arguments\n    /// </summary>\n    public static Option<Func<A, B, C, D, R>> Func4<TYPE, A, B, C, D, R>(Func<MethodInfo, bool>? methodPred = null)\n    {\n        methodPred ??= _ => true;\n\n        var methodInfo = typeof(TYPE)\n                        .GetTypeInfo()\n                        .GetAllMethods(true)\n                        .Where(x =>\n                         {\n                             if (!x.IsStatic) return false;\n                             var ps = x.GetParameters();\n                             if (ps.Length           != 4) return false;\n                             if (ps[0].ParameterType != typeof(A)) return false;\n                             if (ps[1].ParameterType != typeof(B)) return false;\n                             if (ps[2].ParameterType != typeof(C)) return false;\n                             if (ps[3].ParameterType != typeof(D)) return false;\n                             return methodPred(x);\n                         })\n                        .FirstOrDefault();\n\n        if (methodInfo == null) return None;\n\n        if (ILCapability.Available)\n        {\n            var methodParams = methodInfo.GetParameters();\n\n            var dynamic = new DynamicMethod(\"CreateInstance\",\n                                            typeof(R),\n                                            methodParams.Select(p => p.ParameterType).ToArray(),\n                                            typeof(R).Module,\n                                            true);\n\n            var il = dynamic.GetILGenerator();\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Ldarg_1);\n            il.Emit(OpCodes.Ldarg_2);\n            il.Emit(OpCodes.Ldarg_3);\n            il.Emit(OpCodes.Call, methodInfo);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, B, C, D, R>)dynamic.CreateDelegate(typeof(Func<A, B, C, D, R>));\n        }\n        else\n        {\n            var larg0  = Expression.Parameter(typeof(A), \"arg0\");\n            var larg1  = Expression.Parameter(typeof(B), \"arg1\");\n            var larg2  = Expression.Parameter(typeof(C), \"arg2\");\n            var larg3  = Expression.Parameter(typeof(D), \"arg3\");\n            var expr   = Expression.Call(methodInfo, larg0, larg1, larg2, larg3);\n            var lambda = Expression.Lambda<Func<A, B, C, D, R>>(expr, larg0, larg1, larg2, larg3);\n            return lambda.Compile();\n        }\n    }\n\n    /// <summary>\n    /// Builds a function to provide a hash-code for a record type.  the hash-code is built from\n    /// the hash-codes of all the *fields* that make up the type.  \n    /// </summary>\n    /// <remarks>You should cache the result of this method to reduce the work of building the IL \n    /// each time.  Better still use the `RecordType〈A〉` type to provide a cached version of these\n    /// results.\n    /// </remarks>\n    public static Func<A, int> GetHashCode<A>(bool includeBase)\n    {\n        var hashF = (HashableResolve<A>.Exists, EqResolve<A>.Exists, OrdResolve<A>.Exists) switch\n                         {\n                             (true, _, _) => HashableResolve<A>.GetHashCodeFunc,\n                             (_, true, _) => EqResolve<A>.GetHashCodeFunc,\n                             (_, _, true) => OrdResolve<A>.GetHashCodeFunc,\n                             _            => null\n                         };\n\n        if (hashF is not null) return hashF;\n\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonHashAttribute), \n            typeof(NonStructuralAttribute), \n            typeof(NonRecordAttribute));\n\n        var self = Expression.Parameter(typeof(A));\n\n        // Use 32-bit FNV hash parameters as signed values since .net GetHashCode returns a signed 32-bit integer.\n        var fnvOffsetBasis = Expression.Constant(-2128831035);\n        var fnvPrime = Expression.Constant(16777619);\n\n        var Null = Expression.Constant(null, typeof(A));\n        var refEq = Expression.ReferenceEqual(self, Null);\n\n        IEnumerable<Expression> Fields()\n        {\n            foreach (var field in fields)\n            {\n                var hashMethod = Resolver.GetHashCodeMethodAlways(field.FieldType);\n                yield return Expression.Call(\n                    null,\n                    hashMethod,\n                    Expression.PropertyOrField(self, field.Name)\n                );\n            }\n        }\n\n        // Implement FNV 1a hashing algorithm - [Fowler–Noll–Vo hash function](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash)\n        var expr = Fields()\n                  .AsIterable()\n                  .Fold(fnvOffsetBasis as Expression,\n                        (state, field) =>\n                            Expression.Multiply(\n                                fnvPrime,\n                                Expression.ExclusiveOr(\n                                    state,\n                                    field)));\n\n        var lambda = Expression.Lambda<Func<A, int>>(\n            typeof(A).GetTypeInfo().IsValueType\n                ? expr\n                : Expression.Condition(refEq, Expression.Constant(0), expr)\n          , self);\n\n        return lambda.Compile();\n    }\n\n    /// <summary>\n    /// Provides a function that compares two record type arguments (one of type A and one of \n    /// object) for structural equality, this first makes sure that the `Object` argument is of \n    /// type A and then compares the *fields* from each argument for equality and returns true if \n    /// all are equal.  \n    /// </summary>\n    /// <remarks>You should cache the result of this method to reduce the work of building the IL \n    /// each time.  Better still use the `RecordType〈A〉` type to provide a cached version of these\n    /// results.\n    /// </remarks>\n    public static Func<A, object, bool> Equals<A>(bool includeBase)\n    {\n        var eqF = (EqResolve<A>.Exists, OrdResolve<A>.Exists) switch\n                  {\n                      (true, _) => EqResolve<A>.EqualsFunc,\n                      (_, true) => OrdResolve<A>.EqualsFunc,\n                      _         => null\n                  };\n\n        if (eqF is not null)\n        {\n            return (lhs, rhs) => rhs is A r && eqF(lhs, r);\n        }\n\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonEqAttribute),\n            typeof(NonStructuralAttribute),\n            typeof(NonRecordAttribute));\n\n        var self = Expression.Parameter(typeof(A), \"self\");\n        var other = Expression.Parameter(typeof(object), \"other\");\n        var otherCast = Expression.Convert(other, typeof(A));\n        var True = Expression.Constant(true);\n\n        var NullA = Expression.Constant(null, typeof(A));\n        var NullObj = Expression.Constant(null, typeof(object));\n        var refEq = Expression.ReferenceEqual(self, other);\n        var notNullX = Expression.ReferenceNotEqual(self, NullA);\n        var notNullY = Expression.ReferenceNotEqual(other, NullObj);\n\n        var typeA = Expression.TypeEqual(self, typeof(A));\n        var typeB = Expression.TypeEqual(other, typeof(A));\n        var typesEqual = Expression.Equal(typeA, typeB);\n\n        var expr = Expression.AndAlso(\n            typesEqual,\n            fields\n               .AsIterable()\n               .Fold(True as Expression,\n                        (state, field) =>\n                            Expression.AndAlso(\n                                state,\n                                Expression.Call(\n                                    null,\n                                    Resolver.GetEqualsMethodAlways(field.FieldType),\n                                    Expression.PropertyOrField(self, field.Name),\n                                    Expression.PropertyOrField(otherCast, field.Name)))));\n\n        var orExpr = Expression.OrElse(refEq, Expression.AndAlso(notNullX, Expression.AndAlso(notNullY, expr)));\n\n        var lambda = Expression.Lambda<Func<A, object, bool>>(\n            typeof(A).GetTypeInfo().IsValueType\n                ? expr\n                : orExpr, self, other);\n\n        return lambda.Compile();\n    }\n\n    /// <summary>\n    /// Provides a function that compares two record type arguments for structural equality, this \n    /// first compares the *fields* from each argument for equality and returns true if all are \n    /// equal.  \n    /// </summary>\n    /// <remarks>You should cache the result of this method to reduce the work of building the IL \n    /// each time.  Better still use the `RecordType〈A〉` type to provide a cached version of these\n    /// results.\n    /// </remarks>\n    public static Func<A, A, bool> EqualsTyped<A>(bool includeBase)\n    {\n        var eqF = (EqResolve<A>.Exists, OrdResolve<A>.Exists) switch\n                  {\n                      (true, _) => EqResolve<A>.EqualsFunc,\n                      (_, true) => OrdResolve<A>.EqualsFunc,\n                      _         => null\n                  };\n\n        if (eqF is not null)\n        {\n            return eqF;\n        }\n\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonEqAttribute),\n            typeof(NonStructuralAttribute),\n            typeof(NonRecordAttribute)\n        );\n\n        var self = Expression.Parameter(typeof(A), \"self\");\n        var other = Expression.Parameter(typeof(A), \"other\");\n        var True = Expression.Constant(true);\n        var Null = Expression.Constant(null, typeof(A));\n        var refEq = Expression.ReferenceEqual(self, other);\n        var notNullX = Expression.ReferenceNotEqual(self, Null);\n        var notNullY = Expression.ReferenceNotEqual(other, Null);\n        var typeA = Expression.TypeEqual(self, typeof(A));\n        var typeB = Expression.TypeEqual(other, typeof(A));\n        var typesEqual = Expression.Equal(typeA, typeB);\n\n        var expr = Expression.AndAlso(\n            typesEqual,\n            fields\n               .AsIterable()\n               .Fold(True as Expression, (state, field) =>\n                            Expression.AndAlso(\n                                state,\n                                Expression.Call(\n                                        null, \n                                        Resolver.GetEqualsMethodAlways(field.FieldType),\n                                        Expression.PropertyOrField(self, field.Name),\n                                        Expression.PropertyOrField(other, field.Name)))));\n\n        var orExpr = Expression.OrElse(refEq,  Expression.AndAlso(notNullX, Expression.AndAlso(notNullY, expr)));\n\n        var lambda = Expression.Lambda<Func<A, A, bool>>(\n            typeof(A).GetTypeInfo().IsValueType\n                ? expr\n                : orExpr, self, other);\n\n        return lambda.Compile();\n    }\n\n    /// <summary>\n    /// Provides a function that compares two record type arguments for structural equality, this \n    /// compares the *fields* from each argument for equality and returns 0 if all are equal, -1 \n    /// if X is less than Y, and 1 if X is greater than Y.\n    /// </summary>\n    /// <remarks>You should cache the result of this method to reduce the work of building the IL \n    /// each time.  Better still use the `RecordType〈A〉` type to provide a cached version of these\n    /// results.\n    /// </remarks>\n    public static Func<A, A, int> Compare<A>(bool includeBase)\n    {\n        if (OrdResolve<A>.Exists)\n        {\n            return OrdResolve<A>.CompareFunc;\n        }\n\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonOrdAttribute),\n            typeof(NonStructuralAttribute),\n            typeof(NonRecordAttribute)\n        );\n\n        var self = Expression.Parameter(typeof(A), \"self\");\n        var other = Expression.Parameter(typeof(A), \"other\");\n        var Zero = Expression.Constant(0);\n        var Minus1 = Expression.Constant(-1);\n        var Plus1 = Expression.Constant(1);\n        var Null = Expression.Constant(null, typeof(A));\n        var refEq = Expression.ReferenceEqual(self, other);\n        var xIsNull = Expression.ReferenceEqual(self, Null);\n        var yIsNull = Expression.ReferenceEqual(other, Null);\n        var typeA = Expression.TypeEqual(self, typeof(A));\n        var typeB = Expression.TypeEqual(other, typeof(A));\n        var typesNotEqual = Expression.NotEqual(typeA, typeB);\n        var returnTarget = Expression.Label(typeof(int));\n        var ord = Expression.Variable(typeof(int), \"ord\");\n\n        IEnumerable<Expression[]> Fields()\n        {\n            foreach (var f in fields)\n            {\n                var m = Resolver.GetCompareMethodAlways(f.FieldType);\n\n                var comparer = Expression.Assign(\n                    ord,\n                    Expression.Call(\n                        null,\n                        m,\n                        Expression.PropertyOrField(self, f.Name),\n                        Expression.PropertyOrField(other, f.Name)));\n\n                if (f.FieldType.IsValueType)\n                {\n                    yield return [comparer];\n                }\n                else\n                { \n                    var fnull = Expression.Constant(null, f.FieldType);\n\n                    yield return\n                    [\n                        Expression.IfThen(\n                            Expression.And(\n                                Expression.ReferenceEqual(Expression.PropertyOrField(self, f.Name), fnull),\n                                Expression.IsFalse(Expression.ReferenceEqual(Expression.PropertyOrField(other, f.Name), fnull))),\n                            Expression.Return(returnTarget, Minus1)),\n\n                        Expression.IfThen(\n                            Expression.And(\n                                Expression.ReferenceEqual(Expression.PropertyOrField(other, f.Name), fnull),\n                                Expression.IsFalse(Expression.ReferenceEqual(Expression.PropertyOrField(self, f.Name), fnull))),\n                            Expression.Return(returnTarget, Plus1)),\n\n                        Expression.IfThenElse(\n                            Expression.ReferenceEqual(\n                                Expression.PropertyOrField(self, f.Name),\n                                Expression.PropertyOrField(other, f.Name)),\n                            Expression.Assign(ord, Zero),\n                            comparer) \n                    ];\n                }\n\n                yield return\n                [\n                    // Fields are not equal\n                    Expression.IfThen(\n                        Expression.NotEqual(ord, Zero),\n                        Expression.Return(returnTarget, ord, typeof(int)))\n                ];\n            }\n        }\n\n        var block =  Expression.Block(\n            new [] { ord },\n            new[] {\n                      Expression.IfThen(refEq, Expression.Return(returnTarget, Zero)),\n                      Expression.IfThen(xIsNull, Expression.Return(returnTarget, Minus1)),\n                      Expression.IfThen(yIsNull, Expression.Return(returnTarget, Plus1)),\n                      Expression.IfThen(typesNotEqual, Expression.Return(returnTarget, Minus1))\n                  }\n               .Concat( Fields().Bind(identity))\n               .Concat( new [] { Expression.Label(returnTarget, Zero) as Expression }));\n\n        var lambda = Expression.Lambda<Func<A, A, int>>(block, self, other);\n\n        return lambda.Compile();\n    }\n\n    static Func<A, string> ToStringExpr<A>(bool includeBase)\n    {\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonShowAttribute),\n            typeof(NonRecordAttribute)\n        ).ToArray();\n            \n        var stringBuilder = GetConstructor<StringBuilder>().IfNone(() => throw new ArgumentException($\"Constructor not found for StringBuilder\"));\n        var appendChar    = GetPublicInstanceMethod<StringBuilder, char>(\"Append\", true).IfNone(() => throw new ArgumentException($\"Append method found for StringBuilder\"));\n        var appendString  = GetPublicInstanceMethod<StringBuilder, string>(\"Append\", true).IfNone(() => throw new ArgumentException($\"Append method found for StringBuilder\"));\n        var toString      = GetPublicInstanceMethod<StringBuilder>(\"ToString\", false).IfNone(() => throw new ArgumentException($\"ToString method found for StringBuilder\"));\n        var name          = typeof(A).Name;\n        var self          = Expression.Parameter(typeof(A), \"self\");\n        var nullA         = Expression.Constant(null, typeof(A));\n        var nullStr       = Expression.Constant(null, typeof(string));\n        var sb            = Expression.Variable(typeof(StringBuilder), \"sb\");\n        var tmpStr        = Expression.Variable(typeof(string), \"tmpStr\");\n        var result        = Expression.Variable(typeof(string), \"result\");\n        var returnTarget  = Expression.Label(typeof(string));\n            \n        if (name.IndexOf('`') != -1) name = name.Split('`').AsIterable().Head.Value!;\n\n        Expression fieldExpr(FieldInfo field)\n        {\n            var convertToString = (GetPublicStaticMethod(typeof(Convert), \"ToString\", field.FieldType) ||\n                                   GetPublicStaticMethod(typeof(Convert), \"ToString\", typeof(object)))\n               .IfNone(() => throw new Exception());\n\n            return Expression.Block(\n                Expression.Assign(tmpStr, convertToString.GetParameters()[0].ParameterType == typeof(object)\n                                              ? Expression.Call(convertToString, Expression.Convert(Expression.Field(self, field), typeof(object)))\n                                              : Expression.Call(convertToString, Expression.Field(self, field))),\n                Expression.IfThenElse(\n                    Expression.ReferenceEqual(tmpStr, nullStr),\n                    Expression.Call(sb, appendString, Expression.Constant(\"null\")),\n                    Expression.Call(sb, appendString, tmpStr)));\n        }\n\n        var inner = Expression.Block(\n            fields.Select(fieldExpr).Intersperse(Expression.Call(sb, appendString, Expression.Constant(\", \"))));\n            \n        var outer = Expression.Block(\n            Expression.Assign(sb, Expression.New(stringBuilder)),\n            Expression.Call(sb, appendString, Expression.Constant(name)),\n            Expression.Call(sb, appendChar, Expression.Constant('(')),\n            inner,\n            Expression.Call(sb, appendChar, Expression.Constant(')')),\n            Expression.Assign(result, Expression.Call(sb, toString)));\n            \n        var expr = Expression.IfThenElse(\n            Expression.ReferenceEqual(self, nullA),\n            Expression.Assign(result, Expression.Constant(\"(null)\")),\n            outer);\n                                  \n        var block = Expression.Block(\n            new [] { tmpStr, sb, result },\n            expr,\n            Expression.Return(returnTarget, result),\n            Expression.Label(returnTarget, result));\n            \n        var lambda = Expression.Lambda<Func<A, string>>(block, self);\n\n        return lambda.Compile();\n    }\n\n    public static Func<A, string> ToString<A>(bool includeBase)\n    {\n        if (!ILCapability.Available)\n        {\n            return ToStringExpr<A>(includeBase);\n        }\n\n        var isValueType = typeof(A).GetTypeInfo().IsValueType;\n        var dynamic = new DynamicMethod(\"FieldsToString\", \n                                        typeof(string),\n                                        [typeof(A)],                                            \n                                        typeof(A).Module,\n                                        true);\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonShowAttribute),\n            typeof(NonRecordAttribute)\n        ).ToArray();\n        var stringBuilder = GetConstructor<StringBuilder>().IfNone(() => throw new ArgumentException($\"Constructor not found for StringBuilder\"));\n        var appendChar = GetPublicInstanceMethod<StringBuilder, char>(\"Append\", true).IfNone(() => throw new ArgumentException($\"Append method found for StringBuilder\"));\n        var appendString = GetPublicInstanceMethod<StringBuilder, string>(\"Append\", true).IfNone(() => throw new ArgumentException($\"Append method found for StringBuilder\"));\n        var toString = GetPublicInstanceMethod<Object>(\"ToString\", true).IfNone(() => throw new ArgumentException($\"ToString method found for Object\"));\n        var name = typeof(A).Name;\n        if (name.IndexOf('`') != -1) name = name.Split('`').AsIterable().Head.Value!;\n\n        var il = dynamic.GetILGenerator();\n        il.DeclareLocal(typeof(StringBuilder));\n        var notNull = il.DefineLabel();\n\n        if (!isValueType)\n        {\n            // Check reference == null\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(OpCodes.Brtrue_S, notNull);\n\n            // Is null so return \"(null)\"\n            il.Emit(OpCodes.Ldstr, \"(null)\");\n            il.Emit(OpCodes.Ret);\n\n            il.MarkLabel(notNull);\n        }\n\n        // var sb = new StringBuilder()\n        il.Emit(OpCodes.Newobj, stringBuilder);\n        il.Emit(OpCodes.Stloc_0);\n\n        // sb.Append('(')\n        il.Emit(OpCodes.Ldloc_0);\n        if (fields.Length == 0)\n        {\n            il.Emit(OpCodes.Ldstr, $\"{name}\");\n        }\n        else\n        {\n            il.Emit(OpCodes.Ldstr, $\"{name}(\");\n        }\n        il.Emit(OpCodes.Callvirt, appendString);\n        il.Emit(OpCodes.Pop);\n\n        bool first = true;\n        foreach (var field in fields)\n        {\n            var skipAppend = il.DefineLabel();\n\n            if (!first)\n            {\n                // sb.Append(\", \")\n                il.Emit(OpCodes.Ldloc_0);\n                il.Emit(OpCodes.Ldstr, \", \");\n                il.Emit(OpCodes.Callvirt, appendString);\n                il.Emit(OpCodes.Pop);\n            }\n\n            if (!field.FieldType.GetTypeInfo().IsValueType)\n            {\n                var fieldNotNull = il.DefineLabel();\n\n                // If(this.field == null)\n                il.Emit(OpCodes.Ldarg_0);\n                il.Emit(isValueType ? OpCodes.Ldflda : OpCodes.Ldfld, field);\n                il.Emit(OpCodes.Brtrue_S, fieldNotNull);\n\n                // sb.Append(\"null\")\n                il.Emit(OpCodes.Ldloc_0);\n                il.Emit(OpCodes.Ldstr, \"null\");\n                il.Emit(OpCodes.Callvirt, appendString);\n                il.Emit(OpCodes.Pop);\n\n                // continue\n                il.Emit(OpCodes.Br_S, skipAppend);\n                il.MarkLabel(fieldNotNull);\n            }\n\n            il.Emit(OpCodes.Ldloc_0); // sb\n            il.Emit(OpCodes.Ldarg_0); // this\n            il.Emit(isValueType ? OpCodes.Ldflda : OpCodes.Ldfld, field);\n\n            var convertToString = (GetPublicStaticMethod(typeof(Convert), \"ToString\", field.FieldType) ||\n                                   GetPublicStaticMethod(typeof(Convert), \"ToString\", typeof(object)))\n               .IfNone(() => throw new Exception());\n\n            if (field.FieldType.GetTypeInfo().IsValueType && \n                convertToString.GetParameters().AsIterable().Head.Value!.ParameterType == typeof(object))\n            {\n                il.Emit(OpCodes.Box, field.FieldType);\n            }\n\n            il.Emit(convertToString.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, convertToString);\n\n            il.Emit(OpCodes.Callvirt, appendString);\n            il.Emit(OpCodes.Pop);\n            il.MarkLabel(skipAppend);\n\n            first = false;\n        }\n\n        if (fields.Length > 0)\n        {\n            // Append(')')\n            il.Emit(OpCodes.Ldloc_0);\n            il.Emit(OpCodes.Ldc_I4_S, ')');\n            il.Emit(OpCodes.Callvirt, appendChar);\n            il.Emit(OpCodes.Pop);\n        }\n\n        // return sb.ToString()\n        il.Emit(OpCodes.Ldloc_0);\n        il.Emit(OpCodes.Callvirt, toString);\n        il.Emit(OpCodes.Ret);\n\n        return (Func<A, string>)dynamic.CreateDelegate(typeof(Func<A, string>));\n    }\n\n    static Action<A, SerializationInfo> GetObjectDataExpr<A>(bool includeBase)\n    {\n        var fields        = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonSerializedAttribute),\n            typeof(NonRecordAttribute)\n        );\n        var argNullExcept = GetConstructor<ArgumentNullException, string>().IfNone(() => throw new Exception());\n        var self          = Expression.Parameter(typeof(A), \"self\");\n        var info          = Expression.Parameter(typeof(SerializationInfo), \"info\");\n\n        var returnTarget = Expression.Label();\n\n        Expression WriteField(FieldInfo field)\n        {\n            var name = PrettyFieldName(field);\n            var addValue = (GetPublicInstanceMethod<SerializationInfo>(\"AddValue\", typeof(string), field.FieldType, true) ||\n                            GetPublicInstanceMethod<SerializationInfo>(\"AddValue\", typeof(string), typeof(object), true))\n               .IfNone(() => throw new Exception());\n\n            return addValue.GetParameters()[1].ParameterType == typeof(object)\n                       ? Expression.Call(info, addValue, Expression.Constant(name), Expression.Convert(Expression.Field(self, field), typeof(object)))\n                       : Expression.Call(info, addValue, Expression.Constant(name), Expression.Field(self, field));\n        }\n            \n        var block = Expression.Block(\n            Expression.IfThen(\n                Expression.ReferenceEqual(info, Expression.Constant(null, typeof(SerializationInfo))),\n                Expression.Throw(Expression.New(argNullExcept, Expression.Constant(\"info\")))),\n            Expression.Block(fields.Select(WriteField)),\n            Expression.Return(returnTarget),\n            Expression.Label(returnTarget));\n            \n        var lambda = Expression.Lambda<Action<A, SerializationInfo>>(block, self, info);\n\n        return lambda.Compile();                \n    }\n\n    public static Action<A, SerializationInfo> GetObjectData<A>(bool includeBase)\n    {\n        if (!ILCapability.Available)\n        {\n            return GetObjectDataExpr<A>(includeBase);\n        }\n            \n        var isValueType = typeof(A).GetTypeInfo().IsValueType;\n        var dynamic = new DynamicMethod(\n            \"GetObjectData\", \n            null, \n            new[] { typeof(A), typeof(SerializationInfo) }, \n            typeof(A).Module,\n            true);\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonSerializedAttribute),\n            typeof(NonRecordAttribute)\n        );\n        var argNullExcept =  GetConstructor<ArgumentNullException, string>().IfNone(() => throw new Exception());\n        var il = dynamic.GetILGenerator();\n\n        var infoIsNotNull = il.DefineLabel();\n\n        // if(info == null)\n        il.Emit(OpCodes.Ldarg_1);\n        il.Emit(OpCodes.Brtrue_S, infoIsNotNull);\n\n        /// throw new ArgumentNullException(\"info\");\n        il.Emit(OpCodes.Ldstr, \"info\");\n        il.Emit(OpCodes.Newobj, argNullExcept);\n        il.Emit(OpCodes.Throw);\n\n        il.MarkLabel(infoIsNotNull);\n\n        foreach (var field in fields)\n        {\n            var name = PrettyFieldName(field);\n\n            il.Emit(OpCodes.Ldarg_1);\n            il.Emit(OpCodes.Ldstr, name);\n            il.Emit(OpCodes.Ldarg_0);\n            il.Emit(isValueType ? OpCodes.Ldflda : OpCodes.Ldfld, field);\n\n            var addValue = (GetPublicInstanceMethod<SerializationInfo>(\"AddValue\", typeof(string), field.FieldType, true) ||\n                            GetPublicInstanceMethod<SerializationInfo>(\"AddValue\", typeof(string), typeof(object), true))\n               .IfNone(() => throw new Exception());\n            if (field.FieldType.GetTypeInfo().IsValueType && addValue.GetParameters()[1].ParameterType == typeof(object))\n            {\n                il.Emit(OpCodes.Box, field.FieldType);\n            }\n\n            il.Emit(OpCodes.Callvirt, addValue);\n        }\n        il.Emit(OpCodes.Ret);\n\n        return (Action<A, SerializationInfo>)dynamic.CreateDelegate(typeof(Action<A, SerializationInfo>));\n    }\n        \n    static Action<A, SerializationInfo> SetObjectDataExpr<A>(bool includeBase)\n    {\n        // Expression doesn't support setting of fields that are readonly or init only.\n        // So we fall back to reflection for this.  Not ideal.\n\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonSerializedAttribute),\n            typeof(NonRecordAttribute));\n            \n        return (self, info) =>\n        {\n            foreach (var field in fields)\n            {\n                var name = PrettyFieldName(field);\n                field.SetValue(self, info.GetValue(name, field.FieldType));\n            }\n        };\n    }        \n\n    public static Action<A, SerializationInfo> SetObjectData<A>(bool includeBase)\n    {\n        if (!ILCapability.Available)\n        {\n            return SetObjectDataExpr<A>(includeBase);\n        }\n            \n        var dynamic = new DynamicMethod(\"SetObjectData\",\n                                        null,\n                                        [typeof(A), typeof(SerializationInfo)],\n                                        typeof(A).Module,\n                                        true);\n        var fields = GetPublicInstanceFields<A>(\n            includeBase,\n            typeof(NonSerializedAttribute),\n            typeof(NonRecordAttribute));\n        var getTypeFromHandle = GetPublicStaticMethod<Type, RuntimeTypeHandle>(\"GetTypeFromHandle\").IfNone(() => throw new Exception());\n        var getValue = GetPublicInstanceMethod<SerializationInfo, string, Type>(\"GetValue\", true).IfNone(() => throw new Exception());\n        var argNullExcept = GetConstructor<ArgumentNullException, string>().IfNone(() => throw new Exception());\n        var il = dynamic.GetILGenerator();\n\n        var infoIsNotNull = il.DefineLabel();\n\n        // if(info == null)\n        il.Emit(OpCodes.Ldarg_1);\n        il.Emit(OpCodes.Brtrue_S, infoIsNotNull);\n\n        /// throw new ArgumentNullException(\"info\");\n        il.Emit(OpCodes.Ldstr, \"info\");\n        il.Emit(OpCodes.Newobj, argNullExcept);\n        il.Emit(OpCodes.Throw);\n\n        il.MarkLabel(infoIsNotNull);\n\n        foreach (var field in fields)\n        {\n            var name = PrettyFieldName(field);\n\n            il.Emit(OpCodes.Ldarg_0);                  // this\n            il.Emit(OpCodes.Ldarg_1);                  // info\n            il.Emit(OpCodes.Ldstr, name);              // field-name\n            il.Emit(OpCodes.Ldtoken, field.FieldType); // typeof(FieldType)\n            il.Emit(OpCodes.Call, getTypeFromHandle);  // Type.GetTypeFromHandle(typeof(FieldType))\n            il.Emit(OpCodes.Callvirt, getValue);       // info.GetValue(\"field-name\", FieldType)\n            if (field.FieldType.GetTypeInfo().IsValueType)\n            {\n                il.Emit(OpCodes.Unbox_Any, field.FieldType);\n            }\n            else\n            {\n                il.Emit(OpCodes.Castclass, field.FieldType);\n            }\n            il.Emit(OpCodes.Stfld, field);\n        }\n        il.Emit(OpCodes.Ret);\n\n        return (Action<A, SerializationInfo>)dynamic.CreateDelegate(typeof(Action<A, SerializationInfo>));\n    }\n        \n    public static Func<A, B>? GetPropertyOrField<A, B>(string name) =>\n        GetProperty<A, B>(name) ?? GetField<A, B>(name);\n\n    public static Func<A, B>? GetProperty<A, B>(string name)\n    {\n        var m = typeof(A).GetMethod($\"get_{name}\");\n        if (m            == null) return null;\n        if (m.ReturnType != typeof(B)) return null;\n            \n        if (ILCapability.Available)\n        {\n            var arg = typeof(A);\n            var dynamic = new DynamicMethod(\n                $\"{typeof(A).Name}_{name}\",\n                typeof(B),\n                [arg],\n                typeof(A).Module,\n                true);\n\n            var il = dynamic.GetILGenerator();\n            il.DeclareLocal(typeof(B));\n            if (arg.IsValueType)\n            {\n                il.Emit(OpCodes.Ldarga_S, 0);\n            }\n            else\n            {\n                il.Emit(OpCodes.Ldarg_0);\n            }\n\n            if (m.IsVirtual)\n            {\n                il.Emit(OpCodes.Callvirt, m);\n            }\n            else\n            {\n                il.Emit(OpCodes.Call, m);\n            }\n\n            il.Emit(OpCodes.Stloc_0);\n            il.Emit(OpCodes.Ldloc_0);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, B>)dynamic.CreateDelegate(typeof(Func<A, B>));\n        }\n        else\n        {\n            var larg0  = Expression.Parameter(typeof(A), \"arg0\");\n            var expr   = Expression.Property(larg0, m);\n            var lambda = Expression.Lambda<Func<A, B>>(expr, larg0);\n            return lambda.Compile();\n        }\n    }\n \n    public static Func<A, B>? GetField<A, B>(string name)\n    {\n        var fld = typeof(A).GetField(name);\n        if (fld           == null) return null;\n        if (fld.FieldType != typeof(B)) return null;\n\n        if (ILCapability.Available)\n        {\n            var arg = typeof(A);\n            var dynamic = new DynamicMethod(\n                $\"{typeof(A).Name}_{name}\",\n                typeof(B),\n                new[] {arg},\n                typeof(A).Module,\n                true);\n\n            var il = dynamic.GetILGenerator();\n            il.DeclareLocal(typeof(B));\n            if (arg.IsValueType)\n            {\n                il.Emit(OpCodes.Ldarga_S, 0);\n            }\n            else\n            {\n                il.Emit(OpCodes.Ldarg_0);\n            }\n\n            il.Emit(OpCodes.Ldfld, fld);\n            il.Emit(OpCodes.Stloc_0);\n            il.Emit(OpCodes.Ldloc_0);\n            il.Emit(OpCodes.Ret);\n\n            return (Func<A, B>)dynamic.CreateDelegate(typeof(Func<A, B>));\n        }\n        else\n        {\n            var larg0  = Expression.Parameter(typeof(A), \"arg0\");\n            var expr   = Expression.Field(larg0, fld);\n            var lambda = Expression.Lambda<Func<A, B>>(expr, larg0);\n            return lambda.Compile();\n        }\n    }\n\n    static string PrettyFieldName(FieldInfo field) =>\n        field.Name.Split('<', '>').Match(\n            ()      => \"\",\n            x       => x,\n            (_, xs) => xs.Head.Value!);\n}\n    \npublic static class ILCapability\n{\n    public static readonly bool Available;\n\n    static ILCapability() =>\n        Available = GetAvailability();\n\n    static bool GetAvailability()\n    {\n        try\n        {\n            TestSystemExceptionCtor();\n            return true;\n        }\n        catch (PlatformNotSupportedException)\n        {\n            return false;\n        }\n    }\n\n    static Func<SystemException> TestSystemExceptionCtor()\n    {\n        var type = typeof(SystemException);\n        var ctor = type.GetConstructor(Type.EmptyTypes);\n\n        var dynamic = new DynamicMethod(\"CreateInstance\",\n                                        type,\n                                        Type.EmptyTypes,\n                                        true);\n\n        var il = dynamic.GetILGenerator();\n        il.Emit(OpCodes.Newobj, ctor!);\n        il.Emit(OpCodes.Ret);\n\n        return (Func<SystemException>)dynamic.CreateDelegate(typeof(Func<SystemException>));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/Inter.cs",
    "content": "using System.Runtime.CompilerServices;\nusing System.Threading;\n\nnamespace LanguageExt\n{\n    internal static class Inter\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public static int And(ref int loc, int value)\n        {\n            int current = loc;\n            while (true)\n            {\n                int newValue = current & value;\n                int oldValue = Interlocked.CompareExchange(ref loc, newValue, current);\n                if (oldValue == current)\n                {\n                    return oldValue;\n                }\n                current = oldValue;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/Pool.cs",
    "content": "﻿using System;\nusing System.Collections.Concurrent;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// Type class for newing an object\n    /// </summary>\n    internal interface New<A>\n    {\n        A New();\n    }\n\n    /// <summary>\n    /// Type class for newing an object with one constructor argument\n    /// Also provides a Set for setting the value when being popped off a\n    /// pool stack (see `Pool` below).\n    /// </summary>\n    internal interface New<A, B>\n    {\n        A New(B value);\n        void Set(A item, B value);\n    }\n\n    /// <summary>\n    /// Thread-safe pooling \n    /// Manages a concurrent stack of values that will grow as needed\n    /// When spent new objects are allocated used the `New〈A〉` trait\n    /// </summary>\n    internal static class Pool<NewA, A> where NewA : struct, New<A>\n    {\n        static ConcurrentStack<A> stack = new ConcurrentStack<A>();\n\n        public static A Pop() =>\n            stack.TryPop(out var var)\n                ? var\n                : default(NewA).New();\n\n        public static void Push(A value) =>\n            stack.Push(value);\n    }\n\n    /// <summary>\n    /// Thread-safe pooling \n    /// Manages a concurrent stack of values that will grow as needed\n    /// When spent new objects are allocated used the `New〈A〉` trait\n    /// </summary>\n    internal static class Pool<NewA, A, B> where NewA : struct, New<A, B>\n    {\n        static ConcurrentStack<A> stack = new ConcurrentStack<A>();\n\n        public static A Pop(B value)\n        {\n            if(stack.TryPop(out var var))\n            {\n                default(NewA).Set(var, value);\n                return var;\n            }\n            else\n            {\n                return default(NewA).New(value);\n            }\n        }\n\n        public static void Push(A value) =>\n            stack.Push(value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/ReferenceEqualityComparer.cs",
    "content": "using System.Collections.Generic;\n\nnamespace LanguageExt\n{\n    internal class ReferenceEqualityComparer<A> : IEqualityComparer<A>\n    {\n        public bool Equals(A? x, A? y) =>\n            ReferenceEquals(x, y);\n\n        public int GetHashCode(A? obj) =>\n            obj?.GetHashCode() ?? 0;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/Reflect.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt\n{\n    class Reflect\n    {\n        static bool Intersects<A>(A[] ma, A[] mb)\n        {\n            foreach (var a in ma)\n            {\n                foreach (var b in mb)\n                {\n                    if (a?.Equals(b) ?? false) return true;\n                }\n            }\n\n            return false;\n        }\n\n        public static IEnumerable<FieldInfo> GetPublicInstanceFields<A>(bool includeBase, params Type[] excludeAttrs)\n        {\n            var excludeAttrsSet = excludeAttrs.AsIterable().Map(a => a.Name).ToArray();\n            var publicFields = typeof(A)\n                .GetTypeInfo()\n                .GetAllFields(includeBase)\n#if !COREFX13\n                .OrderBy(f => f.MetadataToken)\n#endif\n                .Where(f =>\n                {\n                    if (!f.IsPublic || f.IsStatic) return false;\n                    if (Intersects(f.CustomAttributes.AsIterable().Map(a => a.AttributeType.Name).ToArray(), excludeAttrsSet)) return false;\n                    return true;\n                });\n\n            var publicPropNames = typeof(A)\n                                    .GetTypeInfo()\n                                    .GetAllProperties(includeBase)\n#if !COREFX13\n                                    .OrderBy(p => p.MetadataToken)\n#endif\n                                    .Where(p => p.CanRead && (p.GetMethod?.IsPublic ?? false) && !IsStatic(p))\n                                    .Where(p => !Intersects(p.CustomAttributes.AsIterable().Map(a => a.AttributeType.Name).ToArray(), excludeAttrsSet))\n                                    .ToArray();\n\n            var backingFields = typeof(A)\n                                    .GetTypeInfo()\n                                    .GetAllFields(includeBase)\n#if !COREFX13\n                                    .OrderBy(p => p.MetadataToken)\n#endif\n                                    .Where(f => f.IsPrivate &&\n                                                publicPropNames.AsIterable().Exists(p => f.Name.StartsWith($\"<{p.Name}>\")))\n                                    .ToArray();\n\n            return EnumerableOptimal.ConcatFast(publicFields, backingFields);\n        }\n\n        /// <summary>\n        /// Returns true if the property is static by inspecting\n        /// the static property of the accessors. Note that if\n        /// there are no accessors then the property is assumed\n        /// to be **non static**. Not sure that this case is\n        /// even possible in CLR.\n        /// </summary>\n        /// <param name=\"p\"></param>\n        /// <returns></returns>\n        public static bool IsStatic\n            (PropertyInfo p) => p.GetAccessors( true ).AsIterable().Head.Map( x => x.IsStatic ).IfNone( false );\n\n        public static Option<MethodInfo> GetPublicStaticMethod(Type type, string name, Type argA) =>\n            type.GetTypeInfo()\n                .DeclaredMethods\n                .Where(x =>\n                {\n                    if (!x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 1) return false;\n                    if (ps[0].ParameterType != argA) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<MethodInfo> GetPublicStaticMethod<TYPE>(string name, Type argA) =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredMethods\n                .Where(x =>\n                {\n                    if (!x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 1) return false;\n                    if (ps[0].ParameterType != argA) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<MethodInfo> GetPublicStaticMethod<TYPE, A>(string name) =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredMethods\n                .Where(x =>\n                {\n                    if (!x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 1) return false;\n                    if (ps[0].ParameterType != typeof(A)) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<MethodInfo> GetPublicStaticMethod<TYPE, A, B>(string name) =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredMethods\n                .Where(x =>\n                {\n                    if (!x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 2) return false;\n                    if (ps[0].ParameterType != typeof(A)) return false;\n                    if (ps[1].ParameterType != typeof(B)) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<MethodInfo> GetPublicStaticMethod<TYPE>(string name, Type argA, Type argB) =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredMethods\n                .Where(x =>\n                {\n                    if (!x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 2) return false;\n                    if (ps[0].ParameterType != argA) return false;\n                    if (ps[1].ParameterType != argB) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<MethodInfo> GetPublicInstanceMethod<TYPE>(string name, bool includeBase) =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .GetAllMethods(includeBase)\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    if (x.GetParameters().Length != 0) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<MethodInfo> GetPublicInstanceMethod<TYPE, A>(string name, bool includeBase) =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .GetAllMethods(includeBase)\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 1) return false;\n                    if (ps[0].ParameterType != typeof(A)) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n\n        public static Option<MethodInfo> GetPublicInstanceMethod<TYPE, A, B>(string name, bool includeBase) =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .GetAllMethods(includeBase)\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 2) return false;\n                    if (ps[0].ParameterType != typeof(A)) return false;\n                    if (ps[1].ParameterType != typeof(B)) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<MethodInfo> GetPublicInstanceMethod(Type type, string name, bool includeBase) =>\n            type.GetTypeInfo()\n                .GetAllMethods(includeBase)\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    if (x.GetParameters().Length != 0) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<MethodInfo> GetPublicInstanceMethod<TYPE>(string name, Type arg1, Type arg2, bool includeBase) =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .GetAllMethods(includeBase)\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    if (x.Name != name) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 2) return false;\n                    if (ps[0].ParameterType != arg1) return false;\n                    if (ps[1].ParameterType != arg2) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<ConstructorInfo> GetConstructor<TYPE>() =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredConstructors\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    if (x.GetParameters().Length != 0) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<ConstructorInfo> GetConstructor<TYPE, A>() =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredConstructors\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 1) return false;\n                    if (ps[0].ParameterType != typeof(A)) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<ConstructorInfo> GetConstructor<TYPE, A, B>() =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredConstructors\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 2) return false;\n                    if (ps[0].ParameterType != typeof(A)) return false;\n                    if (ps[1].ParameterType != typeof(B)) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<ConstructorInfo> GetConstructor<TYPE, A, B, C>() =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredConstructors\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 3) return false;\n                    if (ps[0].ParameterType != typeof(A)) return false;\n                    if (ps[1].ParameterType != typeof(B)) return false;\n                    if (ps[2].ParameterType != typeof(C)) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static Option<ConstructorInfo> GetConstructor<TYPE, A, B, C, D>() =>\n            typeof(TYPE)\n                .GetTypeInfo()\n                .DeclaredConstructors\n                .Where(x =>\n                {\n                    if (x.IsStatic) return false;\n                    var ps = x.GetParameters();\n                    if (ps.Length != 4) return false;\n                    if (ps[0].ParameterType != typeof(A)) return false;\n                    if (ps[1].ParameterType != typeof(B)) return false;\n                    if (ps[2].ParameterType != typeof(C)) return false;\n                    if (ps[3].ParameterType != typeof(D)) return false;\n                    return true;\n                })\n                .FirstOrDefault();\n\n        public static bool IsFunc(Type? type) =>\n            type != null && typeof(MulticastDelegate).IsAssignableFrom(type);\n\n        public static bool IsAnonymous(Type? type) =>\n            type != null && \n            Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false) && \n            type.IsGenericType && type.Name.Contains(\"AnonymousType\") &&\n            (type.Name.StartsWith(\"<>\") || type.Name.StartsWith(\"VB$\")) &&\n            type.Attributes.HasFlag(TypeAttributes.NotPublic);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/SysInfo.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt\n{\n    /// <summary>\n    /// System information helper\n    /// </summary>\n    public static class SysInfo\n    {\n        static int processorCount;\n        static int defaultAsyncSequenceParallelism;\n\n        /// <summary>\n        /// Cached number of processors in the machine\n        /// </summary>\n        public static int ProcessorCount\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => processorCount == 0\n                ? (processorCount = Environment.ProcessorCount)\n                : processorCount;\n        }\n\n        /// <summary>\n        /// When working with an IEnumerable of Tasks or Seq of Tasks, this setting is used as\n        /// the default number of task items streamed at any one time.  This reduces pressure\n        /// on the system when working with large lazy streams of tasks.\n        ///\n        /// Each method that uses it has an override that allows for per-usage settings.\n        ///\n        /// The default value is max(1, Environment.ProcessorCount / 2)\n        /// </summary>\n        public static int DefaultAsyncSequenceParallelism\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => defaultAsyncSequenceParallelism == 0\n                ? (defaultAsyncSequenceParallelism = Math.Max(4, ProcessorCount / 2))\n                : defaultAsyncSequenceParallelism;\n\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            set => defaultAsyncSequenceParallelism = Math.Max(4, value);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/TaskExt.cs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT License.\n// See the LICENSE file in the project root for more information. \n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Runtime.CompilerServices;\n\nnamespace System.Threading.Tasks\n{\n    internal static class TaskExt\n    {\n        public static readonly Task<bool> Never = new TaskCompletionSource<bool>().Task;\n\n        public static WhenAnyValueTask<T> WhenAny<T>(ValueTask<T>[] tasks)\n        {\n            var whenAny = new WhenAnyValueTask<T>(tasks);\n\n            whenAny.Start();\n\n            return whenAny;\n        }\n\n        // REVIEW: Evaluate options to reduce locking and test performance. Right now, there's one lock\n        //         protecting the queue and the completion delegate field. Care has been taken to limit\n        //         the time under the lock, and the (sequential single) reader path has limited locking.\n        //         Contention due to concurrent completion of tasks could be a concern.\n\n        internal sealed class WhenAnyValueTask<T>\n        {\n            /// <summary>\n            /// The tasks to await. Entries in this array may be replaced using <see cref=\"Replace\"/>.\n            /// </summary>\n            private readonly ValueTask<T>[] _tasks;\n\n            /// <summary>\n            /// Array of cached delegates passed to awaiters on tasks. These delegates have a closure containing the task index.\n            /// </summary>\n            private readonly Action[] _onReady;\n\n            /// <summary>\n            /// Queue of indexes of ready tasks. Awaiting the <see cref=\"WhenAnyValueTask{T}\"/> object will consume this queue in order.\n            /// </summary>\n            /// <remarks>\n            /// A lock on this field is taken when updating the queue or <see cref=\"_onCompleted\"/>.\n            /// </remarks>\n            private readonly Queue<int> _ready;\n\n            /// <summary>\n            /// Callback of the current awaiter, if any.\n            /// </summary>\n            /// <remarks>\n            /// Protected for reads and writes by a lock on <see cref=\"_ready\"/>.\n            /// </remarks>\n            private Action? _onCompleted;\n\n            /// <summary>\n            /// Creates a when any task around the specified tasks.\n            /// </summary>\n            /// <param name=\"tasks\">Initial set of tasks to await.</param>\n            public WhenAnyValueTask(ValueTask<T>[] tasks)\n            {\n                _tasks = tasks;\n\n                var n = tasks.Length;\n\n                _ready = new Queue<int>(n); // NB: Should never exceed this length, so we won't see dynamic realloc.\n                _onReady = new Action[n];\n\n                for (var i = 0; i < n; i++)\n                {\n                    //\n                    // Cache these delegates, for they have closures (over `this` and `index`), and we need them\n                    // for each replacement of a task, to hook up the continuation.\n                    //\n\n                    int index = i;\n                    _onReady[index] = () => OnReady(index);\n                }\n            }\n\n            /// <summary>\n            /// Start awaiting the tasks. This is done separately from the constructor to avoid complexity dealing\n            /// with handling concurrent callbacks to the current instance while the constructor is running.\n            /// </summary>\n            public void Start()\n            {\n                for (var i = 0; i < _tasks.Length; i++)\n                {\n                    //\n                    // Register a callback with the task, which will enqueue the index of the completed task\n                    // for consumption by awaiters.\n                    //\n\n                    _tasks[i].ConfigureAwait(false).GetAwaiter().OnCompleted(_onReady[i]);\n                }\n            }\n\n            /// <summary>\n            /// Gets an awaiter to await completion of any of the awaited tasks, returning the index of the completed\n            /// task. When sequentially awaiting the current instance, task indices are yielded in the order that of\n            /// completion. If all tasks have completed and been observed by awaiting the current instance, the awaiter\n            /// never returns on a subsequent attempt to await the completion of any task. The caller is responsible\n            /// for bookkeeping that avoids awaiting this instance more often than the number of pending tasks.\n            /// </summary>\n            /// <returns>Awaiter to await completion of any of the awaited task.</returns>\n            /// <remarks>This class only supports a single active awaiter at any point in time.</remarks>\n            public Awaiter GetAwaiter() => new Awaiter(this);\n\n            /// <summary>\n            /// Replaces the (completed) task at the specified <paramref name=\"index\"/> and starts awaiting it.\n            /// </summary>\n            /// <param name=\"index\">The index of the parameter to replace.</param>\n            /// <param name=\"task\">The new task to store and await at the specified index.</param>\n            public void Replace(int index, in ValueTask<T> task)\n            {\n                Debug.Assert(_tasks[index].IsCompleted, \"A task shouldn't be replaced before it has completed.\");\n\n                _tasks[index] = task;\n\n                task.ConfigureAwait(false).GetAwaiter().OnCompleted(_onReady[index]);\n            }\n\n            /// <summary>\n            /// Called when any task has completed (thus may run concurrently).\n            /// </summary>\n            /// <param name=\"index\">The index of the completed task in <see cref=\"_tasks\"/>.</param>\n            private void OnReady(int index)\n            {\n                Action? onCompleted = null;\n\n                lock (_ready)\n                {\n                    //\n                    // Store the index of the task that has completed. This will be picked up from GetResult.\n                    //\n\n                    _ready.Enqueue(index);\n\n                    //\n                    // If there's a current awaiter, we'll steal its continuation action and invoke it. By setting\n                    // the continuation action to null, we avoid waking up the same awaiter more than once. Any\n                    // task completions that occur while no awaiter is active will end up being enqueued in _ready.\n                    //\n\n                    if (_onCompleted != null)\n                    {\n                        onCompleted = _onCompleted;\n                        _onCompleted = null;\n                    }\n                }\n\n                onCompleted?.Invoke();\n            }\n\n            /// <summary>\n            /// Invoked by awaiters to check if any task has completed, in order to short-circuit the await operation.\n            /// </summary>\n            /// <returns><c>true</c> if any task has completed; otherwise, <c>false</c>.</returns>\n            private bool IsCompleted()\n            {\n                // REVIEW: Evaluate options to reduce locking, so the single consuming awaiter has limited contention\n                //         with the multiple concurrent completing enumerator tasks, e.g. using ConcurrentQueue<T>.\n\n                lock (_ready)\n                {\n                    return _ready.Count > 0;\n                }\n            }\n\n            /// <summary>\n            /// Gets the index of the earliest task that has completed, used by the awaiter. After stealing an index from\n            /// the ready queue (by means of awaiting the current instance), the user may chose to replace the task at the\n            /// returned index by a new task, using the <see cref=\"Replace\"/> method.\n            /// </summary>\n            /// <returns>Index of the earliest task that has completed.</returns>\n            private int GetResult()\n            {\n                lock (_ready)\n                {\n                    return _ready.Dequeue();\n                }\n            }\n\n            /// <summary>\n            /// Register a continuation passed by an awaiter.\n            /// </summary>\n            /// <param name=\"action\">The continuation action delegate to call when any task is ready.</param>\n            private void OnCompleted(Action action)\n            {\n                bool shouldInvoke = false;\n\n                lock (_ready)\n                {\n                    //\n                    // Check if we have anything ready (which could happen in the short window between checking\n                    // for IsCompleted and calling OnCompleted). If so, we should invoke the action directly. Not\n                    // doing so would be a correctness issue where a task has completed, its index was enqueued,\n                    // but the continuation was never called (unless another task completes and calls the action\n                    // delegate, whose subsequent call to GetResult would pick up the lost index).\n                    //\n\n                    if (_ready.Count > 0)\n                    {\n                        shouldInvoke = true;\n                    }\n                    else\n                    {\n                        Debug.Assert(_onCompleted == null, \"Only a single awaiter is allowed.\");\n\n                        _onCompleted = action;\n                    }\n                }\n\n                //\n                // NB: We assume this case is rare enough (IsCompleted and OnCompleted happen right after one\n                //     another, and an enqueue should have happened right in between to go from an empty to a\n                //     non-empty queue), so we don't run the risk of triggering a stack overflow due to\n                //     synchronous completion of the await operation (which may be in a loop that awaits the\n                //     current instance again).\n                //\n\n                if (shouldInvoke)\n                {\n                    action();\n                }\n            }\n\n            /// <summary>\n            /// Awaiter type used to await completion of any task.\n            /// </summary>\n            public struct Awaiter : INotifyCompletion\n            {\n                private readonly WhenAnyValueTask<T> _parent;\n\n                public Awaiter(WhenAnyValueTask<T> parent) => _parent = parent;\n\n                public bool IsCompleted => _parent.IsCompleted();\n                public int GetResult() => _parent.GetResult();\n                public void OnCompleted(Action action) => _parent.OnCompleted(action);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Core/Utility/WaitAsync.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic static class WaitAsync\n{\n    public static async ValueTask<(A A, B B)> WaitAll<A, B>(ValueTask<A> va, ValueTask<B> vb)\n    {\n        var ta = va.AsTask();\n        var tb = vb.AsTask();\n        await Task.WhenAll(ta, tb).ConfigureAwait(false);\n        return (ta.Result, tb.Result);\n    }\n        \n    public static async ValueTask<(A A, B B, C C)> WaitAll<A, B, C>(ValueTask<A> va, ValueTask<B> vb, ValueTask<C> vc)\n    {\n        var ta = va.AsTask();\n        var tb = vb.AsTask();\n        var tc = vc.AsTask();\n        await Task.WhenAll(ta, tb, tc).ConfigureAwait(false);\n        return (ta.Result, tb.Result, tc.Result);\n    }\n        \n    public static async ValueTask<(A A, B B, C C, D D)> WaitAll<A, B, C, D>(ValueTask<A> va, ValueTask<B> vb, ValueTask<C> vc, ValueTask<D> vd)\n    {\n        var ta = va.AsTask();\n        var tb = vb.AsTask();\n        var tc = vc.AsTask();\n        var td = vd.AsTask();\n        await Task.WhenAll(ta, tb, tc, td).ConfigureAwait(false);\n        return (ta.Result, tb.Result, tc.Result, td.Result);\n    }\n        \n    public static async ValueTask<(A A, B B, C C, D D, E E)> WaitAll<A, B, C, D, E>(ValueTask<A> va, ValueTask<B> vb, ValueTask<C> vc, ValueTask<D> vd, ValueTask<E> ve)\n    {\n        var ta = va.AsTask();\n        var tb = vb.AsTask();\n        var tc = vc.AsTask();\n        var td = vd.AsTask();\n        var te = ve.AsTask();\n        await Task.WhenAll(ta, tb, tc, td, te).ConfigureAwait(false);\n        return (ta.Result, tb.Result, tc.Result, td.Result, te.Result);\n    }\n        \n    public static async ValueTask<(A A, B B, C C, D D, E E, F F)> WaitAll<A, B, C, D, E, F>(ValueTask<A> va, ValueTask<B> vb, ValueTask<C> vc, ValueTask<D> vd, ValueTask<E> ve, ValueTask<F> vf)\n    {\n        var ta = va.AsTask();\n        var tb = vb.AsTask();\n        var tc = vc.AsTask();\n        var td = vd.AsTask();\n        var te = ve.AsTask();\n        var tf = vf.AsTask();\n        await Task.WhenAll(ta, tb, tc, td, te, tf).ConfigureAwait(false);\n        return (ta.Result, tb.Result, tc.Result, td.Result, te.Result, tf.Result);\n    }\n        \n    public static async Task<bool> WaitOneAsync(this WaitHandle handle, int millisecondsTimeout, CancellationToken cancellationToken)\n    {\n        RegisteredWaitHandle? registeredHandle  = null;\n        var                   tokenRegistration = default(CancellationTokenRegistration);\n        try\n        {\n            var tcs = new TaskCompletionSource<bool>();\n                \n            registeredHandle = ThreadPool.RegisterWaitForSingleObject(\n                handle,\n                static (state, timedOut) => ((TaskCompletionSource<bool>?)state)?.TrySetResult(!timedOut),\n                tcs,\n                millisecondsTimeout,\n                true);\n                \n            tokenRegistration = cancellationToken.Register(\n                static state => ((TaskCompletionSource<bool>?)state)?.TrySetCanceled(),\n                tcs);\n            return await tcs.Task.ConfigureAwait(false);\n        }\n        finally\n        {\n            registeredHandle?.Unregister(null);\n            tokenRegistration.Dispose();\n        }\n    }\n        \n    public static async Task<bool> WaitOneAsync(this WaitHandle handle, int millisecondsTimeout)\n    {\n        RegisteredWaitHandle? registeredHandle = null;\n        try\n        {\n            var tcs = new TaskCompletionSource<bool>();\n                \n            registeredHandle = ThreadPool.RegisterWaitForSingleObject(\n                handle,\n                static (state, timedOut) => ((TaskCompletionSource<bool>)state!).TrySetResult(!timedOut),\n                tcs,\n                millisecondsTimeout,\n                true);\n                \n            return await tcs.Task.ConfigureAwait(false);\n        }\n        finally\n        {\n            registeredHandle?.Unregister(null);\n        }\n    }\n\n    public static Task<bool> WaitOneAsync(this WaitHandle handle, TimeSpan timeout, CancellationToken cancellationToken) =>\n        handle.WaitOneAsync((int)timeout.TotalMilliseconds, cancellationToken);\n\n    public static Task<bool> WaitOneAsync(this WaitHandle handle, CancellationToken cancellationToken) =>\n        handle.WaitOneAsync(Timeout.Infinite, cancellationToken);\n\n    public static Task<bool> WaitOneAsync(this WaitHandle handle) =>\n        handle.WaitOneAsync(Timeout.Infinite);\n}\n"
  },
  {
    "path": "LanguageExt.Core/Void.cs",
    "content": "using System.Diagnostics.Contracts;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Meant to represent `void`, but we can't construct a `System.Void`.\n/// \n/// A `Void` is the initial object in a category, equivalent to an empty set, and because there are no values in an\n/// empty set there's no way to construct a type of `Void`.\n/// </summary>\n/// <remarks>\n/// Usages:\n///   * Used in the pipes system to represent a 'closed' path.\n///   * Used in `Decidable` contravariant functors to 'lose' information.  \n/// </remarks>\npublic record Void\n{\n    /// <summary>\n    /// Voids can't be constructed, as they're the 'uninhabited type', i.e. an empty set, with no values.\n    /// </summary>\n    Void() => \n        throw new BottomException();\n    \n    [Pure]\n    public override string ToString() => \n        \"void\";\n}\n"
  },
  {
    "path": "LanguageExt.FSharp/LanguageExt.FSharp.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)'=='Debug'\">\n        <DefineConstants>TRACE;DEBUG</DefineConstants>\n    </PropertyGroup>\n    <PropertyGroup Label=\"Configuration\">\n        <DefineConstants>CONTRACTS_FULL</DefineConstants>\n        <NoWarn>1701;1702;1705;IDE1006;CS1591;CS1573;CS1712;CS1711;CS1572;CS1587</NoWarn>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <PackageVersion>5.0.0-beta-77</PackageVersion>\n        <PackageId>LanguageExt.FSharp</PackageId>\n        <Title>LanguageExt.FSharp</Title>\n        <Authors>Paul Louth</Authors>\n        <Summary>Functional language extensions for C#</Summary>\n        <Copyright>Copyright (c) Paul Louth. All rights reserved.</Copyright>\n        <PackageReadmeFile>README.nuget.md</PackageReadmeFile>\n        <Description>Helper library for the  LanguageExt functional framework that facilitates interop between F# native types like Option, Map, List, etc to .NET and Language-Ext types.</Description>\n        <PackageTags>C#, Functional, Language Extension, Monad, Option, Either, Reader, Writer, State, List, Set, Map, Queue, Memo, Memoization, Immutable, Lambda, Pattern Matching, Tuple</PackageTags>\n        <PackageIcon>lang-ext-small.png</PackageIcon>\n        <PackageProjectUrl>https://github.com/louthy/language-ext</PackageProjectUrl>\n        <PackageLicenseExpression>MIT</PackageLicenseExpression>\n        <EnableDefaultCompileItems>false</EnableDefaultCompileItems>\n        <DocumentationFile>bin\\$(Configuration)\\$(TargetFramework)\\$(AssemblyName).xml</DocumentationFile>\n        <OutputType>library</OutputType>\n        <AssemblyVersion>5.0.0.0</AssemblyVersion>\n        <FileVersion>5.0.0.0</FileVersion>\n        <LangVersion>default</LangVersion>\n    </PropertyGroup>\n    <ItemGroup>\n        <None Include=\"README.nuget.md\" Pack=\"true\" PackagePath=\"\\\"/>\n        <None Include=\"..\\Images\\lang-ext-small.png\" Pack=\"true\" PackagePath=\"\\\"/>\n    </ItemGroup>\n\n    <ItemGroup>\n        <Compile Include=\"**\\*.cs\" />\n        <EmbeddedResource Include=\"**\\*.resx\" />\n    </ItemGroup>\n    <ItemGroup>\n        <Compile Remove=\"obj\\**\" />\n        <EmbeddedResource Remove=\"obj\\**\" />\n        <None Remove=\"obj\\**\" />\n    </ItemGroup>\n    <ItemGroup>\n        <PackageReference Include=\"FSharp.Core\" Version=\"7.0.200\" />\n    </ItemGroup>\n    <ItemGroup>\n        <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "LanguageExt.FSharp/Prelude.cs",
    "content": "﻿using System;\nusing Microsoft.FSharp.Core;\nusing Microsoft.FSharp.Collections;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class FSharp\n{\n    /// <summary>\n    /// Convert an F# Option into a LanguageExt Option \n    /// </summary>\n    public static Option<T> fs<T>(FSharpOption<T> fsOption) =>\n        FSharpOption<T>.get_IsSome(fsOption)\n            ? Some(fsOption.Value)\n            : None;\n\n    /// <summary>\n    /// Convert a LanguageExt Option into an F# Option \n    /// </summary>\n    public static FSharpOption<T> fs<T>(Option<T> option) =>\n        option.Map(FSharpOption<T>.Some)\n              .IfNone(FSharpOption<T>.None)!;\n\n    /// <summary>\n    /// Convert an F# List into an IEnumerable T\n    /// </summary>\n    public static Lst<T> fs<T>(FSharpList<T> fsList) =>\n        List.createRange(fsList);\n\n    /// <summary>\n    /// Convert a LanguageExt List (Lst T) into an F# List\n    /// </summary>\n    public static FSharpList<T> fs<T>(Lst<T> list) =>\n        ListModule.OfSeq(list);\n\n    /// <summary>\n    /// Convert an F# Map into a LanguageExt Map (Map K V)\n    /// </summary>\n    public static Map<K, V> fs<K, V>(FSharpMap<K, V> fsMap) =>\n        Map.addRange( Map<K, V>(), List.map(fsMap, identity) );\n\n    /// <summary>\n    /// Convert a LanguageExt Map (Map K V) into an F# Map\n    /// </summary>\n    public static FSharpMap<K, V> fs<K, V>(Map<K, V> map) =>\n        MapModule.OfSeq(map.AsIterable().Map(item => Tuple.Create(item.Key,item.Value)));\n\n    /// <summary>\n    /// Convert LanguageExt Unit to F# unit\n    /// </summary>\n    /// <param name=\"unit\">()</param>\n    public static void fs(Unit unit)\n    {\n    }\n\n    /// <summary>\n    /// Convert an F# Result into a LanguageExt Either\n    /// </summary>\n    public static Either<TError, T> fs<T, TError>(FSharpResult<T, TError> result) =>\n        result.IsOk\n            ? Either.Right<TError, T>(result.ResultValue)\n            : Either.Left<TError, T>(result.ErrorValue);\n\n    /// <summary>\n    /// Convert a LanguageExt Either into an F# Result\n    /// </summary>\n    public static FSharpResult<R, L> fs<L, R>(Either<L, R> either) =>\n        either.Match(FSharpResult<R, L>.NewError,\n                     FSharpResult<R, L>.NewOk);\n\n    /// <summary>\n    /// Convert a LanguageExt Option into an F# Option \n    /// </summary>\n    public static FSharpOption<T> ToFSharp<T>(this Option<T> option) =>\n        option.IsNone\n            ? FSharpOption<T>.None\n            : match(option,\n                    Some: FSharpOption<T>.Some,\n                    None: () => failwith<FSharpOption<T>>(\"returns null, so can't use the None branch\"));\n\n    /// <summary>\n    /// Convert a LanguageExt Map (Map K V) into an F# Map\n    /// </summary>\n    public static FSharpMap<K, V> ToFSharp<K, V>(this Map<K, V> map) =>\n        MapModule.OfSeq(map.AsIterable().Map(item => Tuple.Create(item.Key, item.Value)));\n\n    /// <summary>\n    /// Convert a LanguageExt List (Lst A) into an F# List\n    /// </summary>\n    public static FSharpList<A> ToFSharp<A>(this Lst<A> list) =>\n        ListModule.OfSeq(list);\n\n    /// <summary>\n    /// Convert a LanguageExt Either into an F# Result\n    /// </summary>\n    public static FSharpResult<R, L> ToFSharp<L, R>(this Either<L, R> either) =>\n        either.Match(FSharpResult<R, L>.NewError,\n                     FSharpResult<R, L>.NewOk);\n}\n"
  },
  {
    "path": "LanguageExt.FSharp/README.nuget.md",
    "content": "# LanguageExt.FSharp\n\n`LanguageExt.FSharp` is provides interop between F# and C# for the [language-ext functional programming framework](https://github.com/louthy/language-ext).\n\nThe framework uses and abuses the features of C# to provide a pure functional-programming \n'Base Class Library' that, if you squint, can look like extensions to the language itself. \nThe desire here is to make programming in C# much more robust by helping the engineer's \ninertia flow in the direction of declarative and pure functional code rather than imperative. \n\nUsing these techniques for large code-bases can bring tangible benefits to long-term maintenance \nby removing hidden complexity and by easing the engineer's cognitive load.\n\n## Features\n\n### [Functional effects and IO](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/index.html)\n\n| Location | Feature      | Description                                                                                                                                                                                              |\n|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `IO<A>`      | [A synchronous and asynchronous side-effect: an IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/IO/index.html)                                                                  |\n| `Core`   | `Eff<A>`     | [A synchronous and asynchronous side-effect with error handling](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20no%20runtime/index.html)                                       |\n| `Core`   | `Eff<RT, A>` | [Same as `Eff<A>` but with an injectable runtime for dependency-injection: a unit testable IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20with%20runtime/index.html) |\n| `Core`   | Pipes        | [A clean and powerful stream processing system that lets you build and connect reusable streaming components](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Pipes/index.html)           |\n| `Core`   | StreamT      | [less powerful (than Pipes), but easier to use streaming effects transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/StreamT/index.html)                                         |\n\n### [Atomic concurrency and collections](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/index.html)\n\n| Location | Feature                            | Description                                                                                                                                            |\n|----------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Atom<A>`                          | [A lock-free atomically mutable reference for working with shared state](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/Atom)      |\n| `Core`   | `Ref<A>`                           | [An atomic reference to be used in the transactional memory system](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/STM)            |\n| `Core`   | `AtomHashMap<K, V>`                | [An immutable `HashMap` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomHashMap) |\n| `Core`   | `AtomSeq<A>`                       | [An immutable `Seq` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomSeq)         |\n| `Core`   | `VectorClock<A>`                   | [Understand distributed causality](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VectorClock)                                     |\n| `Core`   | `VersionVector<A>`                 | [A vector clock with some versioned data](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionVector)                            |\n| `Core`   | `VersionHashMap <ConflictV, K, V>` | [Distrubuted atomic versioning of keys in a hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionHashMap)               |\n\n### [Immutable collections](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/index.html)\n\n| Location | Feature              | Description                                                                                                                                                                                                             |\n|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Arr<A>`             | [Immutable array](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Arr/index.html)                                                                                                        |\n| `Core`   | `Seq<A>`             | [Lazy immutable list, evaluate at-most-once](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Seq/index.html) - very, very fast!                                                          |\n| `Core`   | `Iterable<A>`        | [Wrapper around `IEnumerable` with support for traits](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Iterable/index.html) - enables the higher-kinded traits to work with enumerables. |\n| `Core`   | `Lst<A>`             | [Immutable list](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/List/index.html) - use `Seq` over `Lst` unless you need `InsertAt`                                                      |\n| `Core`   | `Map<K, V>`          | [Immutable map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                                                          |\n| `Core`   | `Map<OrdK, K, V>`    | [Immutable map with Ord constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                               |\n| `Core`   | `HashMap<K, V>`      | [Immutable hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                                                 |\n| `Core`   | `HashMap<EqK, K, V>` | [Immutable hash-map with Eq constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                       |\n| `Core`   | `Set<A>`             | [Immutable set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                                                          |\n| `Core`   | `Set<OrdA, A>`       | [Immutable set with Ord constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                               |\n| `Core`   | `HashSet<A>`         | [Immutable hash-set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                                                 |\n| `Core`   | `HashSet<EqA, A>`    | [Immutable hash-set with Eq constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                       |\n| `Core`   | `Que<A>`             | [Immutable queue](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Queue/index.html)                                                                                                      |\n| `Core`   | `Stck<A>`            | [Immutable stack](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Stack/index.html)                                                                                                      |\n\n### [Optional and alternative value monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/index.html)\n\n| Location | Feature                         | Description                                                                                                                                                                                              |\n|----------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Option<A>`                     | [Option monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Option/index.html)                                                                                     |\n| `Core`   | `OptionT<M, A>`                 | [Option monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/OptionT/index.html)                                                                        |\n| `Core`   | `Either<L,R>`                   | [Right/Left choice monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Either/index.html)                                                                          |\n| `Core`   | `EitherT<L, M, R>`              | [Right/Left choice monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/EitherT/index.html)                                                             |\n| `Core`   | `Fin<A>`                        | [`Error` handling monad, like `Either<Error, A>`](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Fin/index.html)                                                     |\n| `Core`   | `FinT<M, A>`                    | [`Error` handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/FinT/index.html)                                                                 |\n| `Core`   | `Try<A>`                        | [Exception handling monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Try/index.html)                                                                            |\n| `Core`   | `TryT<M, A>`                    | [Exception handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/TryT/index.html)                                                               |\n| `Core`   | `Validation<FAIL ,SUCCESS>`     | [Validation applicative and monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Validation/index.html) for collecting multiple errors before aborting an operation |\n| `Core`   | `ValidationT<FAIL, M, SUCCESS>` | [Validation applicative and monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/ValidationT/index.html)                                                |\n\n### [State managing monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/index.html)\n\n| Location | Feature            | Description                                                                                                                                                                             |\n|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Reader<E, A>`     | [Reader monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/Reader/index.html)                                               |\n| `Core`   | `ReaderT<E, M, A>` | [Reader monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/ReaderT/index.html)                                  |\n| `Core`   | `Writer<W, A>`     | [Writer monad that logs to a `W` constrained to be a Monoid](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/Writer/index.html) |\n| `Core`   | `WriterT<W, M, A>` | [Writer monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/WriterT/index.html)                                  |\n| `Core`   | `State<S, A>`      | [State monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/State/index.html)                                                  |\n| `Core`   | `StateT<S, M, A>`  | [State monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/StateT/index.html)                                     |\n\n### [Parser combinators](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)\n\n| Location | Feature        | Description                                                                                                                    |\n|----------|----------------|--------------------------------------------------------------------------------------------------------------------------------|\n| `Parsec` | `Parser<A>`    | [String parser monad and full parser combinators library](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html) |\n| `Parsec` | `Parser<I, O>` | [Parser monad that can work with any input stream type](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)   |\n\n### [Pretty](https://louthy.github.io/language-ext/LanguageExt.Core/Pretty/index.html)\n\n| Location | Feature  | Description                                      |\n|----------|----------|--------------------------------------------------|\n| `Core`   | `Doc<A>` | Produce nicely formatted text with smart layouts |\n\n### [Differencing](https://louthy.github.io/language-ext/LanguageExt.Core/DataTypes/Patch/index.html)\n\n| Location | Feature         | Description                                                                                                                                                                                                                          |\n|----------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Patch<EqA, A>` | Uses patch-theory to efficiently calculate the difference (`Patch.diff(list1, list2)`) between two collections of `A` and build a patch which can be applied (`Patch.apply(patch, list)`) to one to make the other (think git diff). |\n\n### [Traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/index.html)\n\nThe traits are major feature of `v5`+ language-ext that makes generic programming with higher-kinds a reality.  Check out Paul's [series on Higher Kinds](https://paullouth.com/higher-kinds-in-c-with-language-ext/) to get a deeper insight.\n\n| Location | Feature                                | Description                                                                                                                                                            |\n|----------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `MonoidK<F>`                       | [A monoid on applicative functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Alternative/index.html)                                               |\n| `Core`   | `Applicative<F>`                       | [Applicative functor](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Applicative/index.html)                                                            |\n| `Core`   | `Eq<A>`                                | [Ad-hoc equality trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Eq/index.html)                                                                   |\n| `Core`   | `Fallible<F>`                          | [Trait that describes types that can fail](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Fallible/index.html)                                          |\n| `Core`   | `Foldable<T>`                          | [Aggregation over a structure](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Foldable/index.html)                                                      |\n| `Core`   | `Functor<F>`                           | [Functor `Map`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Functor/index.html)                                                                      |\n| `Core`   | `Has<M, TRAIT>`                        | [Used in runtimes to enable DI-like capabilities](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Has/index.html)                                        |\n| `Core`   | `Hashable<A>`                          | [Ad-hoc has-a-hash-code trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Hashable/index.html)                                                      |\n| `Core`   | `Local<M, E>`                          | [Creates a local environment to run a computation ](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Local/index.html)                                    |\n| `Core`   | `Monad<M>`                             | [Monad trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/Monad/index.html)                                                                   |\n| `Core`   | `MonadT<M, N>`                         | [Monad transformer trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/MonadT/index.html)                                                      |\n| `Core`   | `Monoid<A>`                            | [A monoid is a type with an identity `Empty` and an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monoid/index.html) |\n| `Core`   | `MonoidK<M>`                           | [Equivalent of monoids for working on higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/MonoidK/index.html)                           |\n| `Core`   | `Mutates<M, OUTER_STATE, INNER_STATE>` | [Used in runtimes to enable stateful operations](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Mutates/index.html)                                     |\n| `Core`   | `Ord<A>`                               | [Ad-hoc ordering / comparisons](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Ord/index.html)                                                          |\n| `Core`   | `Range<SELF, NumOrdA, A>`              | [Abstraction of a range of values](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Range/index.html)                                                     |\n| `Core`   | `Readable<M, Env>`                     | [Generalised Reader monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Readable/index.html)                                              |\n| `Core`   | `SemigroupK<F>`                   | [A semigroup on functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                                                    |\n| `Core`   | `Semigroup<A>`                         | [Provides an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Semigroup/index.html)                                     |\n| `Core`   | `SemigroupK<M>`                        | [Equivalent of semigroups for working with higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                   |\n| `Core`   | `Stateful<M, S>`                       | [Generalised State monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Stateful/index.html)                                               |\n| `Core`   | `Traversable<T>`                       | [Traversable structures support element-wise sequencing of Applicative effects](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Traversable/index.html)  |\n| `Core`   | `Writable<M, W>`                       | [Generalised Writer monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Writable/index.html)                                              |\n\n### [Value traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Domain/index.html)\n\nThese work a little like `NewType` but they impart semantic meaning and some common operators for the underlying value.\n\n| Location | Feature                              | Description                                                                                                                                                                                                                                       |\n|----------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `DomainType<SELF, REPR>`             | Provides a mapping from `SELF` to an underlying representation: `REPR`                                                                                                                                                                            |\n| `Core`   | `Identifier <SELF>`                  | Identifiers (like IDs in databases: `PersonId` for example), they are equivalent to `DomaintType` with equality.                                                                                                                                  |\n| `Core`   | `VectorSpace<SELF, SCALAR>`          | Scalable values; can add and subtract self, but can only multiply and divide by a scalar. Can also negate.                                                                                                                                        |\n| `Core`   | `Amount <SELF, SCALAR>`              | Quantities, such as the amount of money in USD on a bank account or a file size in bytes. Derives `VectorSpace`, `IdentifierLike`, `DomainType`, and is orderable (comparable).                                                                   |\n| `Core`   | `LocusLike <SELF, SCALAR, DISTANCE>` | Works with space-like structures. Spaces have absolute and relative distances. Has an origin/zero point and derives `DomainType`, `IdentifierLike`, `AmountLike` and `VectorSpace`.  `DISTANCE` must also be an `AmountLike<SELF, REPR, SCALAR>`. |\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Delegates.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\npublic delegate K<M, B> ConsumedOK<E, S, T, in M, in A, B>(A value, State<S, T, E> state, Hints<T> hints);\npublic delegate K<M, B> ConsumedErr<E, S, T, in M, B>(ParseError<T, E> error, State<S, T, E> state);\npublic delegate K<M, B> EmptyOK<E, S, T, in M, in A, B>(A value, State<S, T, E> state, Hints<T> hints);\npublic delegate K<M, B> EmptyErr<E, S, T, in M, B>(ParseError<T, E> error, State<S, T, E> state);\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ErrorFancy/ErrorFancy.Module.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\npublic static class ErrorFancy\n{\n    public static ErrorFancy<E> Fail<E>(string value) => \n        new ErrorFancy<E>.Fail(value);\n    \n    public static ErrorFancy<E> Indentation<E>(int ordering, int reference, int actual) => \n        new ErrorFancy<E>.Indentation(ordering, reference, actual);\n    \n    public static ErrorFancy<E> Custom<E>(E value) => \n        new ErrorFancy<E>.Custom(value);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ErrorFancy/ErrorFancy.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\npublic abstract record ErrorFancy<E> : IComparable<ErrorFancy<E>>\n{\n    public record Fail(string Value) : ErrorFancy<E>\n    {\n        public override int CompareTo(ErrorFancy<E>? other) =>\n            other is Fail(var rhs)\n                ? string.Compare(Value, rhs, StringComparison.Ordinal)\n                : 1;\n    }\n\n    public record Indentation(int Ordering, int Reference, int Actual) : ErrorFancy<E>\n    {\n        public override int CompareTo(ErrorFancy<E>? other) =>\n            other switch\n            {\n                Fail => 0,\n                Indentation(var rhsOrdering, var rhsReference, var rhsActual) =>\n                    Ordering.CompareTo(rhsOrdering) switch\n                    {\n                        0 => Reference.CompareTo(rhsReference) switch\n                             {\n                                 0     => Actual.CompareTo(rhsActual),\n                                 var n => n\n                             },\n                        var n => n\n                    },\n                Custom => 1,\n                _      => throw new NotSupportedException()\n            };\n    }\n\n    public record Custom(E Value) : ErrorFancy<E>\n    {\n        public override int CompareTo(ErrorFancy<E>? other) =>\n            other is Custom(var rhs)\n                ? Comparer<E>.Default.Compare(Value, rhs)\n                : 0;\n    }\n\n    public abstract int CompareTo(ErrorFancy<E>? other);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ErrorItem/ErrorItem.Extensions.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static class ErrorItemExtensions\n{\n    public static ErrorItem<T> As<T>(this K<ErrorItem, T> ea) =>\n        (ErrorItem<T>)ea;\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ErrorItem/ErrorItem.Module.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\npublic class ErrorItem : Functor<ErrorItem>\n{\n    public static ErrorItem<T> Token<T>(T token) => \n        new ErrorItem<T>.Tokens([token]);\n    \n    public static ErrorItem<T> Tokens<T>(in Seq<T> tokens) => \n        new ErrorItem<T>.Tokens(tokens);\n    \n    public static ErrorItem<T> Tokens<T>(in ReadOnlySpan<T> tokens) => \n        new ErrorItem<T>.Tokens([..tokens]);\n    \n    public static ErrorItem<T> Tokens<S, T>(in S tokens)\n        where S : TokenStream<S, T> => \n        Tokens(S.ChunkToTokens(tokens));\n    \n    public static ErrorItem<T> Label<T>(string label) => \n        new ErrorItem<T>.Label(label);\n    \n    public static ErrorItem<T> EndOfInput<T>() => \n        new ErrorItem<T>.EndfOfInput();\n\n    public static K<ErrorItem, B> Map<A, B>(Func<A, B> f, K<ErrorItem, A> ma) =>\n        ma switch\n        {\n            ErrorItem<A>.Tokens (var tokens) => Tokens(tokens.Map(f)),\n            ErrorItem<A>.Label (var label)   => Label<B>(label),\n            ErrorItem<A>.EndfOfInput         => EndOfInput<B>(),\n            _                                => throw new NotSupportedException()\n        };\n}\n\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ErrorItem/ErrorItem.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n///  A data type that is used to represent “unexpected or expected” items in\n/// 'ParseError'. It is parametrised over the token type `T`.\n/// </summary>\n/// <typeparam name=\"T\">Token type</typeparam>\npublic abstract record ErrorItem<T> : K<ErrorItem, T>, IComparable<ErrorItem<T>>\n{\n    public ErrorItem<U> Map<U>(Func<T, U> f) =>\n        this.Kind().Map(f).As();\n\n    public ErrorItem<U> Select<U>(Func<T, U> f) =>\n        this.Kind().Map(f).As();\n\n    /// <summary>\n    /// Non-empty stream of tokens\n    /// </summary>\n    /// <param name=\"Tokens\">Tokens</param>\n    /// <typeparam name=\"T\">Token type</typeparam>\n    public record Tokens(in Seq<T> Items) : ErrorItem<T>\n    {\n        public override int CompareTo(ErrorItem<T>? other) =>\n            throw new NotImplementedException();\n    }\n\n    /// <summary>\n    /// Label (should not be empty)\n    /// </summary>\n    /// <param name=\"Value\">Label value</param>\n    /// <typeparam name=\"T\">Token type</typeparam>\n    public record Label(string Value) : ErrorItem<T>\n    {\n        public override int CompareTo(ErrorItem<T>? other) =>\n            throw new NotImplementedException();\n    }\n\n    /// <summary>\n    /// End of input\n    /// </summary>\n    /// <typeparam name=\"T\">Token type</typeparam>\n    public record EndfOfInput : ErrorItem<T>\n    {\n        public override int CompareTo(ErrorItem<T>? other) =>\n            throw new NotImplementedException();\n    }\n\n    public abstract int CompareTo(ErrorItem<T>? other);\n\n    public static bool operator >(ErrorItem<T> l, ErrorItem<T> r) =>\n        l.CompareTo(r) > 0;\n\n    public static bool operator >=(ErrorItem<T> l, ErrorItem<T> r) =>\n        l.CompareTo(r) >= 0;\n\n    public static bool operator <(ErrorItem<T> l, ErrorItem<T> r) =>\n        l.CompareTo(r) < 0;\n\n    public static bool operator <=(ErrorItem<T> l, ErrorItem<T> r) =>\n        l.CompareTo(r) <= 0;\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ErrorItem/ExpectedErrors.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Precomputed expected errors\n/// </summary>\n/// <remarks>\n/// By precomputing expected errors, we can avoid creating a lot of additional memory allocations for common\n/// parser combinators.\n/// </remarks>\npublic static class ExpectedErrors\n{\n    public static readonly Set<ErrorItem<char>> newline =\n        Set.singleton(ErrorItem.Label<char>(\"newline\"));\n    \n    public static readonly Set<ErrorItem<char>> tab =\n        Set.singleton(ErrorItem.Label<char>(\"tab\"));\n    \n    public static readonly Option<string> whiteSpace =\n        \"white space\";\n    \n    public static readonly Set<ErrorItem<char>> whiteSpaceChar =\n        Set.singleton(ErrorItem.Label<char>(\"white space\"));\n    \n    public static readonly Set<ErrorItem<char>> upperChar =\n        Set.singleton(ErrorItem.Label<char>(\"uppercase letter\"));\n    \n    public static readonly Set<ErrorItem<char>> lowerChar =\n        Set.singleton(ErrorItem.Label<char>(\"lowercase letter\"));\n    \n    public static readonly Set<ErrorItem<char>> letterChar =\n        Set.singleton(ErrorItem.Label<char>(\"letter\"));\n    \n    public static readonly Set<ErrorItem<char>> alphaNumChar =\n        Set.singleton(ErrorItem.Label<char>(\"alphanumeric character\"));\n    \n    public static readonly Set<ErrorItem<char>> digitChar =\n        Set.singleton(ErrorItem.Label<char>(\"digit\"));\n    \n    public static readonly Set<ErrorItem<char>> binaryDigitChar =\n        Set.singleton(ErrorItem.Label<char>(\"binary digit\"));\n    \n    public static readonly Set<ErrorItem<char>> hexDigitChar =\n        Set.singleton(ErrorItem.Label<char>(\"hexadecimal digit\"));\n    \n    public static readonly Set<ErrorItem<char>> numberChar =\n        Set.singleton(ErrorItem.Label<char>(\"numeric character\"));\n    \n    public static readonly Set<ErrorItem<char>> symbolChar =\n        Set.singleton(ErrorItem.Label<char>(\"symbol\"));\n    \n    public static readonly Set<ErrorItem<char>> punctuationChar =\n        Set.singleton(ErrorItem.Label<char>(\"punctuation\"));\n\n    public static readonly Set<ErrorItem<char>> control =\n        Set.singleton(ErrorItem.Label<char>(\"control character\"));\n\n    public static readonly Set<ErrorItem<char>> separator =\n        Set.singleton(ErrorItem.Label<char>(\"separator\"));\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Hints/Hints.Module.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\npublic static class Hints \n{\n    /// <summary>\n    /// No hints\n    /// </summary>\n    public static Hints<T> empty<T>() => \n        Hints<T>.Empty;\n    \n    /// <summary>\n    /// No hints\n    /// </summary>\n    public static Hints<T> singleton<T>(ErrorItem<T> value) => \n        new ([value]);\n    \n    /// <summary>\n    /// Convert a `ParseError` record into 'Hints'.\n    /// </summary>\n    /// <param name=\"streamPos\"></param>\n    /// <param name=\"error\"></param>\n    /// <typeparam name=\"T\">Token type</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <returns>Hints</returns>\n    public static Hints<T> fromOffset<T, E>(int streamPos, ParseError<T, E> error) =>\n        error switch\n        {\n            ParseError<T, E>.Trivial(var errOffset, _, var ps) =>\n                streamPos == errOffset\n                    ? ps.IsEmpty\n                          ? Hints<T>.Empty\n                          : new Hints<T>(ps)\n                    : Hints<T>.Empty,\n\n            _ => Hints<T>.Empty\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Hints/Hints.cs",
    "content": "using LanguageExt.Traits;\nusing LanguageExt.UnsafeValueAccess;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// `Hints` represent a collection of `ErrorItem` values to be included into\n/// q `ParseError` (when it's a `TrivialError`) as 'expected' message items\n/// when a parser fails without consuming input right after a successful parser\n/// that produced the hints. \n/// </summary>\n/// <param name=\"Errors\">Errors</param>\n/// <typeparam name=\"T\">Token type</typeparam>\npublic record Hints<T>(Set<ErrorItem<T>> Errors) : Monoid<Hints<T>>\n{\n    public Hints<T> Combine(Hints<T> rhs) => \n        new (Errors + rhs.Errors);\n\n    public static Hints<T> Empty { get; } = \n        new (Set<ErrorItem<T>>.Empty);\n\n    /// <summary>\n    /// Replace the hints with the given `ErrorItem` (or delete it if 'Nothing' is given).\n    /// This is used in the `label` primitive.\n    /// </summary>\n    /// <param name=\"errorItem\">Error item</param>\n    /// <returns>Refreshed hints</returns>\n    public Hints<T> Refresh(Option<ErrorItem<T>> errorItem) =>\n        errorItem.IsSome\n            ? Errors.IsEmpty\n                  ? Empty\n                  : new Hints<T>(Set.singleton(errorItem.ValueUnsafe()!))\n            : Empty;\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/LanguageExt.Megaparsec.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "LanguageExt.Megaparsec/LineText.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Lazy text structure\n/// </summary>\n/// <param name=\"lazyText\">Lazy text function</param>\npublic class LineText(Func<string> lazyText)\n{\n    int isAvailable;\n    string text = \"\";\n    \n    /// <summary>\n    /// Construct a new LineText\n    /// </summary>\n    /// <param name=\"lazyText\">Lazy text function</param>\n    /// <returns>LineText</returns>\n    public static LineText Lift(Func<string> lazyText) =>\n        new (lazyText);\n    \n    /// <summary>\n    /// Read text\n    /// </summary>\n    public string Text => \n        GetText();\n    \n    string GetText()\n    {\n        if(isAvailable == 2) return text;\n        SpinWait sw = default;\n        while (true)\n        {\n            if(isAvailable == 2) return text;\n            if (Interlocked.CompareExchange(ref isAvailable, 1, 0) == 0)\n            {\n                try\n                {\n                    text = lazyText();\n                    isAvailable = 2;\n                    return text;\n                }\n                catch\n                {\n                    isAvailable = 0;\n                    throw;\n                }\n            }\n            else\n            {\n                sw.SpinOnce();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ModuleT/Expr.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static partial class ModuleT<MP, E, S, T, M>\n    where MP : MonadParsecT<MP, E, S, T, M>\n    where S : TokenStream<S, T>\n    where M : Monad<M>\n{\n    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ModuleT/Failure.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static partial class ModuleT<MP, E, S, T, M>\n    where MP : MonadParsecT<MP, E, S, T, M>\n    where S : TokenStream<S, T>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Stop parsing and report the `ParseError`.\n    /// </summary>\n    /// <remarks>\n    /// This is the only way to control the position of the error without\n    /// manipulating the parser state manually.\n    /// </remarks>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <param name=\"error\">Error</param>\n    /// <returns>Parser</returns>\n    public static K<MP, A> error<A>(ParseError<T, E> error) =>\n        MP.Error<A>(error);\n\n    /// <summary>\n    /// Stop parsing and report a trivial `ParseError`.\n    /// </summary>\n    /// <param name=\"unexpected\">Optional unexpected tokens</param>\n    /// <param name=\"expected\">Expected tokens</param>\n    /// <typeparam name=\"A\">Value type (never yielded because this is designed to error)</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> failure<A>(Option<ErrorItem<T>> unexpected, Set<ErrorItem<T>> expected) =>\n        getOffset >> (o => error<A>(ParseError.Trivial<T, E>(o, unexpected, expected)));\n\n    /// <summary>\n    /// Stop parsing and report a fancy 'ParseError'. To report a single custom parse error\n    /// </summary>\n    /// <param name=\"errors\">Optional unexpected tokens</param>\n    /// <typeparam name=\"A\">Value type (never yielded because this is designed to error)</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> failure<A>(Set<ErrorFancy<E>> errors) =>\n        getOffset >> (o => error<A>(ParseError.Fancy<T, E>(o, errors)));\n\n    /// <summary>\n    /// Stop parsing and report a fancy 'ParseError'. To report a single custom parse error\n    /// </summary>\n    /// <param name=\"error\">Custom error</param>\n    /// <typeparam name=\"A\">Value type (never yielded because this is designed to error)</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> failure<A>(E error) =>\n        Pure(error) >> ErrorFancy.Custom >> Set.singleton >> (failure<A>) >> lower;\n\n    /// <summary>\n    /// The parser `unexpected(item)` fails with an error message telling\n    /// about an unexpected `item` without consuming any input.\n    /// </summary>\n    /// <param name=\"item\">The unexpected item</param>\n    /// <typeparam name=\"A\">Value type (never yielded because this is designed to error)</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> unexpected<A>(ErrorItem<T> item) =>\n        failure<A>(Some(item), default);\n    \n    /// <summary>\n    /// `observing(p)` allows us to 'observe' failure of the `p` parser,\n    /// should it happen, without actually ending parsing but instead getting\n    /// the `ParseError` in `Left`. On success, the parsed value is returned in\n    /// `Right`, as usual. Note, this primitive just allows you to observe\n    /// parse errors as they happen, it does not backtrack or change how the\n    /// `p` parser works in any way.\n    /// </summary>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <param name=\"p\">Parser</param>\n    /// <returns>Parser</returns>\n    public static K<MP, Either<ParseError<T, E>, A>> observing<A>(K<MP, A> p) =>\n        MP.Observing(p);\n\n    /// <summary>\n    /// Specify how to process a `ParseError` that happens inside the specified\n    /// region. This applies to both normal and delayed `ParseError` values.\n    /// \n    /// As a side effect of the implementation, the inner computation will start\n    /// with an empty collection of delayed errors; they will be updated and\n    /// “restored” on the way out of 'region'.\n    /// </summary>\n    /// <param name=\"mapError\">Error mapping for any raised error in the region</param>\n    /// <param name=\"region\">Region to process</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> region<A>(Func<ParseError<T, E>, ParseError<T, E>> mapError, K<MP, A> region) =>\n        from de in MP.Gets(s => s.ParseErrors) >>\n                   MP.Modify(s => s with { ParseErrors = [] })\n        from r1 in MP.Observing(region) >>\n                   MP.Modify(s => s with { ParseErrors = s.ParseErrors.Map(mapError) + de })\n        from r2 in r1 switch\n                   {\n                       Either<ParseError<T, E>, A>.Left (var err) => MP.Error<A>(mapError(err)),\n                       Either<ParseError<T, E>, A>.Right (var x)  => MP.Pure(x),\n                       _                                          => throw new NotSupportedException()\n                   }\n        select r2;\n  \n    /// <summary>\n    /// `withRecovery(f, p)` allows us to continue parsing even if the parser\n    /// `p` fails. In this case `f` is called with the `ParseError` as its\n    /// argument. Typical usage is to return a value signifying failure to\n    /// parse this particular object and to consume some part of the input up\n    /// to the point where the next object starts.\n    /// \n    /// Note that if `f` fails, the original error message is reported as if\n    /// without `withRecovery`. In no way can the recovering parser `f` influence\n    /// error messages.\n    /// </summary>\n    /// <param name=\"onError\">Delegate to invoke on error</param>\n    /// <param name=\"p\">Parser to run</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> withRecovery<A>(Func<ParseError<T, E>, K<MP, A>> onError, K<MP, A> p) =>\n        MP.WithRecovery(onError, p);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ModuleT/Lexer.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static partial class ModuleT<MP, E, S, T, M>\n    where MP : MonadParsecT<MP, E, S, T, M>\n    where S : TokenStream<S, T>\n    where M : Monad<M>\n{\n    // -- | @'space' sc lineComment blockComment@ produces a parser that can parse\n    // -- white space in general. It's expected that you create such a parser once\n    // -- and pass it to other functions in this module as needed (when you see\n    // -- @spaceConsumer@ in documentation, usually it means that something like\n    // -- 'space' is expected there).\n    // --\n    // -- @sc@ is used to parse blocks of space characters. You can use\n    // -- 'Text.Megaparsec.Char.space1' from \"Text.Megaparsec.Char\" for this\n    // -- purpose as well as your own parser (if you don't want to automatically\n    // -- consume newlines, for example). Make sure that the parser does not\n    // -- succeed on the empty input though. In an earlier version of the library\n    // -- 'Text.Megaparsec.Char.spaceChar' was recommended, but now parsers based\n    // -- on 'takeWhile1P' are preferred because of their speed.\n    // --\n    // -- @lineComment@ is used to parse line comments. You can use\n    // -- @skipLineComment@ if you don't need anything special.\n    // --\n    // -- @blockComment@ is used to parse block (multi-line) comments. You can use\n    // -- @skipBlockComment@ or @skipBlockCommentNested@ if you don't need anything\n    // -- special.\n    // --\n    // -- If you don't want to allow a kind of comment, simply pass 'empty' which\n    // -- will fail instantly when parsing of that sort of comment is attempted and\n    // -- 'space' will just move on or finish depending on whether there is more\n    // -- white space for it to consume.\n    // space ::\n    //   (MonadParsec e s m) =>\n    //   -- | A parser for space characters which does not accept empty\n    //   -- input (e.g. 'Text.Megaparsec.Char.space1')\n    //   m () ->\n    //   -- | A parser for a line comment (e.g. 'skipLineComment')\n    //   m () ->\n    //   -- | A parser for a block comment (e.g. 'skipBlockComment')\n    //   m () ->\n    //   m ()\n    // space sp line block =\n    //   skipMany $\n    //     choice\n    //       [hidden sp, hidden line, hidden block]\n    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ModuleT/Prim.cs",
    "content": "using System.Diagnostics.Contracts;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static partial class ModuleT<MP, E, S, T, M>\n    where MP : MonadParsecT<MP, E, S, T, M>\n    where S : TokenStream<S, T>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Match a single token\n    /// </summary>\n    /// <example>\n    ///     semicolon = single(';')\n    /// </example>\n    /// <param name=\"token\">Token to match</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> single(T token) =>\n        single<EqDefault<T>>(token);\n    \n    /// <summary>\n    /// Match a single token\n    /// </summary>\n    /// <example>\n    ///     semicolon = single(';')\n    /// </example>\n    /// <typeparam name=\"EqT\">Equality trait</typeparam>\n    /// <param name=\"token\">Token to match</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> single<EqT>(T token) \n        where EqT : Eq<T> =>\n        token<T>(x => EqT.Equals(x, token) ? Some(x) : None,\n                 Set.singleton(ErrorItem.Token(token)));\n\n    /// <summary>\n    /// The parser `satisfy(f)` succeeds for any token for which the supplied\n    /// function `f` returns `True`.\n    /// </summary>\n    /// <remarks>\n    /// **Performance note**: when you need to parse a single token, it is often\n    /// a good idea to use `satisfy` with the right predicate function instead of\n    /// creating a complex parser using the combinators.\n    /// </remarks>\n    /// <remarks>\n    /// See also: `anySingle`, `anySingleBut`, `oneOf`, `noneOf`.\n    /// </remarks>\n    /// <param name=\"f\">Predicate function</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> satisfy(Func<T, bool> f) =>\n        token<T>(x => f(x) ? Some(x) : None, default);\n\n    /// <summary>\n    /// Parse and return a single token. It's a good idea to attach a 'label'\n    /// to this parser.\n    /// </summary>\n    public static readonly K<MP, T> anySingle =\n        satisfy(_ => true);\n\n    /// <summary>\n    /// Match any token but the given one. It's a good idea to attach a `label`\n    /// to this parser.\n    /// </summary>\n    /// <param name=\"token\">Token to avoid</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> anySingleBut(T token) =>\n        anySingleBut<EqDefault<T>>(token);\n\n    /// <summary>\n    /// Match any token but the given one. It's a good idea to attach a `label`\n    /// to this parser.\n    /// </summary>\n    /// <typeparam name=\"EqT\">Equality trait</typeparam>\n    /// <param name=\"token\">Token to avoid</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> anySingleBut<EqT>(T token) \n        where EqT : Eq<T> =>\n        satisfy(x => !EqT.Equals(x, token));\n\n    /// <summary>\n    /// `chunk(chk)` only matches the chunk `chk`.\n    /// </summary>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, S> chunk(S chk) =>\n        tokens(static (x, y) => x.Equals(y), chk);\n\n    /// <summary>\n    /// The parser `label(name, p)` behaves as parser `p`, but whenever the\n    /// parser `p` fails _without consuming any input_, it replaces names of\n    /// 'expected' tokens with the name `name`.\n    /// </summary>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <param name=\"name\">Label name</param>\n    /// <param name=\"p\">Parser to label</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, A> label<A>(string name, K<MP, A> p) =>\n        MP.Label(name, p);\n\n    /// <summary>\n    /// `hidden(p)` behaves just like parser `p`, but it doesn't show any\n    /// 'expected' tokens in the error-message when `p` fails.\n    /// </summary>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <param name=\"p\">Parser to hide</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, A> hidden<A>(K<MP, A> p) =>\n        MP.Hidden(p);\n\n    /// <summary>\n    /// The parser `Try(p)` behaves like the parser `p`, except that it\n    /// backtracks the parser state when `p` fails (either consuming input or\n    /// not).\n    /// </summary>\n    /// <remarks>\n    /// This combinator is used whenever arbitrary look-ahead is needed. Since\n    /// it pretends that it hasn't consumed any input when `p` fails, the\n    /// (`|`) combinator will try its second alternative even if the first\n    /// parser failed while consuming input.\n    /// </remarks>\n    /// <example>\n    /// For example, here is a parser that is supposed to parse the word “let”\n    /// or the word “lexical”:\n    ///\n    ///     parseTest((string(\"let\") | string(\"lexical\")), \"lexical\")\n    /// \n    ///     unexpected \"lex\"\n    ///     expecting \"let\"\n    ///\n    /// What happens here? The first parser consumes “le” and fails (because it\n    /// doesn't see a “t”). The second parser, however, isn't tried, since the\n    /// first parser has already consumed some input! `Try` fixes this behavior\n    /// and allows backtracking to work:\n    ///\n    ///     parseTest((try (string(\"let\")) | string(\"lexical\")), \"lexical\")\n    ///     \"lexical\"\n    ///\n    /// `Try` also improves error messages in case of overlapping alternatives,\n    /// because Megaparsec's hint system can be used:\n    ///\n    ///     parseTest((try (string(\"let\")) | string(\"lexical\")), \"le\")\n    /// \n    ///     unexpected \"le\"\n    ///     expecting \"let\" or \"lexical\"\n    /// </example>\n    /// **Note** that the combinator: `string` backtracks automatically (see `tokens`), so it\n    /// does not need `Try`. However, the examples above demonstrate the idea behind 'Try' so well\n    /// that it was decided to keep them. You still need to use 'Try' when your\n    /// alternatives are complex, composite parsers.\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <param name=\"p\">Parser to try</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, A> @try<A>(K<MP, A> p) =>\n        MP.Try(p);\n\n    /// <summary>\n    /// If `p` in `lookAhead(p)` succeeds (either by consuming input or not),\n    /// the whole parser behaves like `p` succeeded without consuming anything\n    /// (parser state is also not updated). If `p` fails, `lookAhead` has no\n    ///  effect, i.e. it will fail consuming input if `p` fails consuming input.\n    ///  Combine with `try` if this is undesirable\n    /// </summary>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <param name=\"p\">Parser to look ahead with</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, A> lookAhead<A>(K<MP, A> p) =>\n        MP.LookAhead(p);\n\n    /// <summary>\n    /// `notFollowedBy(p)` only succeeds when the parser `p` fails. This parser\n    /// /never consumes/ any input and /never modifies/ parser state. It can be\n    /// used to implement the “longest match” rule.\n    /// </summary>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <param name=\"p\">Parser to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Unit> notFollowedBy<A>(K<MP, A> p) => \n        MP.NotFollowedBy(p);\n\n    /// <summary>\n    /// This parser only succeeds at the end of input\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static readonly K<MP, Unit> eof =\n        MP.EOF;\n\n    /// <summary>\n    /// An escape hatch for defining custom 'MonadParsec' primitives\n    /// </summary>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <param name=\"f\">Parsing function to lift</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, A> lift<A>(Func<State<S, T, E>, Reply<E, S, T, A>> f) =>\n        MP.Lift(f);\n\n    /// <summary>\n    /// `oneOf(cases)` succeeds if the current token is in the collection of token\n    /// `cases`. Returns the parsed token. Note, this parser cannot automatically\n    /// generate the “expected” component of the error-message, so usually you should\n    /// label it manually with `label` or `|`.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable trait</typeparam>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> oneOf<F>(K<F, T> cases)\n        where F : Foldable<F> =>\n        oneOf<F, EqDefault<T>>(cases);\n\n    /// <summary>\n    /// `oneOf(cases)` succeeds if the current token is in the collection of token\n    /// `cases`. Returns the parsed token. Note, this parser cannot automatically\n    /// generate the “expected” component of the error-message, so usually you should\n    /// label it manually with `label` or `|`.\n    /// </summary>\n    /// <typeparam name=\"F\">Foldable trait</typeparam>\n    /// <typeparam name=\"EqT\">Equality trait</typeparam>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> oneOf<F, EqT>(K<F, T> cases)\n        where F : Foldable<F> \n        where EqT : Eq<T> =>\n        satisfy(x => Foldable.contains<EqT, F, T>(x, cases));\n\n    /// <summary>\n    /// `oneOf(cases)` succeeds if the current token is in the collection of token\n    /// `cases`. Returns the parsed token. Note, this parser cannot automatically\n    /// generate the “expected” component of the error-message, so usually you should\n    /// label it manually with `label` or `|`.\n    /// </summary>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> oneOf(ReadOnlySpan<T> cases) =>\n        MP.OneOf<EqDefault<T>>(S.TokensToChunk(cases));\n\n    /// <summary>\n    /// `oneOf(cases)` succeeds if the current token is in the collection of token\n    /// `cases`. Returns the parsed token. Note, this parser cannot automatically\n    /// generate the “expected” component of the error-message, so usually you should\n    /// label it manually with `label` or `|`.\n    /// </summary>\n    /// <typeparam name=\"EqT\">Equality trait</typeparam>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> oneOf<EqT>(ReadOnlySpan<T> cases) \n        where EqT : Eq<T> =>\n        MP.OneOf<EqT>(S.TokensToChunk(cases));\n\n    /// <summary>\n    /// `oneOf(cases)` succeeds if the current token is in the collection of token\n    /// `cases`. Returns the parsed token. Note, this parser cannot automatically\n    /// generate the “expected” component of the error-message, so usually you should\n    /// label it manually with `label` or `|`.\n    /// </summary>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> oneOf(S cases) =>\n        MP.OneOf<EqDefault<T>>(cases);\n    \n    /// <summary>\n    /// `oneOf(cases)` succeeds if the current token is in the collection of token\n    /// `cases`. Returns the parsed token. Note, this parser cannot automatically\n    /// generate the “expected” component of the error-message, so usually you should\n    /// label it manually with `label` or `|`.\n    /// </summary>\n    /// <typeparam name=\"EqT\">Equality trait</typeparam>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> oneOf<EqT>(S cases) \n        where EqT : Eq<T> =>\n        MP.OneOf<EqT>(cases);\n\n    /// <summary>\n    /// As the dual of `oneOf`, `noneOf` succeeds if the current token is not in the\n    /// supplied list of token `cases`. Returns the parsed character. Note that this\n    /// parser cannot automatically generate the “expected” component of the\n    /// error-message, so usually you should label it manually with.\n    /// `label` or `|`\n    /// </summary>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <typeparam name=\"F\">Foldable trait</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> noneOf<F>(K<F, T> cases)\n        where F : Foldable<F> =>\n        satisfy(x => !Foldable.contains(x, cases));\n    \n    /// <summary>\n    /// As the dual of `oneOf`, `noneOf` succeeds if the current token is not in the\n    /// supplied list of token `cases`. Returns the parsed character. Note that this\n    /// parser cannot automatically generate the “expected” component of the\n    /// error-message, so usually you should label it manually with.\n    /// `label` or `|`\n    /// </summary>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <typeparam name=\"EqT\">Equality trait</typeparam>\n    /// <typeparam name=\"F\">Foldable trait</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> noneOf<EqT, F>(K<F, T> cases)\n        where F : Foldable<F> \n        where EqT : Eq<T> =>\n        satisfy(x => !Foldable.contains<EqT, F, T>(x, cases));\n    \n    /// <summary>\n    /// As the dual of `oneOf`, `noneOf` succeeds if the current token is not in the\n    /// supplied list of token `cases`. Returns the parsed character. Note that this\n    /// parser cannot automatically generate the “expected” component of the\n    /// error-message, so usually you should label it manually with.\n    /// `label` or `|`\n    /// </summary>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> noneOf(ReadOnlySpan<T> cases) => \n        MP.NoneOf<EqDefault<T>>(S.TokensToChunk(cases));\n    \n    /// <summary>\n    /// As the dual of `oneOf`, `noneOf` succeeds if the current token is not in the\n    /// supplied list of token `cases`. Returns the parsed character. Note that this\n    /// parser cannot automatically generate the “expected” component of the\n    /// error-message, so usually you should label it manually with.\n    /// `label` or `|`\n    /// </summary>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <typeparam name=\"EqT\">Equality trait</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> noneOf<EqT>(ReadOnlySpan<T> cases) \n        where EqT : Eq<T> =>\n        MP.NoneOf<EqT>(S.TokensToChunk(cases));\n    \n    /// <summary>\n    /// As the dual of `oneOf`, `noneOf` succeeds if the current token is not in the\n    /// supplied list of token `cases`. Returns the parsed character. Note that this\n    /// parser cannot automatically generate the “expected” component of the\n    /// error-message, so usually you should label it manually with.\n    /// `label` or `|`\n    /// </summary>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> noneOf(S cases) => \n        MP.NoneOf<EqDefault<T>>(cases);\n    \n    /// <summary>\n    /// As the dual of `oneOf`, `noneOf` succeeds if the current token is not in the\n    /// supplied list of token `cases`. Returns the parsed character. Note that this\n    /// parser cannot automatically generate the “expected” component of the\n    /// error-message, so usually you should label it manually with.\n    /// `label` or `|`\n    /// </summary>\n    /// <param name=\"cases\">Token cases to test</param>\n    /// <typeparam name=\"EqT\">Equality trait</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, T> noneOf<EqT>(S cases) \n        where EqT : Eq<T> =>\n        MP.NoneOf<EqT>(cases);\n    \n    /// <summary>\n    /// The `choice(ps)` parser tries to apply the parsers in the list `ps` in order,\n    /// until one of them succeeds. Returns the value of the succeeding parser.\n    /// </summary>\n    /// <param name=\"ps\">Parsers to try</param>\n    /// <typeparam name=\"A\">Type of value to parse</typeparam>\n    /// <returns>Succeeding parser or MP.Empty on fail - use the `|` operator to capture failure</returns>\n    [Pure]\n    public static K<MP, A> choice<A>(params ReadOnlySpan<K<MP, A>> ps) =>\n        Alternative.choice(ps);\n\n    /// <summary>\n    /// One or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly, collecting the results, until failure.\n    ///\n    /// Will succeed if at least one item has been yielded.\n    /// </remarks>\n    /// <param name=\"p\">Parser</param>\n    /// <returns>One or more values</returns>\n    [Pure]\n    public static K<MP, Seq<A>> some<A>(K<MP, A> p) =>\n        Alternative.some(p);\n    \n    /// <summary>\n    /// Zero or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative parser repeatedly, collecting the results, until failure.\n    /// Will always succeed.\n    /// </remarks>\n    /// <param name=\"p\">Parser</param>\n    /// <returns>Zero or more values</returns>\n    [Pure]\n    public static K<MP, Seq<A>> many<A>(K<MP, A> p) =>\n        Alternative.many(p);\n\n    /// <summary>\n    /// Skip zero or more...\n    /// </summary>\n    /// <remarks>\n    /// Run the parser repeatedly until failure.\n    /// Will always succeed.\n    /// </remarks>\n    /// <param name=\"p\">Parser</param>\n    /// <returns>Unit</returns>\n    [Pure]\n    public static K<MP, Unit> skipMany<A>(K<MP, A> p) =>\n        Alternative.skipMany(p);\n    \n    /// <summary>\n    /// `endBy(p, sep)` parses zero-or-more occurrences of `p`, separated and ended by\n    /// `sep`. Returns a list of values returned by `p`.\n    /// </summary>\n    /// <param name=\"p\">Value parser</param>\n    /// <param name=\"sep\">Separator parser</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<MP, Seq<A>> endBy<A, SEP>(K<MP, A> p, K<MP, SEP> sep) =>\n        Alternative.endBy(p, sep);\n    \n    /// <summary>\n    /// `endBy1(p, sep)` parses one-or-more occurrences of `p`, separated and ended by\n    /// `sep`. Returns a list of values returned by `p`.\n    /// </summary>\n    /// <param name=\"p\">Value parser</param>\n    /// <param name=\"sep\">Separator parser</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<MP, Seq<A>> endBy1<A, SEP>(K<MP, A> p, K<MP, SEP> sep) =>\n        Alternative.endBy1(p, sep);\n    \n    /// <summary>\n    /// Combine two alternatives\n    /// </summary>\n    /// <param name=\"ma\">Left parser</param>\n    /// <param name=\"mb\">Right parser</param>\n    /// <typeparam name=\"A\">Left value type</typeparam>\n    /// <typeparam name=\"B\">Right value type</typeparam>\n    /// <returns>Parser structure with an `Either` lifted into it</returns>\n    [Pure]\n    public static K<MP, Either<A, B>> either<A, B>(K<MP, A> ma, K<MP, B> mb) =>\n        Alternative.either(ma, mb);\n    \n    /// <summary>\n    /// `manyUntil(p, end)` applies `p` _zero_ or more times until `end` succeeds.\n    /// Returns the list of values returned by`p`. `end` result is consumed and\n    /// lost. Use `manyUntil2` if you wish to keep it.\n    /// </summary>\n    /// <param name=\"p\">Parser to consume</param>\n    /// <param name=\"end\">Terminating parser</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Seq<A>> manyUntil<A, END>(K<MP, A> p, K<MP, END> end) =>\n        Alternative.manyUntil(p, end);\n        \n    /// <summary>\n    /// `manyUntil2(p, end)` applies `p` _zero_ or more times until `end` succeeds.\n    /// Returns the list of values returned by `p` plus the `end` result.\n    ///\n    /// Use `manyUntil` if you don't wish to keep the `end` result.\n    /// </summary>\n    /// <param name=\"p\">Parser to consume</param>\n    /// <param name=\"end\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, (Seq<A> Items, END End)> manyUntil2<A, END>(K<MP, A> p, K<MP, END> end) =>\n        Alternative.manyUntil2(p, end);\n    \n    /// <summary>\n    /// `someUntil(p, end)` applies `p` _one_ or more times until `end` succeeds.\n    /// Returns the list of values returned by `p`. `end` result is consumed and\n    /// lost. Use `someUntil2` if you wish to keep it.\n    /// </summary>\n    /// <param name=\"p\">Structure to consume</param>\n    /// <param name=\"end\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Seq<A>> someUntil<A, END>(K<MP, A> p, K<MP, END> end)  =>\n        Alternative.someUntil(p, end);\n\n    /// <summary>\n    /// `someUntil2(p, end)` applies `p` _one_ or more times until `end` succeeds.\n    /// Returns the list of values returned by `p` plus the `end` result.\n    ///\n    /// Use `someUntil` if you don't wish to keep the `end` result.\n    /// </summary>\n    /// <param name=\"p\">Structure to consume</param>\n    /// <param name=\"end\">Terminating structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, (Seq<A> Items, END End)> someUntil2<A, END>(K<MP, A> p, K<MP, END> end) =>\n        Alternative.someUntil2(p, end);\n    \n    /// <summary>\n    /// `option(x, p)` tries to apply `p`. If `p` fails without 'consuming' anything, it\n    /// returns `value`, otherwise the value returned by `p`.\n    /// </summary>\n    /// <param name=\"value\">Default value to use if `o` fails without 'consuming' anything</param>\n    /// <param name=\"p\">Parser</param>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, A> option<A>(A value, K<MP, A> p)  =>\n        Alternative.option(value, p);\n    \n    /// <summary>\n    /// `sepBy(p, sep) processes _zero_ or more occurrences of `p`, separated by `sep`. \n    /// </summary>\n    /// <param name=\"p\">Structure to yield return values</param>\n    /// <param name=\"sep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Seq<A>> sepBy<A, SEP>(K<MP, A> p, K<MP, SEP> sep)  =>\n        Alternative.sepBy(p, sep);\n    \n    /// <summary>\n    /// `sepBy(p, sep) processes _one_ or more occurrences of `p`, separated by `sep`. \n    /// </summary>\n    /// <param name=\"p\">Structure to yield return values</param>\n    /// <param name=\"sep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Seq<A>> sepBy1<A, SEP>(K<MP, A> p, K<MP, SEP> sep)  =>\n        Alternative.sepBy1(p, sep);\n\n    /// <summary>\n    /// `sepEndBy(p, sep) processes _zero_ or more occurrences of `p`, separated\n    /// and optionally ended by `sep`. Returns a list of values returned by `p`.\n    /// </summary>\n    /// <param name=\"p\">Structure to yield return values</param>\n    /// <param name=\"sep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Seq<A>> sepByEnd<A, SEP>(K<MP, A> p, K<MP, SEP> sep)  =>\n        Alternative.sepByEnd(p, sep);\n\n    /// <summary>\n    /// `sepEndBy1(p, sep) processes _one_ or more occurrences of `p`, separated\n    /// and optionally ended by `sep`. Returns a list of values returned by `p`.\n    /// </summary>\n    /// <param name=\"p\">Structure to yield return values</param>\n    /// <param name=\"sep\">Separator structure</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"SEP\">Separator type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Seq<A>> sepByEnd1<A, SEP>(K<MP, A> p, K<MP, SEP> sep) =>\n        Alternative.sepByEnd1(p, sep);\n    \n    /// <summary>\n    /// Process `p` _one_ or more times and drop all yielded values.\n    /// </summary>\n    /// <remarks>\n    /// Run the applicative functor repeatedly until failure. At least one item must be yielded for overall success.\n    /// </remarks>\n    /// <param name=\"p\">Parser</param>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Unit> skipSome<A>(K<MP, A> p) => \n        Alternative.skipSome(p);\n\n    /// <summary>\n    /// `skip(n, p)` processes `n` occurrences of `p`, skipping its result.\n    /// If `n` is not positive, the process equates to `Pure(unit)`.\n    /// </summary>\n    /// <param name=\"n\">Number of occurrences of `fa` to skip</param>\n    /// <param name=\"p\">Parser</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, Unit> skip<A>(int n, K<MP, A> p) => \n        Alternative.skip(n, p);\n\n    /// <summary>\n    /// `skipManyUntil(p, end)` applies the process `p` _zero_ or more times\n    /// skipping results until process `end` succeeds. The resulting value from\n    /// `end` is then returned.\n    /// </summary>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns>Parser</returns>\n    [Pure]\n    public static K<MP, END> skipManyUntil<A, END>(K<MP, A> p, K<MP, END> end) =>\n        Alternative.skipManyUntil(p, end);\n\n    /// <summary>\n    /// `skipManyUntil(p, end)` applies the process `p` _one_ or more times\n    /// skipping results until process `end` succeeds. The resulting value from\n    /// `end` is then returned.\n    /// </summary>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <typeparam name=\"END\">End value type</typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static K<MP, END> skipSomeUntil<A, END>(K<MP, A> p, K<MP, END> end) => \n        Alternative.skipSomeUntil(p, end);    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ModuleT/State.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static partial class ModuleT<MP, E, S, T, M>\n    where MP : MonadParsecT<MP, E, S, T, M>\n    where S : TokenStream<S, T>\n    where M : Monad<M>\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  State parser combinators\n    //\n\n    /// <summary>\n    /// Return the full parser state as a `State` record\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static readonly K<MP, State<S, T, E>> getParserState =\n        MP.Ask;\n\n    /// <summary>\n    /// Write the full parser state\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static K<MP, Unit> setParserState(State<S, T, E> s) => \n        MP.Put(s);\n\n    /// <summary>\n    /// Return the full parser state and then map it to a new value using the supplied function\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static K<MP, A> mapParserState<A>(Func<State<S, T, E>, A> f) => \n        MP.Asks(f);\n\n    /// <summary>\n    /// Update the parser state using the supplied function\n    /// </summary>\n    /// <param name=\"f\">Update function</param>\n    /// <returns>Parser</returns>\n    public static K<MP, Unit> modifyParserState(Func<State<S, T, E>, State<S, T, E>> f) =>\n        MP.Modify(f);\n\n    /// <summary>\n    /// Return the current input\n    /// </summary>\n    public static readonly K<MP, S> getInput =\n        MP.Asks(s => s.Input);\n\n    /// <summary>\n    /// `setInput(input)` continues parsing with `input`.\n    /// </summary>\n    /// <param name=\"input\">Input to continue with</param>\n    /// <returns>Parser</returns>\n    public static K<MP, Unit> setInput(S input) =>\n        MP.Modify(current => current with { Input = input });\n\n    /// <summary>\n    /// Get the number of tokens processed so far.\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static readonly K<MP, int> getOffset =\n        MP.Asks(x => x.Offset);\n\n    /// <summary>\n    /// Set the number of tokens processed so far\n    /// </summary>\n    /// <param name=\"offset\">Token offset</param>\n    /// <returns>Parser</returns>\n    public static K<MP, Unit> setOffset(int offset) =>\n        MP.Modify(s => s with { Offset = offset });\n    \n    /// <summary>\n    /// Return the current source position. This function /is not cheap/, do\n    /// not call it e.g. on matching of every token, that's a bad idea. Still you\n    /// can use it to get 'SourcePos' to attach to things that you parse.\n    /// \n    /// The function works under the assumption that we move in the input stream\n    /// only forwards and never backwards, which is always true unless the user\n    /// abuses the library.\n    /// </summary>\n    /// <remarks>\n    /// This isn't a high-performance function, use infrequently and only when you\n    /// need to get the position of the current token.\n    /// </remarks>\n    /// <returns>Parser</returns>\n    public static readonly K<MP, SourcePos> getSourcePos =\n        from st in MP.Get\n        let pst =  Reach<S, T>.offsetNoLine(st.Offset, st.PosState)\n        from _  in MP.Put(st with { PosState = pst })\n        select pst.SourcePos;    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ModuleT/Text.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static partial class ModuleT<MP, E, S, M>\n    where MP : MonadParsecT<MP, E, S, char, M>\n    where S : TokenStream<S, char>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Parse a string\n    /// </summary>\n    public static K<MP, S> @string(string xs) =>\n        ModuleT<MP, E, S, char, M>.chunk(S.TokensToChunk(xs.AsSpan()));\n\n    /// <summary>\n    /// Parse the specified character\n    /// </summary>\n    /// <param name=\"c\">Character to parse</param>\n    /// <returns>Parser</returns>\n    public static K<MP, char> ch(char c) =>\n        MP.Token(ch => ch == c ? Some(c) : None, Set.singleton(ErrorItem.Label<char>($\"{c}\")));\n    \n    /// <summary>\n    /// Parse a newline character.\n    /// </summary>\n    public static readonly K<MP, char> newline =\n        MP.Token(static ch => ch == '\\n' ? Some('\\n') : None, ExpectedErrors.newline);\n    \n    /// <summary>\n    /// Parse a newline character.\n    /// </summary>\n    public static readonly K<MP, char> tab =\n        MP.Token(static ch => ch == '\\t' ? Some('\\t') : None, ExpectedErrors.tab);\n\n    /// <summary>\n    /// Parse a newline character.\n    /// </summary>\n    public static readonly K<MP, S> crlf =\n        ModuleT<MP, E, S, char, M>.chunk(S.TokensToChunk(['\\r', '\\n']));\n    \n    /// <summary>\n    /// End of line parser.\n    /// </summary>\n    /// <remarks>\n    /// Tries a newline parser first, then tries a carriage-return followed by a newline parser.\n    /// </remarks>\n    public static readonly K<MP, S> eol =\n        charToStream * newline \n            | crlf\n            | Prelude.label(\"end of line\");\n\n    /// <summary>\n    /// Parse an uppercase letter\n    /// </summary>\n    public static readonly K<MP, char> upperChar =\n        MP.Token(static ch => char.IsUpper(ch) ? Some(ch) : None, ExpectedErrors.upperChar);\n\n    /// <summary>\n    /// Parse a lowercase letter\n    /// </summary>\n    public static readonly K<MP, char> lowerChar =\n        MP.Token(static ch => char.IsLower(ch) ? Some(ch) : None, ExpectedErrors.lowerChar);\n\n    /// <summary>\n    /// Parse a letter\n    /// </summary>\n    public static readonly K<MP, char> letterChar =\n        MP.Token(static ch => char.IsLetter(ch) ? Some(ch) : None, ExpectedErrors.letterChar);\n\n    /// <summary>\n    /// Parse an alphanumeric character (letter or digit)\n    /// </summary>\n    public static readonly K<MP, char> aplhaNumChar =\n        MP.Token(static ch => char.IsLetterOrDigit(ch) ? Some(ch) : None, ExpectedErrors.alphaNumChar);\n\n    /// <summary>\n    /// Parse a digit\n    /// </summary>\n    public static readonly K<MP, char> digitChar =\n        MP.Token(static ch => char.IsDigit(ch) ? Some(ch) : None, ExpectedErrors.digitChar);\n\n    /// <summary>\n    /// Parse a binary digit\n    /// </summary>\n    public static readonly K<MP, char> binaryDigitChar =\n        MP.Token(static ch => ch is '0' or '1' ? Some(ch) : None, ExpectedErrors.binaryDigitChar);\n\n    /// <summary>\n    /// Parse a hexadecimal digit\n    /// </summary>\n    public static readonly K<MP, char> hexDigitChar =\n        MP.Token(static ch => char.IsAsciiHexDigit(ch) ? Some(ch) : None, ExpectedErrors.hexDigitChar);\n\n    /// <summary>\n    /// Parse a number character\n    /// </summary>\n    public static readonly K<MP, char> numberChar =\n        MP.Token(static ch => char.IsNumber(ch) ? Some(ch) : None, ExpectedErrors.numberChar);\n\n    /// <summary>\n    /// Parse a symbol character\n    /// </summary>\n    public static readonly K<MP, char> symbolChar =\n        MP.Token(static ch => char.IsSymbol(ch) ? Some(ch) : None, ExpectedErrors.symbolChar);\n\n    /// <summary>\n    /// Parse a punctuation character\n    /// </summary>\n    public static readonly K<MP, char> punctuationChar =\n        MP.Token(static ch => char.IsPunctuation(ch) ? Some(ch) : None, ExpectedErrors.punctuationChar);\n\n    /// <summary>\n    /// Parse a white-space character.\n    /// </summary>\n    public static readonly K<MP, char> spaceChar =\n        MP.Token(static ch => char.IsWhiteSpace(ch) ? Some(ch) : None, ExpectedErrors.whiteSpaceChar);\n\n    /// <summary>\n    /// Parse zero or more white-space characters.\n    /// </summary>\n    public static readonly K<MP, Unit> space =\n        (static _ => unit) * MP.TakeWhile(char.IsWhiteSpace, ExpectedErrors.whiteSpace);\n\n    /// <summary>\n    /// Parse one or more white-space characters.\n    /// </summary>\n    public static readonly K<MP, Unit> space1 =\n        (static _ => unit) * MP.TakeWhile1(char.IsWhiteSpace, ExpectedErrors.whiteSpace);\n\n    /// <summary>\n    /// Parse zero or more white-space characters (ignoring newlines and carriage-returns).\n    /// </summary>\n    public static readonly K<MP, Unit> hspace =\n        (static _ => unit) * MP.TakeWhile(static ch => ch != '\\n' && ch != '\\r' && char.IsWhiteSpace(ch),\n                                          ExpectedErrors.whiteSpace);\n\n    /// <summary>\n    /// Parse zero or more white-space characters (ignoring newlines and carriage-returns).\n    /// </summary>\n    public static readonly K<MP, Unit> hspace1 =\n        (static _ => unit) * MP.TakeWhile1(static ch => ch != '\\n' && ch != '\\r' && char.IsWhiteSpace(ch),\n                                           ExpectedErrors.whiteSpace);\n\n    /// <summary>\n    /// Parse a control character\n    /// </summary>\n    public static readonly K<MP, char> controlChar =\n        MP.Token(static ch => char.IsControl(ch) ? Some(ch) : None, ExpectedErrors.control);\n\n    /// <summary>\n    /// Parse a separator character\n    /// </summary>\n    public static readonly K<MP, char> separatorChar =\n        MP.Token(static ch => char.IsSeparator(ch) ? Some(ch) : None, ExpectedErrors.separator);\n    \n    /// <summary>\n    /// Make a chunk `S` from a single token `char`\n    /// </summary>\n    public static S charToStream(char ch) =>\n        S.TokenToChunk(ch);\n    \n    static K<MP, char> Test =>\n        ModuleT<MP, E, S, char, M>.oneOf(['1', '2', '3']) | label(\"hello\");\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ModuleT/Token.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static partial class ModuleT<MP, E, S, T, M>\n    where MP : MonadParsecT<MP, E, S, T, M>\n    where S : TokenStream<S, T>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// The parser `token(test, expected)` accepts tokens for which the\n    /// matching function `test` returns `Some` result. If `None` is\n    /// returned, the `expected` set is used to report the items that were\n    /// expected.\n    /// </summary>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <param name=\"test\">Token predicate test function</param>\n    /// <param name=\"expected\">Expected items</param>\n    /// <returns>Token parser</returns>\n    public static K<MP, A> token<A>(Func<T, Option<A>> test, in Set<ErrorItem<T>> expected) => \n        MP.Token(test, expected);\n    \n    /// <summary>\n    /// The parser `tokens(test, chunk)` parses a chunk of input and returns it.\n    /// The supplied predicate `test` is used to check equality of given and parsed\n    /// chunks after a candidate chunk of correct length is fetched from the stream.\n    /// \n    /// This can be used, for example, to write 'chunk':\n    /// \n    ///     chunk = tokens (==)\n    /// \n    /// Note that this is an auto-backtracking primitive, which means that if it\n    /// fails, it never consumes any input. This is done to make its consumption\n    /// model match how error messages for this primitive are reported (which\n    /// becomes an important thing as user gets more control with primitives like\n    /// 'withRecovery'):\n    /// \n    ///     parseTest((string(\"abc\")), \"abd\")\n    /// \n    ///     unexpected \"abd\"\n    ///     expecting \"abc\"\n    /// \n    /// This means that it's not necessary to use `@try` with `tokens`-based parsers,\n    /// such as `string` and. \n    /// </summary>\n    /// <param name=\"test\">Predicate test function. The first argument is the chunk to\n    /// test, the second argument is the reference chunk.</param>\n    /// <param name=\"chunk\">Reference chunk</param>\n    /// <returns>Parsed chunk</returns>\n    public static K<MP, S> tokens(Func<S, S, bool> test, S chunk) =>\n        MP.Tokens(test, chunk);\n    \n    /// <summary>\n    /// Parse zero or more tokens for which the supplied predicate holds.\n    /// Try to use this as much as possible because, for many streams, this\n    /// combinator is much faster than parsers built with `many` and `satisfy`.\n    /// \n    ///     takeWhile((Some \"foo\"), f) = many (satisfy(f) | \"foo\")\n    ///     takeWhile(None,         f) = many (satisfy(f))\n    /// \n    /// The combinator never fails, although it may parse the empty chunk.\n    /// </summary>\n    /// <param name=\"test\">Predicate to use to test tokens</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static K<MP, S> takeWhile(Func<T, bool> test, Option<string> name = default) =>\n        MP.TakeWhile(test, name);\n    \n    /// <summary>\n    /// Parse one or more tokens for which the supplied predicate holds.\n    /// Try to use this as much as possible because, for many streams, this\n    /// combinator is much faster than parsers built with `many` and `satisfy`.\n    /// \n    ///     takeWhile((Some \"foo\"), f) = many (satisfy(f) | \"foo\")\n    ///     takeWhile(None,         f) = many (satisfy(f))\n    /// \n    /// The combinator never fails, although it may parse the empty chunk.\n    /// </summary>\n    /// <param name=\"test\">Predicate to use to test tokens</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static K<MP, S> takeWhile1(Func<T, bool> test, Option<string> name = default) =>\n        MP.TakeWhile1(test, name);\n\n    /// <summary>\n    /// Extract the specified number of tokens from the input stream and\n    /// return them packed as a chunk of stream. If there are not enough tokens\n    /// in the stream, a parse error will be signalled. It's guaranteed that if\n    /// the parser succeeds, the requested number of tokens will be returned.\n    /// \n    /// The parser is roughly equivalent to:\n    /// \n    ///     take((Just \"foo\"), n) = count(n, (anySingle | \"foo\"))\n    ///     take(Nothing,      n) = count(n, anySingle)\n    /// \n    /// Note that if the combinator fails due to an insufficient number of tokens\n    /// in the input stream, it backtracks automatically. No `@try` is necessary\n    /// with `take`.\n    /// </summary>\n    /// <param name=\"n\">How many tokens to extract</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static K<MP, S> take(int n, Option<string> name = default) => \n        MP.Take(n, name);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/MonadParsecT/MonadParsecT.Module.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// MonadParsec module\n/// </summary>\npublic static partial class Module<MP, E, S, M>\n    where MP : MonadParsecT<MP, E, S, char, M>\n    where S : TokenStream<S, char>\n    where M : Monad<M>\n{\n    /// <summary>\n    /// Stop parsing and report the `ParseError`. This is the only way to\n    /// control the position of the error without manipulating the parser state\n    /// manually.\n    /// </summary>\n    /// <param name=\"error\">Error</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> error<A>(ParseError<char, E> error) =>\n        MP.Error<A>(error);\n\n    /// <summary>\n    /// The parser `Label(name, p)` behaves as parser `p`, but whenever the\n    /// parser `p` fails /without consuming any input/, it replaces names of\n    /// “expected” tokens with the name `name`.\n    /// </summary>\n    /// <param name=\"name\">Label name</param>\n    /// <param name=\"p\">Parser to label</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> label<A>(string name, K<MP, A> p) =>\n        MP.Label(name, p);\n\n    /// <summary>\n    /// `hidden(p)` behaves just like parser `p`, but it doesn't show any\n    /// “expected” tokens in the error-message when `p` fails.\n    /// </summary>\n    /// <param name=\"p\">Parser to hide</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> hidden<A>(K<MP, A> p) =>\n        MP.Hidden(p);\n\n    /// <summary>\n    /// The parser `Try(p)` behaves like the parser `p`, except that it\n    /// backtracks the parser state when `p` fails (either consuming input or\n    /// not).\n    /// </summary>\n    /// <remarks>\n    /// This combinator is used whenever arbitrary look-ahead is needed. Since\n    /// it pretends that it hasn't consumed any input when `p` fails, the\n    /// (`|`) combinator will try its second alternative even if the first\n    /// parser failed while consuming input.\n    /// </remarks>\n    /// <example>\n    /// For example, here is a parser that is supposed to parse the word “let”\n    /// or the word “lexical”:\n    ///\n    ///     parseTest((string(\"let\") | string(\"lexical\")), \"lexical\")\n    /// \n    ///     unexpected \"lex\"\n    ///     expecting \"let\"\n    ///\n    /// What happens here? The first parser consumes “le” and fails (because it\n    /// doesn't see a “t”). The second parser, however, isn't tried, since the\n    /// first parser has already consumed some input! `Try` fixes this behavior\n    /// and allows backtracking to work:\n    ///\n    ///     parseTest((try (string(\"let\")) | string(\"lexical\")), \"lexical\")\n    ///     \"lexical\"\n    ///\n    /// `Try` also improves error messages in case of overlapping alternatives,\n    /// because Megaparsec's hint system can be used:\n    ///\n    ///     parseTest((try (string(\"let\")) | string(\"lexical\")), \"le\")\n    /// \n    ///     unexpected \"le\"\n    ///     expecting \"let\" or \"lexical\"\n    /// </example>\n    /// **Note** that the combinator: `string` backtracks automatically (see `tokens`), so it\n    /// does not need `Try`. However, the examples above demonstrate the idea behind 'Try' so well\n    /// that it was decided to keep them. You still need to use 'Try' when your\n    /// alternatives are complex, composite parsers.\n    /// <param name=\"p\">Parser to try</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> @try<A>(K<MP, A> p) =>\n        MP.Try(p);\n\n    /// <summary>\n    /// If `p` in `lookAhead(p)` succeeds (either by consuming input or not),\n    /// the whole parser behaves like `p` succeeded without consuming anything\n    /// (parser state is also not updated). If `p` fails, `lookAhead` has no\n    ///  effect, i.e. it will fail consuming input if `p` fails consuming input.\n    ///  Combine with `try` if this is undesirable\n    /// </summary>\n    /// <param name=\"p\">Parser to look ahead with</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> lookAhead<A>(K<MP, A> p) =>\n        MP.LookAhead(p);\n\n    /// <summary>\n    /// `notFollowedBy(p)` only succeeds when the parser `p` fails. This parser\n    /// /never consumes/ any input and /never modifies/ parser state. It can be\n    /// used to implement the “longest match” rule.\n    /// </summary>\n    /// <param name=\"p\">Parser to test</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, Unit> notFollowedBy<A>(K<MP, A> p) =>\n        MP.NotFollowedBy(p);\n  \n    /// <summary>\n    /// `withRecovery(f, p)` allows us to continue parsing even if the parser\n    /// `p` fails. In this case `f` is called with the `ParseError` as its\n    /// argument. Typical usage is to return a value signifying failure to\n    /// parse this particular object and to consume some part of the input up\n    /// to the point where the next object starts.\n    /// \n    /// Note that if `f` fails, the original error message is reported as if\n    /// without `withRecovery`. In no way can the recovering parser `f` influence\n    /// error messages.\n    /// </summary>\n    /// <param name=\"onError\">Delegate to invoke on error</param>\n    /// <param name=\"p\">Parser to run</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Parser</returns>\n    public static K<MP, A> withRecovery<A>(Func<ParseError<char, E>, K<MP, A>> onError, K<MP, A> p) =>\n        MP.WithRecovery(onError, p);    \n\n    /// <summary>\n    /// This parser only succeeds at the end of input\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static readonly K<MP, Unit> eof =\n        MP.EOF;\n\n    /// <summary>\n    /// `observing(p)` allows us to “observe” failure of the `p` parser,\n    /// should it happen, without actually ending parsing but instead getting\n    /// the `ParseError` in `Left`. On success, the parsed value is returned in\n    /// `Right` as usual. Note, this primitive just allows you to observe\n    /// parse errors as they happen, it does not backtrack or change how the\n    /// `p` parser works in any way.\n    /// </summary>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <param name=\"p\">Parser</param>\n    /// <returns>Parser</returns>\n    public static K<MP, Either<ParseError<char, E>, A>> observing<A>(K<MP, A> p) =>\n        MP.Observing(p);\n    \n    /// <summary>\n    /// The parser `token(test, expected)` accepts tokens for which the\n    /// matching function `test` returns `Some` result. If `None` is\n    /// returned, the `expected` set is used to report the items that were\n    /// expected.\n    /// </summary>\n    /// <param name=\"test\">Token predicate test function</param>\n    /// <param name=\"expected\">Expected items</param>\n    /// <typeparam name=\"A\">Value type to parse</typeparam>\n    /// <returns>Token parser</returns>\n    public static K<MP, A> token<A>(Func<char, Option<A>> test, in Set<ErrorItem<char>> expected) =>\n        MP.Token(test, expected);\n    \n    /// <summary>\n    /// The parser `tokens(test, chunk)` parses a chunk of input and returns it.\n    /// The supplied predicate `test` is used to check equality of given and parsed\n    /// chunks after a candidate chunk of correct length is fetched from the stream.\n    /// \n    /// This can be used, for example, to write 'chunk':\n    /// \n    ///     chunk = tokens (==)\n    /// \n    /// Note that this is an auto-backtracking primitive, which means that if it\n    /// fails, it never consumes any input. This is done to make its consumption\n    /// model match how error messages for this primitive are reported (which\n    /// becomes an important thing as user gets more control with primitives like\n    /// 'withRecovery'):\n    /// \n    ///     parseTest((string(\"abc\")), \"abd\")\n    /// \n    ///     unexpected \"abd\"\n    ///     expecting \"abc\"\n    /// \n    /// This means that it's not necessary to use `@try` with `tokens`-based parsers,\n    /// such as `string` and. \n    /// </summary>\n    /// <param name=\"test\">Predicate test function. The first argument is the chunk to\n    /// test, the second argument is the reference chunk.</param>\n    /// <param name=\"chunk\">Reference chunk</param>\n    /// <returns>Parsed chunk</returns>\n    public static K<MP, S> tokens(Func<S, S, bool> test, S chunk) =>\n        MP.Tokens(test, chunk);    \n    \n    /// <summary>\n    /// Parse zero or more tokens for which the supplied predicate holds.\n    /// Try to use this as much as possible because, for many streams, this\n    /// combinator is much faster than parsers built with `many` and `satisfy`.\n    /// \n    ///     takeWhile((Some \"foo\"), f) = many (satisfy(f) | \"foo\")\n    ///     takeWhile(None,         f) = many (satisfy(f))\n    /// \n    /// The combinator never fails, although it may parse the empty chunk.\n    /// </summary>\n    /// <param name=\"test\">Predicate to use to test tokens</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static K<MP, S> takeWhile(Func<char, bool> test, Option<string> name = default) =>\n        MP.TakeWhile(test, name);    \n    \n    /// <summary>\n    /// Parse one or more tokens for which the supplied predicate holds.\n    /// Try to use this as much as possible because, for many streams, this\n    /// combinator is much faster than parsers built with `many` and `satisfy`.\n    /// \n    ///     takeWhile((Some \"foo\"), f) = many (satisfy(f) | \"foo\")\n    ///     takeWhile(None,         f) = many (satisfy(f))\n    /// \n    /// The combinator never fails, although it may parse the empty chunk.\n    /// </summary>\n    /// <param name=\"test\">Predicate to use to test tokens</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static K<MP, S> takeWhile1(Func<char, bool> test, Option<string> name = default) =>\n        MP.TakeWhile1(test, name);\n\n    /// <summary>\n    /// Extract the specified number of tokens from the input stream and\n    /// return them packed as a chunk of stream. If there are not enough tokens\n    /// in the stream, a parse error will be signalled. It's guaranteed that if\n    /// the parser succeeds, the requested number of tokens will be returned.\n    /// \n    /// The parser is roughly equivalent to:\n    /// \n    ///     take((Just \"foo\"), n) = count(n, (anySingle | \"foo\"))\n    ///     take(Nothing,      n) = count(n, anySingle)\n    /// \n    /// Note that if the combinator fails due to an insufficient number of tokens\n    /// in the input stream, it backtracks automatically. No `@try` is necessary\n    /// with `take`.\n    /// </summary>\n    /// <param name=\"n\">How many tokens to extract</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static K<MP, S> take(int n, Option<string> name = default) =>\n        MP.Take(n, name);\n\n    /// <summary>\n    /// Return the full parser state as a `State` record\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static readonly K<MP, State<S, char, E>> getParserState = \n        MP.Ask;\n\n    /// <summary>\n    /// Write the full parser state\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static K<MP, Unit> putParserState(State<S, char, E> s) => \n        MP.Put(s);\n\n    /// <summary>\n    /// Return the full parser state and then map it to a new value using the supplied function\n    /// </summary>\n    /// <returns>Parser</returns>\n    public static K<MP, A> mapParserState<A>(Func<State<S, char, E>, A> f) => \n        MP.Asks(f);\n\n    /// <summary>\n    /// Update the parser state using the supplied function\n    /// </summary>\n    /// <param name=\"f\">Update function</param>\n    /// <returns>Parser</returns>\n    public static K<MP, Unit> modifyParserState(Func<State<S, char, E>, State<S, char, E>> f) =>\n        MP.Modify(f);\n\n    /// <summary>\n    /// An escape hatch for defining custom 'MonadParsec' primitives\n    /// </summary>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <param name=\"f\">Parsing function to lift</param>\n    /// <returns>Parser</returns>\n    public static K<MP, A> lift<A>(Func<State<S, char, E>, Reply<E, S, char, A>> f) =>\n        MP.Lift(f);    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/MonadParsecT/MonadParsecT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Parser combinator monad transformer trait \n/// </summary>\n/// <remarks>\n/// Type class describing monads that implement the full set of primitive parsers.\n/// </remarks>\n/// <remarks>\n/// **Note** that the following primitives are “fast” and should be taken\n/// advantage of as much as possible if your aim is a fast parser: `tokens`,\n/// `takeWhileP`, `takeWhile1P`, and `takeP`\n/// </remarks>\n/// <typeparam name=\"MP\">This type</typeparam>\n/// <typeparam name=\"E\">Error type</typeparam>\n/// <typeparam name=\"S\">Token-stream type</typeparam>\n/// <typeparam name=\"T\">Token type</typeparam>\n/// <typeparam name=\"M\">Lifted monad</typeparam>\npublic interface MonadParsecT<MP, E, S, T, out M> : \n    MonadT<MP, M>,\n    Alternative<MP>, \n    Identifiable<MP, string>,\n    Fallible<ParseError<T, E>, MP>,\n    Readable<MP, State<S, T, E>>, \n    Stateful<MP, State<S, T, E>> \n    where MP : MonadParsecT<MP, E, S, T, M>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    /// <summary>\n    /// Stop parsing and report the `ParseError`. This is the only way to\n    /// control the position of the error without manipulating the parser state\n    /// manually.\n    /// </summary>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <param name=\"error\">Error</param>\n    /// <returns></returns>\n    public static abstract K<MP, A> Error<A>(ParseError<T, E> error);\n\n    /// <summary>\n    /// The parser `label(name, p)` behaves as parser `p`, but whenever the\n    /// parser `p` fails /without consuming any input/, it replaces names of\n    /// “expected” tokens with the name `name`.\n    /// </summary>\n    /// <param name=\"name\">Label name</param>\n    /// <param name=\"p\">Parser to label</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Parser</returns>\n    public static abstract K<MP, A> Label<A>(string name, K<MP, A> p);\n\n    /// <summary>\n    /// `hidden(p)` behaves just like parser `p`, but it doesn't show any\n    /// “expected” tokens in the error-message when `p` fails.\n    /// </summary>\n    /// <param name=\"p\">Parser to hide</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Parser</returns>\n    public static virtual K<MP, A> Hidden<A>(K<MP, A> p) =>\n        MP.Label(\"\", p);\n\n    /// <summary>\n    /// The parser `@try(p)` behaves like the parser `p`, except that it\n    /// backtracks the parser state when `p` fails (either consuming input or\n    /// not).\n    /// </summary>\n    /// <remarks>\n    /// This combinator is used whenever arbitrary look-ahead is needed. Since\n    /// it pretends that it hasn't consumed any input when `p` fails, the\n    /// (`|`) combinator will try its second alternative even if the first\n    /// parser failed while consuming input.\n    /// </remarks>\n    /// <example>\n    /// For example, here is a parser that is supposed to parse the word “let”\n    /// or the word “lexical”:\n    ///\n    ///     parseTest((string(\"let\") | string(\"lexical\")), \"lexical\")\n    /// \n    ///     unexpected \"lex\"\n    ///     expecting \"let\"\n    ///\n    /// What happens here? The first parser consumes “le” and fails (because it\n    /// doesn't see a “t”). The second parser, however, isn't tried, since the\n    /// first parser has already consumed some input! `Try` fixes this behavior\n    /// and allows backtracking to work:\n    ///\n    ///     parseTest((@try (string(\"let\")) | string(\"lexical\")), \"lexical\")\n    ///     \"lexical\"\n    ///\n    /// `Try` also improves error messages in case of overlapping alternatives,\n    /// because Megaparsec's hint system can be used:\n    ///\n    ///     parseTest((@try (string(\"let\")) | string(\"lexical\")), \"le\")\n    /// \n    ///     unexpected \"le\"\n    ///     expecting \"let\" or \"lexical\"\n    /// </example>\n    /// <remarks>\n    /// **Note** that the combinator: `string` backtracks automatically (see `tokens`), so it\n    /// does not need `@try`. However, the examples above demonstrate the idea behind `@try` so well\n    /// that it was decided to keep them. You still need to use `@try` when your\n    /// alternatives are complex, composite parsers.\n    /// </remarks>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Parser</returns>\n    public static abstract K<MP, A> Try<A>(K<MP, A> p);\n\n    /// <summary>\n    /// If `p` in `lookAhead(p)` succeeds (either by consuming input or not),\n    /// the whole parser behaves like `p` succeeded without consuming anything\n    /// (parser state is also not updated). If `p` fails, `lookAhead` has no\n    ///  effect, i.e. it will fail consuming input if `p` fails consuming input.\n    ///  Combine with `try` if this is undesirable\n    /// </summary>\n    /// <param name=\"p\">Parser to look ahead with</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Parser</returns>\n    public static abstract K<MP, A> LookAhead<A>(K<MP, A> p);\n\n    /// <summary>\n    /// `notFollowedBy(p)` only succeeds when the parser `p` fails. This parser\n    /// /never consumes/ any input and /never modifies/ parser state. It can be\n    /// used to implement the “longest match” rule.\n    /// </summary>\n    /// <param name=\"p\">Parser to test</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Unit parser</returns>\n    public static abstract K<MP, Unit> NotFollowedBy<A>(K<MP, A> p);\n\n    /// <summary>\n    /// `withRecovery(f, p)` allows us to continue parsing even if the parser\n    /// `p` fails. In this case `f` is called with the `ParseError` as its\n    /// argument. Typical usage is to return a value signifying failure to\n    /// parse this particular object and to consume some part of the input up\n    /// to the point where the next object starts.\n    /// \n    /// Note that if `f` fails, the original error message is reported as if\n    /// without `withRecovery`. In no way can the recovering parser `f` influence\n    /// error messages.\n    /// </summary>\n    /// <param name=\"onError\">Delegate to invoke on error</param>\n    /// <param name=\"p\">Parser to run</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Parser</returns>\n    public static abstract K<MP, A> WithRecovery<A>(Func<ParseError<T, E>, K<MP, A>> onError, K<MP, A> p);\n\n    /// <summary>\n    /// This parser only succeeds at the end of input\n    /// </summary>\n    public static abstract K<MP, Unit> EOF { get; }\n\n    /// <summary>\n    /// `observing(p)` allows us to “observe” failure of the `p` parser,\n    /// should it happen, without actually ending parsing but instead getting\n    /// the `ParseError` in `Left`. On success, the parsed value is returned in\n    /// `Right` as usual. Note, this primitive just allows you to observe\n    /// parse errors as they happen, it does not backtrack or change how the\n    /// `p` parser works in any way.\n    /// </summary>\n    /// <param name=\"p\">Parser</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Parser</returns>\n    public static abstract K<MP, Either<ParseError<T,E>, A>> Observing<A>(K<MP, A> p);\n    \n    /// <summary>\n    /// The parser `token(test, expected)` accepts tokens for which the\n    /// matching function `test` returns `Some` result. If `None` is\n    /// returned, the `expected` set is used to report the items that were\n    /// expected.\n    /// </summary>\n    /// <param name=\"test\">Token predicate test function</param>\n    /// <param name=\"expected\">Expected items</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Token parser</returns>\n    public static abstract K<MP, A> Token<A>(Func<T, Option<A>> test, in Set<ErrorItem<T>> expected);\n\n    /// <summary>\n    /// The parser `tokens(test, chunk)` parses a chunk of input and returns it.\n    /// The supplied predicate `test` is used to check equality of given and parsed\n    /// chunks after a candidate chunk of correct length is fetched from the stream.\n    /// \n    /// This can be used, for example, to write 'chunk':\n    /// \n    ///     chunk = tokens (==)\n    /// \n    /// Note that this is an auto-backtracking primitive, which means that if it\n    /// fails, it never consumes any input. This is done to make its consumption\n    /// model match how error messages for this primitive are reported (which\n    /// becomes an important thing as user gets more control with primitives like\n    /// 'withRecovery'):\n    /// \n    ///     parseTest((string(\"abc\")), \"abd\")\n    /// \n    ///     unexpected \"abd\"\n    ///     expecting \"abc\"\n    /// \n    /// This means that it's not necessary to use `@try` with `tokens`-based parsers,\n    /// such as `string` and. \n    /// </summary>\n    /// <param name=\"test\">Predicate test function. The first argument is the chunk to\n    /// test, the second argument is the reference chunk.</param>\n    /// <param name=\"chunk\">Reference chunk</param>\n    /// <returns>Parsed chunk</returns>\n    public static abstract K<MP, S> Tokens(Func<S, S, bool> test, in S chunk);\n    \n    /// <summary>\n    /// The parser `oneOf(test, expected)` accepts a set of tokens to match.\n    /// </summary>\n    /// <param name=\"tokens\">Tokens to test</param>\n    /// <returns>Parsed stream of tokens</returns>\n    public static abstract K<MP, T> OneOf<EqT>(S tokens) \n        where EqT : Eq<T>;\n    \n    /// <summary>\n    /// The parser `noneOf(test, expected)` accepts a set of tokens to not match.\n    /// </summary>\n    /// <param name=\"tokens\">Tokens to test</param>\n    /// <returns>Parsed stream of tokens</returns>\n    public static abstract K<MP, T> NoneOf<EqT>(S tokens)\n        where EqT : Eq<T>;\n\n    /// <summary>\n    /// Parse zero or more tokens for which the supplied predicate holds.\n    /// Try to use this as much as possible because, for many streams, this\n    /// combinator is much faster than parsers built with `many` and `satisfy`.\n    /// \n    ///     takeWhile((Some \"foo\"), f) = many (satisfy(f) | \"foo\")\n    ///     takeWhile(None,         f) = many (satisfy(f))\n    /// \n    /// The combinator never fails, although it may parse the empty chunk.\n    /// </summary>\n    /// <param name=\"test\">Predicate to use to test tokens</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static abstract K<MP, S> TakeWhile(Func<T, bool> test, in Option<string> name = default);\n\n    /// <summary>\n    /// Parse one or more tokens for which the supplied predicate holds.\n    /// Try to use this as much as possible because, for many streams, this\n    /// combinator is much faster than parsers built with `many` and `satisfy`.\n    /// \n    ///     takeWhile((Some \"foo\"), f) = many (satisfy(f) | \"foo\")\n    ///     takeWhile(None,         f) = many (satisfy(f))\n    /// \n    /// The combinator never fails, although it may parse the empty chunk.\n    /// </summary>\n    /// <param name=\"test\">Predicate to use to test tokens</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static abstract K<MP, S> TakeWhile1(Func<T, bool> test, in Option<string> name = default);\n\n    /// <summary>\n    /// Extract the specified number of tokens from the input stream and\n    /// return them packed as a chunk of stream. If there are not enough tokens\n    /// in the stream, a parse error will be signalled. It's guaranteed that if\n    /// the parser succeeds, the requested number of tokens will be returned.\n    /// \n    /// The parser is roughly equivalent to:\n    /// \n    ///     take((Just \"foo\"), n) = count(n, (anySingle | \"foo\"))\n    ///     take(Nothing,      n) = count(n, anySingle)\n    /// \n    /// Note that if the combinator fails due to an insufficient number of tokens\n    /// in the input stream, it backtracks automatically. No `@try` is necessary\n    /// with `take`.\n    /// </summary>\n    /// <param name=\"n\">How many tokens to extract</param>\n    /// <param name=\"name\">Name for a single token in the row</param>\n    /// <returns>A chunk of matching tokens</returns>\n    public static abstract K<MP, S> Take(int n, in Option<string> name = default);\n\n    /// <summary>\n    /// An escape hatch for defining custom 'MonadParsec' primitives\n    /// </summary>\n    /// <param name=\"f\">Parsing function to lift</param>\n    /// <typeparam name=\"A\">Parser value type</typeparam>\n    /// <returns>Parser</returns>\n    public static abstract K<MP, A> Lift<A>(Func<State<S, T, E>, Reply<E, S, T, A>> f);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Operator.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// This data type specifies operators that work on values of type `A`. An operator\n/// is either binary infix or unary prefix or postfix. A binary operator has also\n/// an associated associativity.\n/// </summary>\n/// <typeparam name=\"M\">Monad trait type</typeparam>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic abstract record Operator<M, A>\n{\n    /// <summary>\n    /// Non-associative infix operator\n    /// </summary>\n    /// <param name=\"Operation\">Lifted binary operation</param>\n    public record InfixN(K<M, Func<A, A, A>> Operation) : Operator<M, A>;\n\n    /// <summary>\n    /// Left-associative infix operator\n    /// </summary>\n    /// <param name=\"Operation\">Lifted binary operation</param>\n    public record InfixL(K<M, Func<A, A, A>> Operation) : Operator<M, A>;\n\n    /// <summary>\n    /// Right-associative infix operator\n    /// </summary>\n    /// <param name=\"Operation\">Lifted binary operation</param>\n    public record InfixR(K<M, Func<A, A, A>> Operation) : Operator<M, A>;\n\n    /// <summary>\n    /// Prefix operator\n    /// </summary>\n    /// <param name=\"Operation\">Lifted unary operation</param>\n    public record Prefix(K<M, Func<A, A>> Operation) : Operator<M, A>;\n\n    /// <summary>\n    /// Prefix operator\n    /// </summary>\n    /// <param name=\"Operation\">Lifted unary operation</param>\n    public record Postfix(K<M, Func<A, A>> Operation) : Operator<M, A>;\n\n    /// <summary>\n    /// Right-associative ternary. \n    /// </summary>\n    /// <remarks>\n    /// Right-associative means that...\n    /// \n    ///     a\n    ///       ? b\n    ///       : d\n    ///             ? e\n    ///             : f\n    ///\n    /// ... is parsed as...\n    ///\n    /// \n    ///     a\n    ///       ? b\n    ///       : (d\n    ///             ? e\n    ///             : f)\n    ///\n    /// ... and not as...\n    /// \n    ///     (a\n    ///       ? b\n    ///       : d)\n    ///             ? e\n    ///             : f\n    ///\n    /// </remarks>\n    /// <remarks>\n    /// The outer monadic action parses the first separator (e.g. `?`) and\n    /// returns an action (of type: `m (a -> a -> a -> a)`) that parses the\n    /// second separator (e.g. `:`).\n    /// </remarks>\n    /// <param name=\"Operation\"></param>\n    public record TernR(K<M, K<M, Func<A, A, A, A>>> Operation) : Operator<M, A>;\n\n}\n\n"
  },
  {
    "path": "LanguageExt.Megaparsec/PString.cs",
    "content": "using System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Type that wraps up a string and its start and length.  This allows us to implement\n/// the low-level streaming trait and get a high-performance parser.\n/// </summary>\n/// <param name=\"value\">Text</param>\n/// <param name=\"start\">Start of text</param>\n/// <param name=\"length\">Length of text</param>\n[CollectionBuilder(typeof(PString), nameof(PString.From))]\npublic readonly struct PString(string value, int start, int length) :\n    TokenStream<PString, char>,\n    IEquatable<PString>,\n    IComparable<PString>\n{\n    /// <summary>\n    /// Backing string\n    /// </summary>\n    string Value => value;\n    \n    /// <summary>\n    /// Start position in the backing string\n    /// </summary>\n    int Start => start;\n    \n    /// <summary>\n    /// Number of characters in the backing string\n    /// </summary>\n    int Length => length;\n    \n    /// <summary>\n    /// Empty parser string\n    /// </summary>\n    public static readonly PString Empty = \n        new(\"\", 0, 0);\n\n    public PString(string Value) : this(Value, 0, Value.Length)\n    {\n    }\n    \n    public static PString From(string value) =>\n        new (value);\n\n    public char this[int ix] =>\n        ix < 0 || ix >= Length \n            ? throw new IndexOutOfRangeException() \n            : Value[Start + ix];\n\n    public char this[Index ix] =>\n        ix.Value < 0 || ix.Value >= Length\n            ? throw new IndexOutOfRangeException()\n            : ix.IsFromEnd\n                ? Value[Start + Length - ix.Value]\n                : Value[Start          + ix.Value];\n    \n    public PString Splice(int offset, int amount)\n    {\n        if (amount < 0) return Empty;\n        return amount - offset < Length\n            ? new PString(Value, Start + offset, amount)\n            : this;\n    }    \n    \n    public PString Splice(int amount)\n    {\n        if (amount < 0) return Empty;\n        return amount < Length\n            ? new PString(Value, Start, amount)\n            : this;\n    }\n\n    public override string ToString() => \n        new (Value.AsSpan(Start, Length));\n\n    public PStringEnum GetEnumerator() =>\n        new (this);\n\n    static bool TokenStream<PString, char>.IsTab(char token) =>\n        token == '\\t';\n\n    static bool TokenStream<PString, char>.IsNewline(char token) => \n        token == '\\n';\n\n    static ReadOnlySpan<char> TokenStream<PString, char>.TokenToString(char token) => \n        new ([token]);\n\n    static PString TokenStream<PString, char>.TokenToChunk(in char token) => \n        new (token.ToString(), 0, 1);\n\n    static PString TokenStream<PString, char>.TokensToChunk(in ReadOnlySpan<char> token) => \n        new (new string(token), 0, token.Length);\n\n    static ReadOnlySpan<char> TokenStream<PString, char>.ChunkToTokens(in PString tokens) => \n        tokens.Value.AsSpan(tokens.Start, tokens.Length);\n\n    static int TokenStream<PString, char>.ChunkLength(in PString tokens) => \n        tokens.Length;\n\n    static bool TokenStream<PString, char>.Take1(in PString stream, out char head, out PString tail)\n    {\n        if (stream.Length > 0)\n        {\n            var start = stream.Start;\n            var value = stream.Value;\n            head = value[start];\n            tail = new PString(value, start + 1, stream.Length - 1);\n            return true;\n        }\n        else\n        {\n            head = '?';\n            tail = stream;\n            return false;\n        }\n    }\n\n    static bool TokenStream<PString, char>.Take(int amount, in PString stream, out PString head, out PString tail)\n    {\n        // If the requested length `amount` is 0 (or less), `false` should\n        // not be returned, instead `true` and `(out Empty, out stream)` should be returned.\n        if (amount <= 0)\n        {\n            head = Empty;\n            tail = stream;\n            return true;\n        }\n\n        // If the requested length is greater than 0 and the stream is\n        // empty, `false` should be returned indicating end-of-input.\n        if (stream.Length <= 0)\n        {\n            head = Empty;\n            tail = stream;\n            return false;\n        }\n        \n        // In other cases, take chunk of length `amount` (or shorter if the\n        // stream is not long enough) from the input stream and return the\n        // chunk along with the rest of the stream.\n        amount = Math.Min(amount, stream.Length);\n        var start = stream.Start;\n        var value = stream.Value;\n        head = new PString(value, start, amount);\n        tail = new PString(value, start + amount, stream.Length - amount);\n        return true;\n    }\n\n    static void TokenStream<PString, char>.TakeWhile(\n        Func<char, bool> predicate, \n        in PString stream,\n        out PString head,\n        out PString tail)\n    {\n        var value  = stream.Value;\n        var start  = stream.Start;\n        var end    = start;\n        var length = stream.Length;\n        var count  = 0;\n\n        while (count < length && !predicate(value[end]))\n        {\n            end++;\n            count++;\n        }\n        head = new PString(value, start, count);\n        tail = new PString(value, end, length - count);\n    }\n\n    public bool Equals(PString other)\n    {\n        if(Length != other.Length) return false;\n        var spanA = Value.AsSpan(Start, Length);\n        var spanB = other.Value.AsSpan(other.Start, other.Length);\n        return spanA.Equals(spanB, StringComparison.Ordinal);\n    }\n    \n    public int CompareTo(PString other)\n    {\n        var spanA = Value.AsSpan(Start, Length);\n        var spanB = other.Value.AsSpan(other.Start, other.Length);\n        return spanA.CompareTo(spanB, StringComparison.Ordinal);\n    }\n    \n    public struct PStringEnum\n    {\n        readonly int start;\n        readonly string target;\n        readonly int end;\n        int current;\n\n        internal PStringEnum(PString ps)\n        {\n            target = ps.Value;\n            start = current = ps.Start - 1;\n            end = ps.Start + ps.Length;\n        }\n        \n        public bool MoveNext()\n        {\n            current++;\n            return current >= end; \n        }\n\n        public void Reset() =>\n            current = start;\n\n        public char Current => \n            target[current];\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParseError/ParseError.Module.cs",
    "content": "using static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static class ParseError\n{\n    public static ParseError<T, E> Trivial<T, E>(\n        int offset, \n        Option<ErrorItem<T>> unexpected, \n        Set<ErrorItem<T>> expected) =>\n        new ParseError<T, E>.Trivial(offset, unexpected, expected);\n    \n    public static ParseError<T, E> Trivial<T, E>(\n        int offset, \n        Option<ErrorItem<T>> unexpected, \n        ErrorItem<T> expected) =>\n        new ParseError<T, E>.Trivial(offset, unexpected, Set.singleton(expected));\n\n    public static ParseError<T, E> Trivial<T, E>(\n        int offset,\n        Option<ErrorItem<T>> unexpected,\n        Option<ErrorItem<T>> expected) =>\n        new ParseError<T, E>.Trivial(offset, unexpected,\n                                     expected.IsSome ? Set.singleton((ErrorItem<T>)expected) : default);\n\n    public static ParseError<T, E> Trivial<T, E>(\n        int offset, \n        Option<ErrorItem<T>> unexpected) =>\n        new ParseError<T, E>.Trivial(offset, unexpected, default);\n    \n    public static ParseError<T, E> Fancy<T, E>(int offset, Set<ErrorFancy<E>> errors) => \n        new ParseError<T, E>.Fancy(offset, errors);\n    \n    public static ParseError<T, E> Fancy<T, E>(int offset, ErrorFancy<E> errors) => \n        new ParseError<T, E>.Fancy(offset, Set.singleton(errors));\n\n    public static ParseError<T, E> mergeError<T, E>(ParseError<T, E> e1, ParseError<T, E> e2)\n    {\n        return (e1.Offset.CompareTo(e2.Offset)) switch\n               {\n                   < 0 => e2,\n                   0 => (e1, e2) switch\n                        {\n                            (ParseError<T, E>.Trivial (var s1, var u1, var p1), ParseError<T, E>.Trivial (_, var u2, var p2)) =>\n                                Trivial<T, E>(s1, n(u1, u2), p1 + p2),\n                            \n                            (ParseError<T, E>.Fancy, ParseError<T, E>.Trivial) =>\n                                e1,\n                            \n                            (ParseError<T, E>.Trivial, ParseError<T, E>.Fancy) =>\n                                e2,\n                            \n                            (ParseError<T, E>.Fancy (var s1, var x1), ParseError<T, E>.Fancy(_, var x2) ) =>\n                                Fancy<T, E>(s1, x1 + x2),\n                            \n                            _ => e1\n                        },\n                   > 0 => e1\n               };\n        \n        // NOTE The logic behind this merging is that since we only combine\n        // parse errors that happen at exactly the same position, all the\n        // unexpected items will be prefixes of input stream at that position or\n        // labels referring to the same thing. Our aim here is to choose the\n        // longest prefix (merging with labels and end of input is somewhat\n        // arbitrary, but is necessary because otherwise we can't make\n        // ParseError lawful Monoid and have nice parse errors at the same\n        // time).\n        static Option<ErrorItem<T>> n(Option<ErrorItem<T>> mx, Option<ErrorItem<T>> my) =>\n            (mx, my) switch\n            {\n                ({ IsNone: true }, { IsNone: true }) => None,\n                ({ IsSome: true }, { IsNone: true }) => mx,\n                ({ IsNone: true }, { IsSome: true }) => my,\n                (_, _)                               => Some((ErrorItem<T>)mx > (ErrorItem<T>)my \n                                                                 ? (ErrorItem<T>)mx \n                                                                 : (ErrorItem<T>)my)\n            };\n    }\n\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParseError/ParseError.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// `ParseError` represents a parse error parametrised over the\n/// stream type `S` and the custom data `E`.\n/// \n/// `Semigroup` and `Monoid` instances of the data type allow us to merge\n/// parse errors from different branches of parsing. When merging two\n/// 'ParseError's, the longest match is preferred; if positions are the same,\n/// custom data sets and collections of message items are combined. Note that\n/// fancy errors take precedence over trivial errors in merging.\n/// </summary>\n/// <typeparam name=\"T\">Token type</typeparam> \n/// <typeparam name=\"E\">Error type</typeparam> \npublic abstract record ParseError<T, E>(int Offset) : Semigroup<ParseError<T, E>>\n{\n    /// <summary>\n    /// Trivial errors, generated by the Megaparsec's machinery. The data\n    /// constructor includes the offset of error, unexpected token (if any),\n    /// and expected tokens.\n    /// </summary>\n    public record Trivial(int Offset, Option<ErrorItem<T>> Unexpected, Set<ErrorItem<T>> Expected)\n        : ParseError<T, E>(Offset)\n    {\n        public override Func<State<S, T, E>, K<M, B>> WithHints<S, M, B>(\n            Hints<T> hs, \n            Func<ParseError<T, E>, State<S, T, E>, K<M, B>> f) => \n            curry(f)(ParseError.Trivial<T, E>(Offset, Unexpected, Expected + hs.Errors));\n    }\n\n    /// <summary>\n    /// Fancy, custom errors.\n    /// </summary>\n    public record Fancy(int Offset, Set<ErrorFancy<E>> Errors)\n        : ParseError<T, E>(Offset)\n    {\n        public override Func<State<S, T, E>, K<M, B>> WithHints<S, M, B>(\n            Hints<T> hs, \n            Func<ParseError<T, E>, State<S, T, E>, K<M, B>> f) => \n            curry(f)(this);\n    }\n\n    public abstract Func<State<S, T, E>, K<M, B>> WithHints<S, M, B>(\n        Hints<T> hs, \n        Func<ParseError<T, E>, State<S, T, E>, K<M, B>> f);\n\n    public ParseError<T, E> Combine(ParseError<T, E> rhs) => \n        ParseError.mergeError(this, rhs);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Apply.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTApply<E, S, T, M, A, B>(ParsecT<E, S, T, M, Func<A, B>> FF, ParsecT<E, S, T, M, A> FA) : \n    ParsecT<E, S, T, M, B>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, C> Run<C>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, B, C> cok,\n        ConsumedErr<E, S, T, M, C> cerr,\n        EmptyOK<E, S, T, M, B, C> eok,\n        EmptyErr<E, S, T, M, C> eerr)\n    {\n        return FF.Run(s, mcok, cerr, meok, eerr);\n        \n        K<M, C> mcok(Func<A, B> f, State<S, T, E> s1, Hints<T> hs) =>\n            FA.Run(s1,\n                   (x2, s2, hs2) => cok(f(x2), s2, hs2),\n                   cerr,\n                   (x2, s2, hs2) => cok(f(x2), s2, hs + hs2),\n                   (e, s2) => e.WithHints<S, M, C>(hs, (ex, sx) => cerr(ex, sx))(s2));\n\n        K<M, C> meok(Func<A, B> f, State<S, T, E> s1, Hints<T> hs) =>\n            FA.Run(s1,\n                   (x2, s2, hs2) => cok(f(x2), s2, hs2),\n                   cerr,\n                   (x2, s2, hs2) => eok(f(x2), s2, hs + hs2),\n                   (e, s2) => e.WithHints<S, M, C>(hs, (ex, sx) => eerr(ex, sx))(s2));\n        \n    }\n}\n\nrecord ParsecTApplyLazy<E, S, T, M, A, B>(ParsecT<E, S, T, M, Func<A, B>> FF, Memo<ParsecT<E, S, T, M>, A> FA) : \n    ParsecT<E, S, T, M, B>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, C> Run<C>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, B, C> cok,\n        ConsumedErr<E, S, T, M, C> cerr,\n        EmptyOK<E, S, T, M, B, C> eok,\n        EmptyErr<E, S, T, M, C> eerr)\n    {\n        return FF.Run(s, mcok, cerr, meok, eerr);\n\n        K<M, C> mcok(Func<A, B> f, State<S, T, E> s1, Hints<T> hs) =>\n            FA.Value.As().Run(s1,\n                              (x2, s2, hs2) => cok(f(x2), s2, hs2),\n                              cerr,\n                              (x2, s2, hs2) => cok(f(x2), s2, hs + hs2),\n                              (e, s2) => e.WithHints<S, M, C>(hs, (ex, sx) => cerr(ex, sx))(s2));\n\n        K<M, C> meok(Func<A, B> f, State<S, T, E> s1, Hints<T> hs) =>\n            FA.Value.As().Run(s1,\n                              (x2, s2, hs2) => cok(f(x2), s2, hs2),\n                              cerr,\n                              (x2, s2, hs2) => eok(f(x2), s2, hs + hs2),\n                              (e, s2) => e.WithHints<S, M, C>(hs, (ex, sx) => eerr(ex, sx))(s2));\n        \n    }\n        \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Bind.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTBind<E, S, T, M, A, B>(ParsecT<E, S, T, M, A> FA, Func<A, K<ParsecT<E, S, T, M>, B>> F) : \n    ParsecT<E, S, T, M, B>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, C> Run<C>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, B, C> cok,\n        ConsumedErr<E, S, T, M, C> cerr,\n        EmptyOK<E, S, T, M, B, C> eok,\n        EmptyErr<E, S, T, M, C> eerr)\n    {\n        return FA.Run(s, mcok, cerr, meok, eerr);\n\n        K<M, C> mcok(A x, State<S, T, E> s1, Hints<T> hs) =>\n            F(x).As().Run(s1,\n                          cok,\n                          cerr,\n                          (x2, s2, hs2) => cok(x2, s2, hs + hs2),\n                          (e, s2) => e.WithHints<S, M, C>(hs, (ex, sx) => cerr(ex, sx))(s2));\n\n        K<M, C> meok(A x, State<S, T, E> s1, Hints<T> hs) =>\n            F(x).As().Run(s1,\n                          cok,\n                          cerr,\n                          (x2, s2, hs2) => eok(x2, s2, hs + hs2),\n                          (e, s2) => e.WithHints<S, M, C>(hs, (ex, sx) => eerr(ex, sx))(s2));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Catch.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTCatch<E, S, T, M, A>(\n    ParsecT<E, S, T, M, A> fa,\n    Func<ParseError<T, E>, bool> predicate, \n    Func<ParseError<T, E>, K<ParsecT<E, S, T, M>, A>> fail) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        return fa.Run(s, cok, cerr, eok, @catch);\n\n        K<M, B> @catch(ParseError<T, E> err, State<S, T, E> ms) =>\n            predicate(err)\n                ? fail(err).As().Run(ms, cok, cerr, eok, eerr)\n                : eerr(err, ms);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Choose.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTChoose<E, S, T, M, A>(ParsecT<E, S, T, M, A> m, ParsecT<E, S, T, M, A> n) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        return m.Run(s, cok, cerr, eok, merr);\n\n        K<M, B> merr(ParseError<T, E> err, State<S, T, E> ms)\n        {\n          K<M, B> ncerr(ParseError<T, E> err1, State<S, T, E> s1) =>\n              cerr(err1 + err, longestMatch(ms, s1));\n          \n          K<M, B> neok(A x, State<S, T, E> s1, Hints<T> hs) =>\n              eok(x, s1, Hints.fromOffset(s1.Offset, err) + hs);\n          \n          K<M, B> neerr(ParseError<T, E> err1, State<S, T, E> s1) =>\n              eerr(err1 + err, longestMatch(ms, s1));\n          \n          return n.Run(ms, cok, ncerr, neok, neerr);\n        }\n        \n        State<S, T, E> longestMatch(State<S, T, E> s1, State<S, T, E> s2) =>\n            s1.Offset > s2.Offset ? s1 : s2;\n    }\n}\n\nrecord ParsecTChooseLazy<E, S, T, M, A>(ParsecT<E, S, T, M, A> m, Memo<ParsecT<E, S, T, M>, A> n) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        return m.Run(s, cok, cerr, eok, merr);\n\n        K<M, B> merr(ParseError<T, E> err, State<S, T, E> ms)\n        {\n            K<M, B> ncerr(ParseError<T, E> err1, State<S, T, E> s1) =>\n                cerr(err1 + err, longestMatch(ms, s1));\n          \n            K<M, B> neok(A x, State<S, T, E> s1, Hints<T> hs) =>\n                eok(x, s1, Hints.fromOffset(s1.Offset, err) + hs);\n          \n            K<M, B> neerr(ParseError<T, E> err1, State<S, T, E> s1) =>\n                eerr(err1 + err, longestMatch(ms, s1));\n          \n            return n.Value.As().Run(ms, cok, ncerr, neok, neerr);\n        }\n        \n        State<S, T, E> longestMatch(State<S, T, E> s1, State<S, T, E> s2) =>\n            s1.Offset > s2.Offset ? s1 : s2;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/DSL.cs",
    "content": "using System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nstatic class DSL<E, S, T, M>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public static ParsecT<E, S, T, M, Unit> eof\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => ParsecTEOF<E, S, T, M>.Default;\n    }\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> pure<A>(A value) => \n        new ParsecTPure<E, S, T, M, A>(value);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> empty<A>() => \n        ParsecTEmpty<E, S, T, M, A>.Default;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> error<A>(\n        ParseError<T, E> error) =>\n        new ParsecTError<E, S, T, M, A>(error);\n\n\n    public static ParsecT<E, S, T, M, State<S, T, E>> ask\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        get => ParsecTAsk<E, S, T, M>.Default;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> asks<A>(Func<State<S, T, E>, A> f) =>\n        new ParsecTAsks<E, S, T, M, A>(f);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> local<A>(\n        Func<State<S, T, E>, State<S, T, E>> f, \n        ParsecT<E, S, T, M, A> ma) =>\n        new ParsecTLocal<E, S, T, M, A>(f, ma);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> label<A>(\n        string name, \n        K<ParsecT<E, S, T, M>, A> p) =>\n        new ParsecTLabel<E, S, T, M, A>(name, p.As());\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> @try<A>(\n        K<ParsecT<E, S, T, M>, A> p) =>\n        new ParsecTTry<E, S, T, M, A>(p.As());\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> lookAhead<A>(\n        K<ParsecT<E, S, T, M>, A> p) =>\n        new ParsecTLookAhead<E, S, T, M, A>(p.As());\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, Unit> notFollowedBy<A>(\n        K<ParsecT<E, S, T, M>, A> p) =>\n        new ParsecTNotFollowedBy<E, S, T, M, A>(p.As());\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, S> take(\n        in Option<string> name, \n        int n) =>\n        new ParsecTTake<E, S, T, M>(name, n);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> withRecovery<A>(\n        Func<ParseError<T, E>, K<ParsecT<E, S, T, M>, A>> recovery, \n        K<ParsecT<E, S, T, M>, A> p) =>\n        new ParsecTWithRecovery<E, S, T, M, A>(recovery, p.As());\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, Either<ParseError<T, E>, A>> observing<A>(\n        K<ParsecT<E, S, T, M>, A> p) =>\n        new ParsecTObserving<E, S, T, M, A>(p.As());\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> token<A>(\n        Func<T, Option<A>> test, \n        in Set<ErrorItem<T>> expected) =>\n        new ParsecTToken<E, S, T, M, A>(test, expected);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, S> tokens(\n        Func<S, S, bool> test, \n        in S chunk) =>\n        new ParsecTTokens<E, S, T, M>(test, chunk);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, T> oneOf<EqT>(S tokens) \n        where EqT : Eq<T> =>\n        new ParsecTOneOf<E, S, T, M, EqT>(tokens);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, T> noneOf<EqT>(S tokens) \n        where EqT : Eq<T> =>\n        new ParsecTNoneOf<E, S, T, M, EqT>(tokens);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, S> takeWhile(\n        Func<T, bool> test,\n        in Option<string> name = default) =>\n        new ParsecTTakeWhile<E, S, T, M>(name, test);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, S> takeWhile1(\n        Func<T, bool> test,\n        in Option<string> name = default) =>\n        new ParsecTTakeWhile1<E, S, T, M>(name, test);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, Unit> put(\n        State<S, T, E> s) =>\n        new ParsecTPutState<E, S, T, M>(s);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, Unit> modify(\n        Func<State<S, T, E>, State<S, T, E>> f) =>\n        new ParsecTModifyState<E, S, T, M>(f);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> lift<A>(\n        Func<State<S, T, E>, Reply<E, S, T, A>> f) =>\n        new ParsecTLift<E, S, T, M, A>(f);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> lift<A>(\n        Func<State<S, T, E>, K<M, Reply<E, S, T, A>>> f) =>\n        new ParsecTLift2<E, S, T, M, A>(f);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> liftM<A>(K<M, A> ma) =>\n        new ParsecTMTransLift<E, S, T, M, A>(ma);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> liftIO<A>(IO<A> ma) =>\n        new ParsecTMTransLiftIO<E, S, T, M, A>(ma);\n        \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, B> map<A, B>(\n        ParsecT<E, S, T, M, A> p, \n        Func<A, B> f) =>\n        new ParsecTMap<E, S, T, M, A, B>(p, f);    \n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, B> apply<A, B>(\n        K<ParsecT<E, S, T, M>, Func<A, B>> ff, \n        K<ParsecT<E, S, T, M>, A> fa) =>\n        new ParsecTApply<E, S, T, M, A, B>(ff.As(), fa.As());\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, B> apply<A, B>(\n        K<ParsecT<E, S, T, M>, Func<A, B>> ff, \n        Memo<ParsecT<E, S, T, M>, A> fa) =>\n        new ParsecTApplyLazy<E, S, T, M, A, B>(ff.As(), fa);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, B> bind<A, B>(\n        K<ParsecT<E, S, T, M>, A> ma, \n        Func<A, K<ParsecT<E, S, T, M>, B>> f) =>\n        new ParsecTBind<E, S, T, M, A, B>(ma.As(), f);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> choose<A>(\n        K<ParsecT<E, S, T, M>, A> m, \n        K<ParsecT<E, S, T, M>, A> n) =>\n        new ParsecTChoose<E, S, T, M, A>(m.As(), n.As());\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> choose<A>(\n        K<ParsecT<E, S, T, M>, A> m, \n        Memo<ParsecT<E, S, T, M>, A> n) =>\n        new ParsecTChooseLazy<E, S, T, M, A>(m.As(), n);\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> @catch<A>(\n        K<ParsecT<E, S, T, M>, A> fa,\n        Func<ParseError<T, E>, bool> predicate, \n        Func<ParseError<T, E>, K<ParsecT<E, S, T, M>, A>> fail) =>\n        new ParsecTCatch<E, S, T, M, A>(fa.As(), predicate, fail);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> fail<A>(string message) =>\n        new ParsecTFail1<E, S, T, M, A>(message);\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static ParsecT<E, S, T, M, A> fail<A>(E error) =>\n        new ParsecTFail2<E, S, T, M, A>(error);    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/EOF.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTEOF<E, S, T, M> : \n    ParsecT<E, S, T, M, Unit>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public static readonly ParsecT<E, S, T, M, Unit> Default = new ParsecTEOF<E, S, T, M>();\n    \n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, Unit, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, Unit, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        S.Take1(s.Input, out var x, out _)\n            ? eerr(ParseError.Trivial<T, E>(s.Offset, ErrorItem.Token(x), ErrorItem.EndOfInput<T>()), s)\n            : eok(unit, s, Hints<T>.Empty);\n    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Empty.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTEmpty<E, S, T, M, A> : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public static readonly ParsecT<E, S, T, M, A> Default = new ParsecTEmpty<E, S, T, M, A>();\n    \n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        eerr(ParseError.Trivial<T, E>(s.Offset, None, []), s);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Error.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTError<E, S, T, M, A>(ParseError<T, E> Error) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        eerr(Error, s);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Fail.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTFail1<E, S, T, M, A>(string Message) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        eerr(ParseError.Fancy<T, E>(s.Offset, ErrorFancy.Fail<E>(Message)), s);\n}\n\nrecord ParsecTFail2<E, S, T, M, A>(E Error) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        eerr(ParseError.Fancy<T, E>(s.Offset, ErrorFancy.Custom(Error)), s);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Label.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTLabel<E, S, T, M, A>(string Name, ParsecT<E, S, T, M, A> P) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        return P.Run(s, cok1, cerr, eok1, eerr1);\n\n        // Updated ConsumedOK\n        K<M, B> cok1(A x, State<S, T, E> s1, Hints<T> hs) =>\n            string.IsNullOrEmpty(Name)\n                ? cok(x, s1, hs.Refresh(None))\n                : cok(x, s1, hs);\n\n        // Updated EmptyOK\n        K<M, B> eok1(A x, State<S, T, E> s1, Hints<T> hs) => \n            eok(x, s1, hs.Refresh(ErrorItem.Label<T>(Name)));\n\n        // Updated EmptyErr\n        K<M, B> eerr1(ParseError<T, E> err, State<S, T, E> s1) =>\n            err switch\n            {\n                ParseError<T, E>.Trivial(var pos, var us, _) => \n                    eerr(ParseError.Trivial<T, E>(pos, us, ErrorItem.Label<T>(Name)), s1),\n\n                _ => eerr(err, s1)\n            };        \n    }\n    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Lift.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTLift<E, S, T, M, A>(Func<State<S, T, E>, Reply<E, S, T, A>> F) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        F(s) switch\n        {\n            (var s1, true, var result) =>\n                result switch\n                {\n                    Result<T, E, A>.OK(var hs, var x) => cok(x, s1, hs),\n                    Result<T, E, A>.Error(var e)      => cerr(e, s1),\n                    _                                 => throw new NotSupportedException()\n                },\n            (var s1, false, var result) =>\n                result switch\n                {\n                    Result<T, E, A>.OK(var hs, var x) => eok(x, s1, hs),\n                    Result<T, E, A>.Error(var e)      => eerr(e, s1),\n                    _                                 => throw new NotSupportedException()\n                }\n        };\n}\n\nrecord ParsecTLift2<E, S, T, M, A>(Func<State<S, T, E>, K<M, Reply<E, S, T, A>>> F) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        F(s) >> (f => f switch\n        {\n            (var s1, true, var result) =>\n                result switch\n                {\n                    Result<T, E, A>.OK(var hs, var x) => cok(x, s1, hs),\n                    Result<T, E, A>.Error(var e)      => cerr(e, s1),\n                    _                                 => throw new NotSupportedException()\n                },\n            (var s1, false, var result) =>\n                result switch\n                {\n                    Result<T, E, A>.OK(var hs, var x) => eok(x, s1, hs),\n                    Result<T, E, A>.Error(var e)      => eerr(e, s1),\n                    _                                 => throw new NotSupportedException()\n                }\n        });\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/LookAhead.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTLookAhead<E, S, T, M, A>(ParsecT<E, S, T, M, A> P) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        return P.Run(s, eok1, cerr, eok1, eerr);\n                                       \n        K<M, B> eok1(A x, State<S, T, E> _, Hints<T> __) => \n            eok(x, s, Hints<T>.Empty) ;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/MTransLift.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTMTransLift<E, S, T, M, A>(K<M, A> ma) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        ma >> (a => eok(a, s, Hints<T>.Empty));\n}\n\nrecord ParsecTMTransLiftIO<E, S, T, M, A>(IO<A> ma) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        M.LiftIOMaybe(ma) >> (a => eok(a, s, Hints<T>.Empty));\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Map.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTMap<E, S, T, M, A, B>(ParsecT<E, S, T, M, A> P, Func<A, B> F) : \n    ParsecT<E, S, T, M, B>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, C> Run<C>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, B, C> cok,\n        ConsumedErr<E, S, T, M, C> cerr,\n        EmptyOK<E, S, T, M, B, C> eok,\n        EmptyErr<E, S, T, M, C> eerr) =>\n        P.Run(s, (x, s1, hs) => cok(F(x), s1, hs), cerr, (x, s1, hs) => eok(F(x), s1, hs), eerr);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/NoneOf.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTNoneOf<E, S, T, M, EqT>(S tokens) : ParsecT<E, S, T, M, T>\n    where S : TokenStream<S, T>\n    where M : Monad<M>\n    where EqT : Eq<T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, T, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, T, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        var ts = S.ChunkToTokens(tokens);\n        if (S.Take1(s.Input, out var head, out var tail))\n        {\n            foreach (var t in ts)\n            {\n                if(EqT.Equals(head, t))\n                {\n                    return eerr(unexpect(s.Offset, ErrorItem.Token(head), ts), s);\n                }\n            }\n            return cok(head, s with { Input = tail, Offset = s.Offset + 1 }, Hints<T>.Empty);\n        }\n        else\n        {\n            return eerr(unexpect(s.Offset, ErrorItem.EndOfInput<T>(), ts), s);\n        }\n        \n        ParseError<T, E> unexpect(int pos1, ErrorItem<T> u, ReadOnlySpan<T> tokens) =>\n            ParseError.Trivial<T, E>(pos1, u, ErrorItem.Tokens(tokens));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/NotFollowedBy.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTNotFollowedBy<E, S, T, M, A>(ParsecT<E, S, T, M, A> P) :\n    ParsecT<E, S, T, M, Unit>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, Unit, B> _,\n        ConsumedErr<E, S, T, M, B> __,\n        EmptyOK<E, S, T, M, Unit, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        return P.Run(s, cok1, cerr1, eok1, eerr1);\n\n        // Updated ConsumedOK\n        K<M, B> cok1(A x, State<S, T, E> s1, Hints<T> hs) =>\n            eerr(unexpect(what()), s);\n\n        // Updated EmptyErr\n        K<M, B> cerr1(ParseError<T, E> err, State<S, T, E> s1) =>\n            eok(unit, s, Hints<T>.Empty);\n\n        // Updated EmptyOK\n        K<M, B> eok1(A x, State<S, T, E> s1, Hints<T> hs) =>\n            eerr(unexpect(what()), s);\n\n        // Updated EmptyErr\n        K<M, B> eerr1(ParseError<T, E> err, State<S, T, E> s1) =>\n            eok(unit, s, Hints<T>.Empty);\n\n        ParseError<T, E> unexpect(ErrorItem<T> u) =>\n            ParseError.Trivial<T, E>(s.Offset, u);\n\n        ErrorItem<T> what()\n        {\n            if (TokenStream.take1<S, T>(s.Input, out var t, out var _))\n            {\n                return ErrorItem.Token(t);\n            }\n            else\n            {\n                return ErrorItem.EndOfInput<T>();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Observing.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTObserving<E, S, T, M, A>(ParsecT<E, S, T, M, A> P) : \n    ParsecT<E, S, T, M, Either<ParseError<T, E>, A>>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, Either<ParseError<T, E>, A>, B> cok,\n        ConsumedErr<E, S, T, M, B> _,\n        EmptyOK<E, S, T, M, Either<ParseError<T, E>, A>, B> eok,\n        EmptyErr<E, S, T, M, B> __)\n    {\n        return P.Run(s, cok1, cerr1, eok1, eerr1);\n\n        K<M, B> cok1(A x, State<S, T, E> s1, Hints<T> hs) =>\n            cok(Right(x), s1, hs);\n        \n        K<M, B> eok1(A x, State<S, T, E> s1, Hints<T> hs) =>\n            eok(Right(x), s1, hs);\n        \n        K<M, B> cerr1(ParseError<T, E> err, State<S, T, E> s1) =>\n            cok(Left(err), s1, Hints<T>.Empty);\n        \n        K<M, B> eerr1(ParseError<T, E> err, State<S, T, E> s1) =>\n            eok(Left(err), s1, Hints.fromOffset(s1.Offset, err));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/OneOf.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTOneOf<E, S, T, M, EqT>(S tokens) : ParsecT<E, S, T, M, T>\n    where S : TokenStream<S, T>\n    where M : Monad<M>\n    where EqT : Eq<T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, T, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, T, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        var ts = S.ChunkToTokens(tokens);\n        if (S.Take1(s.Input, out var head, out var tail))\n        {\n            foreach (var t in ts)\n            {\n                if(EqT.Equals(head, t))\n                {\n                    return cok(head, s with { Input = tail, Offset = s.Offset + 1 }, Hints<T>.Empty);\n                }\n            }\n            return eerr(unexpect(s.Offset, ErrorItem.Token(head), ts), s);\n        }\n        else\n        {\n            return eerr(unexpect(s.Offset, ErrorItem.EndOfInput<T>(), ts), s);\n        }\n        \n        ParseError<T, E> unexpect(int pos1, ErrorItem<T> u, ReadOnlySpan<T> tokens) =>\n            ParseError.Trivial<T, E>(pos1, u, ErrorItem.Tokens(tokens));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Pure.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTPure<E, S, T, M, A>(A Value) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, C> Run<C>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, C> cok,\n        ConsumedErr<E, S, T, M, C> cerr,\n        EmptyOK<E, S, T, M, A, C> eok,\n        EmptyErr<E, S, T, M, C> eerr) =>\n        eok(Value, s, Hints<T>.Empty);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Reader.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTAsk<E, S, T, M> :\n    ParsecT<E, S, T, M, State<S, T, E>>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public static readonly ParsecT<E, S, T, M, State<S, T, E>> Default = new ParsecTAsk<E, S, T, M>();\n    \n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, State<S, T, E>, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, State<S, T, E>, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        eok(s, s, Hints<T>.Empty);\n}\n\nrecord ParsecTAsks<E, S, T, M, A>(Func<State<S, T, E>, A> F) :\n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        eok(F(s), s, Hints<T>.Empty);\n}\n\nrecord ParsecTLocal<E, S, T, M, A>(Func<State<S, T, E>, State<S, T, E>> F, ParsecT<E, S, T, M, A> P) :\n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr) =>\n        P.Run(F(s), cok, cerr, eok, eerr);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/State.cs",
    "content": "using LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTPutState<E, S, T, M>(State<S, T, E> State) : \n    ParsecT<E, S, T, M, Unit>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, Unit, B> _,\n        ConsumedErr<E, S, T, M, B> __,\n        EmptyOK<E, S, T, M, Unit, B> eok,\n        EmptyErr<E, S, T, M, B> ___) =>\n        eok(unit, State, Hints<T>.Empty);\n}\n\nrecord ParsecTModifyState<E, S, T, M>(Func<State<S, T, E>, State<S, T, E>> Update) : \n    ParsecT<E, S, T, M, Unit>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, Unit, B> _,\n        ConsumedErr<E, S, T, M, B> __,\n        EmptyOK<E, S, T, M, Unit, B> eok,\n        EmptyErr<E, S, T, M, B> ___) =>\n        eok(unit, Update(s), Hints<T>.Empty);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Take.cs",
    "content": "using LanguageExt.Traits;\nusing LanguageExt.UnsafeValueAccess;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTTake<E, S, T, M>(in Option<string> Name, int Amount) : \n    ParsecT<E, S, T, M, S>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, S, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, S, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        var n = Math.Max(0, Amount);\n        if (S.Take(n, s.Input, out var ts, out var input1))\n        {\n            var len = S.ChunkLength(ts);\n            if (len == n)\n            {\n                // Happy path\n                return cok(ts, s with { Input = input1, Offset = s.Offset + len }, Hints<T>.Empty);\n            }\n            else\n            {\n                // Didn't read the desired number of tokens\n                var el = (ErrorItem.Label<T>) * Name;\n                var ps = el.IsNone ? [] : Set.singleton(el.ValueUnsafe()!);\n                return eerr(ParseError.Trivial<T, E>(s.Offset + len, ErrorItem.EndOfInput<T>(), ps), s);\n            }\n        }\n        else\n        {\n            // End of the input stream\n            var el = (ErrorItem.Label<T>) * Name;\n            var ps = el.IsNone ? [] : Set.singleton(el.ValueUnsafe()!);\n            return eerr(ParseError.Trivial<T, E>(s.Offset, ErrorItem.EndOfInput<T>(), ps), s);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/TakeWhile.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTTakeWhile<E, S, T, M>(in Option<string> Name, Func<T, bool> Test) : \n    ParsecT<E, S, T, M, S>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, S, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, S, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        S.TakeWhile(Test, s.Input, out var ts, out var input1);\n        var len = S.ChunkLength(ts);\n        var hs = Name.IsSome\n                     ? (string)Name switch\n                       {\n                           var n when string.IsNullOrEmpty(n) =>\n                               Hints<T>.Empty,\n\n                           var n => Hints.singleton(ErrorItem.Label<T>(n))\n                       }\n                     : Hints<T>.Empty;\n        \n        return len <= 0\n                   ? eok(ts, s with { Input = input1, Offset = s.Offset + len }, hs)\n                   : cok(ts, s with { Input = input1, Offset = s.Offset + len }, hs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/TakeWhile1.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTTakeWhile1<E, S, T, M>(in Option<string> Name, Func<T, bool> Test) : \n    ParsecT<E, S, T, M, S>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, S, B> cok,\n        ConsumedErr<E, S, T, M, B> __,\n        EmptyOK<E, S, T, M, S, B> ___,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        S.TakeWhile(Test, s.Input, out var ts, out var input1);\n        var len = S.ChunkLength(ts);\n        var el = Name.IsSome\n                     ? Option.Some(ErrorItem.Label<T>((string)Name))\n                     : Option.None;\n        \n        if (len <= 0)\n        {\n            if (S.Take1(s.Input, out var t, out _))\n                return eerr(ParseError.Trivial<T, E>(s.Offset, ErrorItem.Token(t), el), s);\n            else\n                return eerr(ParseError.Trivial<T, E>(s.Offset, ErrorItem.EndOfInput<T>(), el), s);\n        }\n        else\n        {\n            var hs = Name.IsSome\n                         ? Hints.singleton((ErrorItem<T>)el)\n                         : Hints<T>.Empty;\n\n            return cok(ts, s with { Input = input1, Offset = s.Offset + len }, hs);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Token.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTToken<E, S, T, M, A>(Func<T, Option<A>> Test, in Set<ErrorItem<T>> Expected) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        if (S.Take1(s.Input, out var c, out var cs))\n        {\n            switch (Test(c))\n            {\n                case { IsSome: true } o:\n                    var value = (A)o;\n                    return cok(value, s with { Offset = s.Offset + 1, Input = cs }, Hints<T>.Empty);\n                \n                default:\n                    return eerr(ParseError.Trivial<T, E>(s.Offset, ErrorItem.Token(c), Expected), s);\n            }\n        }\n        else\n        {\n            return eerr(ParseError.Trivial<T, E>(s.Offset, ErrorItem.EndOfInput<T>(), Expected), s);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Tokens.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTTokens<E, S, T, M>(Func<S, S, bool> Test, in S Chunk) : \n    ParsecT<E, S, T, M, S>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, S, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, S, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        var len  = S.ChunkLength(Chunk);\n        if (S.Take(len, s.Input, out var tts1, out var input1))\n        {\n            if (Test(Chunk, tts1))\n            {\n                var st = s with { Input = input1, Offset = s.Offset + len };\n                return len <= 0\n                           ? eok(tts1, st, Hints<T>.Empty)\n                           : cok(tts1, st, Hints<T>.Empty);\n            }\n            else\n            {\n                return eerr(unexpect(s.Offset, ErrorItem.Tokens<S, T>(tts1)), s);\n            }\n        }\n        else\n        {\n            return eerr(unexpect(s.Offset, ErrorItem.EndOfInput<T>()), s);\n        }\n        \n        ParseError<T, E> unexpect(int pos1, ErrorItem<T> u) =>\n            ParseError.Trivial<T, E>(pos1, u, ErrorItem.Tokens<S, T>(Chunk));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/Try.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTTry<E, S, T, M, A>(ParsecT<E, S, T, M, A> P) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        return P.Run(s, cok, eerr1, eok, eerr1);\n\n        // Resets the state to before the error\n        K<M, B> eerr1(ParseError<T, E> err, State<S, T, E> _) =>\n            eerr(err, s);        \n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/DSL/WithRecovery.cs",
    "content": "using LanguageExt.Traits;\nnamespace LanguageExt.Megaparsec.DSL;\n\nrecord ParsecTWithRecovery<E, S, T, M, A>(\n    Func<ParseError<T, E>, K<ParsecT<E, S, T, M>, A>> OnError, \n    ParsecT<E, S, T, M, A> P) : \n    ParsecT<E, S, T, M, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    public K<M, B> Run<B>(\n        State<S, T, E> s,\n        ConsumedOK<E, S, T, M, A, B> cok,\n        ConsumedErr<E, S, T, M, B> cerr,\n        EmptyOK<E, S, T, M, A, B> eok,\n        EmptyErr<E, S, T, M, B> eerr)\n    {\n        return P.Run(s, cok, mcerr, eok, meerr);\n        \n        K<M, B> mcerr(ParseError<T, E> err, State<S, T, E> ms)\n        {\n            return OnError(err).As().Run(ms, rcok, rcerr, reok, reerr);\n            K<M, B> rcok(A x, State<S, T, E> s1, Hints<T> _) => cok(x, s1, Hints<T>.Empty);\n            K<M, B> rcerr(ParseError<T, E> _, State<S, T, E> __) => cerr(err, ms);\n            K<M, B> reok(A x, State<S, T, E> s1, Hints<T> _) => eok(x, s1, Hints.fromOffset(s1.Offset, err));\n            K<M, B> reerr(ParseError<T, E> _, State<S, T, E> s1) => cerr(err, ms);\n        } \n        K<M, B> meerr(ParseError<T, E> err, State<S, T, E> ms)\n        {\n            return OnError(err).As().Run(ms, rcok, rcerr, reok, reerr);\n            K<M, B> rcok(A x, State<S, T, E> s1, Hints<T> _) => cok(x, s1, Hints.fromOffset(s1.Offset, err));\n            K<M, B> rcerr(ParseError<T, E> _, State<S, T, E> __) => eerr(err, ms);\n            K<M, B> reok(A x, State<S, T, E> s1, Hints<T> _) => eok(x, s1, Hints.fromOffset(s1.Offset, err));\n            K<M, B> reerr(ParseError<T, E> _, State<S, T, E> s1) => eerr(err, ms);\n        } \n    }\n}\n\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/Extensions/ParsecTExtensions.cs",
    "content": "using LanguageExt.Megaparsec.DSL;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static class ParsecTExtensions\n{\n    extension<E, S, T, M, A>(K<ParsecT<E, S, T, M>, A> self) \n        where S : TokenStream<S, T> \n        where M : Monad<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public ParsecT<E, S, T, M, A> As() =>\n            (ParsecT<E, S, T, M, A>)self;\n\n        /// <summary>\n        /// Run the parser\n        /// </summary>\n        /// <param name=\"initialState\">Starting state</param>\n        /// <returns>Result of the parse</returns>\n        public K<M, Reply<E, S, T, A>> Run(State<S, T, E> initialState)\n        {\n            return self.As().Run(initialState, cok, cerr, eok, eerr);\n        \n            K<M, Reply<E, S, T, A>> cok(A x, State<S, T, E> s1, Hints<T> hs) =>\n                M.Pure(Reply.ConsumedOK(x, s1, hs));\n        \n            K<M, Reply<E, S, T, A>> cerr(ParseError<T, E> e, State<S, T, E> s1) =>\n                M.Pure(Reply.ConsumedError<E, S, T, A>(e, s1));        \n        \n            K<M, Reply<E, S, T, A>> eok(A x, State<S, T, E> s1, Hints<T> hs) =>\n                M.Pure(Reply.EmptyOK(x, s1, hs));\n        \n            K<M, Reply<E, S, T, A>> eerr(ParseError<T, E> e, State<S, T, E> s1) =>\n                M.Pure(Reply.EmptyError<E, S, T, A>(e, s1));        \n        }\n\n        /// <summary>\n        /// Invoke this parser and then feed the lifted reply to the `f` function provided.\n        /// Then rewrap the resulting lifted reply into a new parser. \n        /// </summary>\n        /// <param name=\"f\">Reply mapping function</param>\n        /// <typeparam name=\"B\">New parser result type</typeparam>\n        /// <returns>Parser</returns>\n        public ParsecT<E, S, T, M, B> Hoist<B>(Func<K<M, Reply<E, S, T, A>>, K<M, Reply<E, S, T, B>>> f) =>\n            DSL<E, S, T, M>.lift<B>(s => f(self.Run(s)));        \n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static ParsecT<E, S, T, M, A> operator +(K<ParsecT<E, S, T, M>, A> ma) =>\n            ma.As();\n\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static ParsecT<E, S, T, M, A> operator >>(K<ParsecT<E, S, T, M>, A> lhs, Lower _) =>\n            lhs.As();\n    }\n\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/ParsecT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Parser combinator transformer\n/// </summary>\n/// <typeparam name=\"E\">Error type</typeparam>\n/// <typeparam name=\"S\">Token stream type</typeparam>\n/// <typeparam name=\"T\">Token type</typeparam>\n/// <typeparam name=\"M\">Lifted monad</typeparam>\n/// <typeparam name=\"A\">Parse value type</typeparam>\npublic interface ParsecT<E, S, T, M, A> :\n    K<ParsecT<E, S, T, M>, A>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    /// <summary>\n    /// Run the parser\n    /// </summary>\n    /// <param name=\"initialState\">Starting state</param>\n    /// <param name=\"consumedOK\">Called when a value has successfully parsed</param>\n    /// <param name=\"consumedError\">Called when a value has partially parsed before failure</param>\n    /// <param name=\"emptyOK\">Called when the parsing process was successful but didn't yield a value</param>\n    /// <param name=\"emptyError\">Called when the parsing process was unsuccessful and didn't parse anything at all</param>\n    /// <returns>Result of the parse being passed to one of the provided functions</returns>\n    K<M, B> Run<B>(\n        State<S, T, E> initialState,\n        ConsumedOK<E, S, T, M, A, B> consumedOK,\n        ConsumedErr<E, S, T, M, B> consumedError,\n        EmptyOK<E, S, T, M, A, B> emptyOK,\n        EmptyErr<E, S, T, M, B> emptyError);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/ParsecT/Trait/ParsecT.TraitImpl.cs",
    "content": "using LanguageExt.Megaparsec.DSL;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Megaparsec;\n\npublic class ParsecT<E, S, T, M> : \n    MonoidK<ParsecT<E, S, T, M>>, \n    MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>,\n    MonadIO<ParsecT<E, S, T, M>>\n    where M : Monad<M>\n    where S : TokenStream<S, T>\n{\n    static K<ParsecT<E, S, T, M>, A> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.Error<A>(\n        ParseError<T, E> error) =>\n        DSL<E, S, T, M>.error<A>(error);\n\n    static K<ParsecT<E, S, T, M>, A> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.Label<A>(\n        string name,\n        K<ParsecT<E, S, T, M>, A> p) =>\n        DSL<E, S, T, M>.label(name, p);\n\n    static K<ParsecT<E, S, T, M>, A> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.Try<A>(\n        K<ParsecT<E, S, T, M>, A> p) =>\n        DSL<E, S, T, M>.@try(p);\n\n    static K<ParsecT<E, S, T, M>, A> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.LookAhead<A>(\n        K<ParsecT<E, S, T, M>, A> p) =>\n        DSL<E, S, T, M>.lookAhead(p);\n\n    static K<ParsecT<E, S, T, M>, Unit> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.NotFollowedBy<A>(\n        K<ParsecT<E, S, T, M>, A> p) =>\n        DSL<E, S, T, M>.notFollowedBy(p);\n\n    static K<ParsecT<E, S, T, M>, A> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.WithRecovery<A>(\n        Func<ParseError<T, E>, K<ParsecT<E, S, T, M>, A>> onError, \n        K<ParsecT<E, S, T, M>, A> p) => \n        DSL<E, S, T, M>.withRecovery(onError, p);\n\n    static K<ParsecT<E, S, T, M>, Unit> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.EOF => \n        DSL<E, S, T, M>.eof;\n\n    static K<ParsecT<E, S, T, M>, Either<ParseError<T, E>, A>> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.Observing<A>(\n        K<ParsecT<E, S, T, M>, A> p) => \n        DSL<E, S, T, M>.observing(p);\n\n    static K<ParsecT<E, S, T, M>, A> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.Token<A>(\n        Func<T, Option<A>> test, \n        in Set<ErrorItem<T>> expected) => \n        DSL<E, S, T, M>.token(test, expected);\n\n    static K<ParsecT<E, S, T, M>, S> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.Tokens(\n        Func<S, S, bool> test, \n        in S chunk) => \n        DSL<E, S, T, M>.tokens(test, chunk);\n\n    static K<ParsecT<E, S, T, M>, T> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.OneOf<EqT>(\n        S tokens)  =>\n        DSL<E, S, T, M>.oneOf<EqT>(tokens);\n\n    static K<ParsecT<E, S, T, M>, T> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.NoneOf<EqT>(\n        S tokens) => \n        DSL<E, S, T, M>.noneOf<EqT>(tokens);\n\n    static K<ParsecT<E, S, T, M>, S> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.TakeWhile(\n        Func<T, bool> test,\n        in Option<string> name) => \n        DSL<E, S, T, M>.takeWhile(test, name);\n\n    static K<ParsecT<E, S, T, M>, S> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.TakeWhile1(\n        Func<T, bool> test,\n        in Option<string> name) => \n        DSL<E, S, T, M>.takeWhile1(test, name);\n\n    static K<ParsecT<E, S, T, M>, S> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.Take(\n        int n,\n        in Option<string> name) =>\n        DSL<E, S, T, M>.take(name, n);\n\n    static K<ParsecT<E, S, T, M>, A> MonadParsecT<ParsecT<E, S, T, M>, E, S, T, M>.Lift<A>(\n        Func<State<S, T, E>, Reply<E, S, T, A>> f) =>\n        DSL<E, S, T, M>.lift(f);\n\n    static K<ParsecT<E, S, T, M>, A> Identifiable<ParsecT<E, S, T, M>, string>.Identify<A>(\n        K<ParsecT<E, S, T, M>, A> fa,\n        Label<string> label) =>\n        DSL<E, S, T, M>.label(label.Value, fa);\n\n    static K<ParsecT<E, S, T, M>, B> Functor<ParsecT<E, S, T, M>>.Map<A, B>(\n        Func<A, B> f, \n        K<ParsecT<E, S, T, M>, A> ma) => \n        DSL<E, S, T, M>.map(ma.As(), f);\n\n    static K<ParsecT<E, S, T, M>, A> Applicative<ParsecT<E, S, T, M>>.Pure<A>(A value) => \n        DSL<E, S, T, M>.pure(value);\n\n    static K<ParsecT<E, S, T, M>, B> Applicative<ParsecT<E, S, T, M>>.Apply<A, B>(\n        K<ParsecT<E, S, T, M>, Func<A, B>> mf,\n        K<ParsecT<E, S, T, M>, A> ma) =>\n        DSL<E, S, T, M>.apply(mf.As(), ma.As());\n\n    static K<ParsecT<E, S, T, M>, B> Applicative<ParsecT<E, S, T, M>>.Apply<A, B>(\n        K<ParsecT<E, S, T, M>, Func<A, B>> mf,\n        Memo<ParsecT<E, S, T, M>, A> ma) =>\n        DSL<E, S, T, M>.apply(mf.As(), ma);\n\n    static K<ParsecT<E, S, T, M>, B> Monad<ParsecT<E, S, T, M>>.Bind<A, B>(\n        K<ParsecT<E, S, T, M>, A> ma, \n        Func<A, K<ParsecT<E, S, T, M>, B>> f) => \n        DSL<E, S, T, M>.bind(ma, f);\n\n    static K<ParsecT<E, S, T, M>, B> Monad<ParsecT<E, S, T, M>>.Recur<A, B>(A value, Func<A, K<ParsecT<E, S, T, M>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<ParsecT<E, S, T, M>, A> Choice<ParsecT<E, S, T, M>>.Choose<A>(\n        K<ParsecT<E, S, T, M>, A> fa, \n        K<ParsecT<E, S, T, M>, A> fb) => \n        DSL<E, S, T, M>.choose(fa, fb);\n\n    static K<ParsecT<E, S, T, M>, A> Choice<ParsecT<E, S, T, M>>.Choose<A>(\n        K<ParsecT<E, S, T, M>, A> fa,\n        Memo<ParsecT<E, S, T, M>, A> fb) =>\n        DSL<E, S, T, M>.choose(fa, fb);\n\n    static K<ParsecT<E, S, T, M>, A> SemigroupK<ParsecT<E, S, T, M>>.Combine<A>(\n        K<ParsecT<E, S, T, M>, A> fa,\n        K<ParsecT<E, S, T, M>, A> fb) =>\n        SemigroupInstance<A>.Instance switch\n        {\n            { IsSome: true, Case: SemigroupInstance<A> semi } =>\n                ((A x, A y) => semi.Combine(x, y)) * fa * fb,\n\n            _ => DSL<E, S, T, M>.choose(fa, fb)\n        };\n\n    static K<ParsecT<E, S, T, M>, A> MonoidK<ParsecT<E, S, T, M>>.Empty<A>() =>\n        DSL<E, S, T, M>.empty<A>();\n\n    static K<ParsecT<E, S, T, M>, A> Alternative<ParsecT<E, S, T, M>>.Empty<A>() =>\n        DSL<E, S, T, M>.empty<A>();\n\n    static K<ParsecT<E, S, T, M>, A> Fallible<ParseError<T, E>, ParsecT<E, S, T, M>>.Fail<A>(ParseError<T, E> error) =>\n        DSL<E, S, T, M>.error<A>(error);\n\n    static K<ParsecT<E, S, T, M>, A> Fallible<ParseError<T, E>, ParsecT<E, S, T, M>>.Catch<A>(\n        K<ParsecT<E, S, T, M>, A> fa,\n        Func<ParseError<T, E>, bool> predicate,\n        Func<ParseError<T, E>, K<ParsecT<E, S, T, M>, A>> fail) =>\n        DSL<E, S, T, M>.@catch(fa, predicate, fail);\n\n    static K<ParsecT<E, S, T, M>, A> MonadIO<ParsecT<E, S, T, M>>.LiftIO<A>(IO<A> ma) =>\n        DSL<E, S, T, M>.liftIO(ma);\n\n    static K<ParsecT<E, S, T, M>, A> MonadT<ParsecT<E, S, T, M>, M>.Lift<A>(K<M, A> ma) =>\n        DSL<E, S, T, M>.liftM(ma);\n\n    static K<ParsecT<E, S, T, M>, A> Readable<ParsecT<E, S, T, M>, State<S, T, E>>.Asks<A>(\n        Func<State<S, T, E>, A> f) => \n        DSL<E, S, T, M>.asks(f);\n\n    static K<ParsecT<E, S, T, M>, A> Readable<ParsecT<E, S, T, M>, State<S, T, E>>.Local<A>(\n        Func<State<S, T, E>, State<S, T, E>> f, \n        K<ParsecT<E, S, T, M>, A> ma) => \n        DSL<E, S, T, M>.local(f, ma.As());\n\n    static K<ParsecT<E, S, T, M>, Unit> Stateful<ParsecT<E, S, T, M>, State<S, T, E>>.Put(\n        State<S, T, E> value) => \n        DSL<E, S, T, M>.put(value);\n\n    static K<ParsecT<E, S, T, M>, Unit> Stateful<ParsecT<E, S, T, M>, State<S, T, E>>.Modify(\n        Func<State<S, T, E>, State<S, T, E>> f) => \n        DSL<E, S, T, M>.modify(f);\n    \n    static K<ParsecT<E, S, T, M>, A> Stateful<ParsecT<E, S, T, M>, State<S, T, E>>.Gets<A>(\n        Func<State<S, T, E>, A> f) =>\n        DSL<E, S, T, M>.asks(f);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Pos.cs",
    "content": "using System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Numerics;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// `Pos` is the type for positive integers. This is used to represent line\n/// number, column number, and similar things like indentation level.\n/// \n/// `Semigroup` instance can be  used to safely and efficiently add `Pos` values\n/// together.\n/// </summary>\n/// <param name=\"Value\"></param>\npublic readonly record struct Pos(int Value) : Monoid<Pos>, INumber<Pos>\n{\n    public Pos Combine(Pos rhs) => \n        new (Value + rhs.Value);\n\n    /// <summary>\n    /// Monoid identity: Zero position\n    /// </summary>\n    static Pos Monoid<Pos>.Empty { get; } = \n        new (0);\n\n    /// <summary>\n    /// Zero position\n    /// </summary>\n    public static Pos Zero { get; } = \n        new (0);\n\n    public static Pos One { get; } =\n        new(1);\n    \n    public static int Radix { get; } =\n        10;\n    \n    public static Pos AdditiveIdentity { get; } =\n        new(0);\n\n    public static Pos MultiplicativeIdentity { get; } =\n        new(1);\n\n    /// <summary>\n    /// Implicit conversion from int to Pos\n    /// </summary>\n    public static implicit operator Pos(int value) => \n        new (value);\n\n    public static Pos Abs(Pos value) => \n        new(Math.Abs(value.Value));\n\n    public static bool IsCanonical(Pos value) => \n        true;\n\n    public static bool IsComplexNumber(Pos value) =>\n        false;\n\n    public static bool IsEvenInteger(Pos value) => \n        int.IsEvenInteger(value.Value);\n\n    public static bool IsFinite(Pos value) => \n        true;\n\n    public static bool IsImaginaryNumber(Pos value) => \n        false;\n\n    public static bool IsInfinity(Pos value) => \n        false;\n\n    public static bool IsInteger(Pos value) => \n        true;\n\n    public static bool IsNaN(Pos value) => \n        false;\n\n    public static bool IsNegative(Pos value) => \n        value.Value < 0;\n\n    public static bool IsNegativeInfinity(Pos value) => \n        false;\n\n    public static bool IsNormal(Pos value) =>\n        true;\n\n    public static bool IsOddInteger(Pos value) => \n        (value.Value & 1) == 1;\n\n    public static bool IsPositive(Pos value) => \n        true;\n\n    public static bool IsPositiveInfinity(Pos value) => \n        false;\n\n    public static bool IsRealNumber(Pos value) => \n        false;\n\n    public static bool IsSubnormal(Pos value) => \n        false;\n\n    public static bool IsZero(Pos value) => \n        value.Value == 0;\n\n    public static Pos MaxMagnitude(Pos x, Pos y) =>\n        x.Value > y.Value\n            ? x\n            : y;\n\n    public static Pos MaxMagnitudeNumber(Pos x, Pos y) => \n        x.Value > y.Value\n            ? x\n            : y;\n\n    public static Pos MinMagnitude(Pos x, Pos y) => \n        x.Value < y.Value\n            ? x\n            : y;\n\n    public static Pos MinMagnitudeNumber(Pos x, Pos y) => \n        x.Value < y.Value\n            ? x\n            : y;\n\n    public static Pos Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider) => \n        new (int.Parse(s, style, provider));\n\n    public static Pos Parse(string s, NumberStyles style, IFormatProvider? provider) => \n        new (int.Parse(s, style, provider));\n    \n    public static Pos Parse(string s, IFormatProvider? provider) => \n        new (int.Parse(s, provider));\n\n    public static Pos Parse(ReadOnlySpan<char> s, IFormatProvider? provider) => \n        new (int.Parse(s, provider));\n\n    public static bool TryConvertFromChecked<TOther>(TOther value, out Pos result) where TOther : INumberBase<TOther> =>\n        throw new NotImplementedException();\n\n    public static bool TryConvertFromSaturating<TOther>(TOther value, out Pos result) where TOther : INumberBase<TOther> => \n        throw new NotImplementedException();\n\n    public static bool TryConvertFromTruncating<TOther>(TOther value, out Pos result) where TOther : INumberBase<TOther> => \n        throw new NotImplementedException();\n\n    public static bool TryConvertToChecked<TOther>(Pos value, [MaybeNullWhen(false)] out TOther result) where TOther : INumberBase<TOther> => \n        throw new NotImplementedException();\n\n    public static bool TryConvertToSaturating<TOther>(Pos value, [MaybeNullWhen(false)] out TOther result) where TOther : INumberBase<TOther> => \n        throw new NotImplementedException();\n\n    public static bool TryConvertToTruncating<TOther>(Pos value, [MaybeNullWhen(false)] out TOther result) where TOther : INumberBase<TOther> => \n        throw new NotImplementedException();\n\n    public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out Pos result) \n    {\n        if (int.TryParse(s, style, provider, out var x))\n        {\n            result = new Pos(x);\n            return true;\n        }\n        result = default;\n        return false;\n    }\n\n    public static bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out Pos result) \n    {\n        if (int.TryParse(s, style, provider, out var x))\n        {\n            result = new Pos(x);\n            return true;\n        }\n        result = default;\n        return false;\n    }\n\n    public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, out Pos result)\n    {\n        if (int.TryParse(s, provider, out var x))\n        {\n            result = new Pos(x);\n            return true;\n        }\n        result = default;\n        return false;\n    }\n\n    public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out Pos result)\n    {\n        if (int.TryParse(s, provider, out var x))\n        {\n            result = new Pos(x);\n            return true;\n        }\n        result = default;\n        return false;\n    }\n\n    public int CompareTo(object? obj) =>\n        obj is Pos rhs\n            ? CompareTo(rhs)\n            : 1;\n\n    public int CompareTo(Pos other) => \n        Value.CompareTo(other.Value);\n\n    public string ToString(string? format, IFormatProvider? formatProvider) => \n        $\"Pos({Value})\";\n\n    public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) => \n        throw new NotImplementedException();\n\n    public static Pos operator +(Pos left, Pos right) => \n        new (left.Value + right.Value);\n\n    public static bool operator >(Pos left, Pos right) => \n        left.Value > right.Value;\n\n    public static bool operator >=(Pos left, Pos right) => \n        left.Value >= right.Value;\n\n    public static bool operator <(Pos left, Pos right) => \n        left.Value < right.Value;\n\n    public static bool operator <=(Pos left, Pos right) => \n        left.Value <= right.Value;\n\n    public static Pos operator --(Pos value) =>\n        new(value.Value - 1);\n\n    public static Pos operator /(Pos left, Pos right) => \n        new (left.Value / right.Value);\n\n    public static Pos operator ++(Pos value) => \n        new (value.Value + 1);\n\n    public static Pos operator %(Pos left, Pos right) => \n        new (left.Value % right.Value);\n  \n    public static Pos operator *(Pos left, Pos right) => \n        new (left.Value * right.Value);\n\n    public static Pos operator -(Pos left, Pos right) => \n        new (left.Value - right.Value);\n\n    public static Pos operator -(Pos value) => \n        new (-value.Value);\n\n    public static Pos operator +(Pos value) => \n        new (+value.Value);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/PosState.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\npublic readonly record struct PosState<S>(\n    S Input, \n    int Offset, \n    SourcePos SourcePos, \n    int TabWidth, \n    string LinePrefix);\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Reach.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\ninternal static class Reach<S, T>\n    where S : TokenStream<S, T>\n{\n    // Buffer size for collecting a line of text\n    const int lineBufferSize = 256;\n    const int lineBufferSizeMinus3 = lineBufferSize - 3;\n    \n    /// <summary>\n    /// TODO \n    /// </summary>\n    /// <param name=\"o\">Offset to reach</param>\n    /// <param name=\"posState\">Initial `PosState` to use</param>\n    /// <returns></returns>\n    public static (string Line, PosState<S> UpdatedState) offset(int o, in PosState<S> posState) \n    {\n        // Split the input stream at the current offset position\n        // TODO: Consider if the maths here are correct\n        // TODO: Probably TokenStream should support Split\n        S.Take(posState.Offset, posState.Input, out _, out var input);\n        S.Take(o, input, out var pre, out var post); \n        //var (pre, post) = //splitAt(o - posState.Offset, posState.Input); -- OLD VERSION OF ABOVE LINE\n        \n        // Walk the input stream and collect the position and line-text\n        Span<char> ns    = stackalloc char[lineBufferSize];\n        var        spos  = posState.SourcePos;\n        var        c     = spos.Column.Value;\n        var        l     = spos.Line.Value;\n        var        w     = posState.TabWidth;\n        var        ix    = 0;\n        \n        while(S.Take1(pre, out var tok, out pre)) \n        {\n            if (S.IsNewline(tok))\n            {\n                // Newlines add 1 to the line number, reset the column number to 1, and reset the line text\n                l += 1;\n                c = 1;\n                ix = 0;\n            }\n            else if (S.IsTab(tok))\n            {\n                // Tabs add 0-<tab width> spaces to align with the tab stop \n                var tw = w - (c - 1) % w;\n                c += tw;\n                for (var i = 0; i < tw; i++)\n                {\n                    if(ix < lineBufferSizeMinus3 ) ns[ix] = ' ';\n                    ix++;\n                }\n            }\n            else\n            {\n                // Regular tokens should be converted to char strings and added to the line text\n                var tchars = S.TokenToString(tok);\n                foreach (var tch in tchars)\n                {\n                    if (ix < lineBufferSizeMinus3) ns[ix] = tch;\n                    c++;\n                    ix++;\n                }\n            }\n\n            // Truncate long lines\n            if (ix == lineBufferSize)\n            {\n                ns[lineBufferSize - 1] = '.';\n                ns[lineBufferSize - 2] = '.';\n                ns[lineBufferSize - 3] = '.';\n            }\n        }\n        spos = spos with { Column = c, Line = l };\n        var sameLine = spos.Line == posState.SourcePos.Line;\n        var line = sameLine\n                       ? posState.LinePrefix + (ix == 0\n                                                    ? \"<empty line>\"\n                                                    : new string(ns[..Math.Min(ix, lineBufferSize)]))\n                       : ix == 0\n                           ? \"<empty line>\"\n                           : new string(ns[..Math.Min(ix, lineBufferSize)]); \n        \n        var pstate = new PosState<S>(\n            post, \n            Math.Max(o, posState.Offset), \n            spos, \n            posState.TabWidth, \n            posState.LinePrefix);\n        \n        return (line, pstate);\n    }\n    \n    /// <summary>\n    /// TODO \n    /// </summary>\n    /// <param name=\"o\">Offset to reach</param>\n    /// <param name=\"posState\">Initial `PosState` to use</param>\n    /// <returns></returns>\n    public static PosState<S> offsetNoLine(int o, in PosState<S> posState)                    \n    {\n        // Split the input stream at the current offset position\n        // TODO: Consider if the maths here are correct\n        // TODO: Probably TokenStream should support Split\n        S.Take(posState.Offset, posState.Input, out _, out var input);\n        S.Take(o, input, out var pre, out var post); \n        //var (pre, post) = //splitAt(o - posState.Offset, posState.Input); -- OLD VERSION OF ABOVE LINE\n        \n        // Walk the input stream and collect the position and line-text\n        var spos = posState.SourcePos;\n        var c    = spos.Column.Value;\n        var l    = spos.Line.Value;\n        var w    = posState.TabWidth;\n        \n        while(S.Take1(pre, out var tok, out pre)) \n        {\n            if (S.IsNewline(tok))\n            {\n                // Newlines add 1 to the line number, reset the column number to 1, and reset the line text\n                l += 1;\n                c = 1;\n            }\n            else if (S.IsTab(tok))\n            {\n                // Tabs add 0-<tab width> spaces to align with the tab stop \n                var tw = w - (c - 1) % w;\n                c += tw;\n            }\n            else\n            {\n                // Regular tokens should be converted to char strings and added to the line text\n                var tchars = S.TokenToString(tok);\n                c += tchars.Length;\n            }\n        }\n        \n        spos = spos with { Column = c, Line = l };\n        \n        var pstate = new PosState<S>(\n            post, \n            Math.Max(o, posState.Offset), \n            spos, \n            posState.TabWidth, \n            posState.LinePrefix);\n\n        return pstate;\n    }\n        \n    \n    /// <summary>\n    /// Replace tab characters with the given number of spaces\n    /// </summary>\n    /// <param name=\"tabWidth\">Tab width</param>\n    /// <param name=\"str\">String to expand</param>\n    /// <returns></returns>\n    public static string expandTab(Pos tabWidth, string str)\n    {\n        // Find out the new size of the string\n        var tabSize = tabWidth.Value;\n        var length  = 0;\n        \n        foreach (var c in str)\n        {\n            if (c == '\\t')\n            {\n                length += tabSize - length % tabSize;\n            }\n            else\n            {\n                length++;\n            }\n        }\n\n        if (str.Length == length)\n        {\n            // Bail early when there are no tabs to expand\n            return str;\n        }\n        \n        Span<char> ns    = stackalloc char[length];\n        var        index = 0;\n        foreach (var c in str)\n        {\n            if (c == '\\t')\n            {\n                var tl = tabSize - index % tabSize;\n                for (var i = 0; i < tl; i++)\n                {\n                    ns[index++] = ' ';\n                }\n            }\n            else\n            {\n                ns[index++] = c;\n            }\n        }\n        return new string(ns);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Reply/Extensions/Reply.Extensions.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static class ReplyExtensions\n{\n    extension<E, S, T, A>(K<Reply<E, S, T>, A> self)\n    {\n        public Reply<E, S, T, A> As() =>\n            (Reply<E, S, T, A>)self;\n\n        public static Reply<E, S, T, A> operator +(K<Reply<E, S, T>, A> ma) =>\n            ma.As();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Reply/Reply.Module.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Reply module\n/// </summary>\npublic static class Reply\n{\n    public static Reply<E, S, T, A> ConsumedOK<E, S, T, A>(A value, State<S, T, E> state, Hints<T> hints) =>\n        new (state, true, Result.OK<T, E, A>(hints, value));\n    \n    public static Reply<E, S, T, A> EmptyOK<E, S, T, A>(A value, State<S, T, E> state, Hints<T> hints) =>\n        new (state, false, Result.OK<T, E, A>(hints, value));    \n    \n    public static Reply<E, S, T, A> ConsumedError<E, S, T, A>(ParseError<T, E> error, State<S, T, E> state) =>\n        new (state, true, Result.Error<T, E, A>(error));\n    \n    public static Reply<E, S, T, A> EmptyError<E, S, T, A>(ParseError<T, E> error, State<S, T, E> state) =>\n        new (state, false, Result.Error<T, E, A>(error));\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Reply/Reply.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// All information available after parsing. This includes consumption of input, success (with the returned value) or\n/// failure (with the parse error), and parser state at the end of parsing. 'Reply' can also be used to resume parsing.\n/// </summary>\n/// <param name=\"NewState\">Updated state</param>\n/// <param name=\"Consumed\">Consumption flag</param>\n/// <param name=\"Result\">Parsed value</param>\n/// <typeparam name=\"E\">Error type</typeparam>\n/// <typeparam name=\"S\">Stream type</typeparam>\n/// <typeparam name=\"T\">Token type</typeparam>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic readonly record struct Reply<E, S, T, A>(State<S, T, E> NewState, bool Consumed, Result<T, E, A> Result)\n    : K<Reply<E, S, T>, A>\n{\n    public Reply(State<S, T, E> NewState, bool Consumed, K<Result<T, E>, A> Result) :\n        this(NewState, Consumed, +Result)\n    { }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Reply/Trait/Reply.TraitImpl.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\npublic class Reply<E, S, T> : Functor<Reply<E, S, T>>\n{\n    static K<Reply<E, S, T>, B> Functor<Reply<E, S, T>>.Map<A, B>(Func<A, B> f, K<Reply<E, S, T>, A> ma) =>\n        ma switch\n        {\n            Reply<E, S, T, A> r => new Reply<E, S, T, B>(r.NewState, r.Consumed, f * r.Result),\n            _                   => throw new Exception(\"Impossible\")\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Result/Extensions/Result.Extensions.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\npublic static class ResultExtensions\n{\n    extension<S, E, A>(K<Result<S, E>, A> self)\n    {\n        public Result<S, E, A> As() =>\n            (Result<S, E, A>)self;\n        \n        public static Result<S, E, A> operator+(K<Result<S, E>, A> ma) =>\n            (Result<S, E, A>)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Result/Result.Module.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\npublic static class Result\n{\n    /// <summary>\n    /// Parser succeeded (includes hints)\n    /// </summary>\n    /// <param name=\"hints\">Hints</param>\n    /// <param name=\"value\">Parsed value</param>\n    /// <typeparam name=\"T\">Token type</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Result</returns>\n    public static Result<T, E, A> OK<T, E, A>(Hints<T> hints, A value) => \n        new Result<T, E, A>.OK(hints, value);\n    \n    /// <summary>\n    /// Parse failed\n    /// </summary>\n    /// <param name=\"error\">Error value</param>\n    /// <typeparam name=\"T\">Token type</typeparam>\n    /// <typeparam name=\"E\">Error type</typeparam>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Result</returns>\n    public static Result<T, E, A> Error<T, E, A>(ParseError<T, E> error) => \n        new Result<T, E, A>.Error(error);\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Result/Result.cs",
    "content": "using LanguageExt.Traits;\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Whether the parser has failed or not. On success we include the\n/// resulting value, on failure we include a `ParseError`.\n/// </summary>\n/// <typeparam name=\"T\">Token type</typeparam>\n/// <typeparam name=\"E\">Error type</typeparam>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic abstract record Result<T, E, A> : K<Result<T, E>, A>\n{\n    /// <summary>\n    /// Parser succeeded (includes hints)\n    /// </summary>\n    /// <param name=\"Hints\">Hints</param>\n    /// <param name=\"Value\">Parsed value</param>\n    public record OK(Hints<T> Hints, A Value) : Result<T, E, A>;\n    \n    /// <summary>\n    /// Parse failed\n    /// </summary>\n    /// <param name=\"Value\">Error value</param>\n    public record Error(ParseError<T, E> Value) : Result<T, E, A>;\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/Result/Trait/Result.TraitImpl.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Result trait implementation\n/// </summary>\n/// <typeparam name=\"T\">Token type</typeparam>\n/// <typeparam name=\"E\">Error type</typeparam>\npublic class Result<T, E> : Functor<Result<T, E>>\n{\n    static K<Result<T, E>, B> Functor<Result<T, E>>.Map<A, B>(Func<A, B> f, K<Result<T, E>, A> ma) =>\n        ma switch\n        {\n            Result<T, E, A>.OK (var hints, var value) => Result.OK<T, E, B>(hints, f(value)),\n            Result<T, E, A>.Error (var e)             => Result.Error<T, E, B>(e),\n            _                                         => throw new NotSupportedException()\n        };\n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/SourcePos.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\n/// <summary>\n/// Represents a source position in a named location (i.e. a file)\n/// </summary>\n/// <param name=\"Name\">Source location name (file name)</param>\n/// <param name=\"Line\">Line number, starting at 1</param>\n/// <param name=\"Column\">Column number, starting at 1</param>\npublic readonly record struct SourcePos(\n    string Name,\n    Pos Line,\n    Pos Column)\n{\n    /// <summary>\n    /// Create a source position from a name\n    /// </summary>\n    /// <param name=\"name\">Name</param>\n    /// <returns>SourcePos</returns>\n    public static SourcePos FromName(string name) =>\n        new (name, Pos.One, Pos.One);\n    \n    /// <summary>\n    /// Convert to string\n    /// </summary>\n    /// <returns>String representation of the structure</returns>\n    public override string ToString() => \n        $\"{Name}({Line},{Column})\";\n\n    /// <summary>\n    /// Move to the beginning of the next line\n    /// </summary>\n    /// <returns></returns>\n    public SourcePos NextLine =>\n        this with { Line = Line + 1, Column = Pos.One };\n\n    /// <summary>\n    /// Move to the next token\n    /// </summary>\n    /// <returns></returns>\n    public SourcePos NextToken =>\n        this with { Column = Column + 1 };    \n\n    /// <summary>\n    /// Move to the next token\n    /// </summary>\n    /// <returns></returns>\n    public SourcePos Next(int amount) =>\n        this with { Column = Column + amount };    \n}\n"
  },
  {
    "path": "LanguageExt.Megaparsec/State.cs",
    "content": "namespace LanguageExt.Megaparsec;\n\npublic readonly record struct State<S, T, E>(\n    S Input,\n    int Offset,\n    PosState<S> PosState,\n    Seq<ParseError<T, E>> ParseErrors);\n"
  },
  {
    "path": "LanguageExt.Parsec/Common.cs",
    "content": "﻿using static LanguageExt.Parsec.ParserResult;\n\nnamespace LanguageExt.Parsec;\n\npublic static class Common\n{\n    public static readonly Parser<Pos> getDefPos =\n        inp => ConsumedOK(inp.DefPos, inp);\n\n    public static Parser<T> setDefPos<T>(Pos defpos, Parser<T> p) =>\n        inp => p(inp.SetDefPos(defpos));\n\n    public static bool onside(Pos pos, Pos delta) =>\n        pos.Column > delta.Column || pos.Line == delta.Line;\n\n    public static ParserError mergeError(ParserError? err1, ParserError? err2) =>\n        err1 is null && err2 is null     ? ParserError.Unknown(Pos.Zero)\n        : err1 is null                   ? err2 ?? ParserError.Unknown(Pos.Zero)\n        : err2 is null                   ? err1\n        : string.IsNullOrEmpty(err1.Msg) ? err2\n        : string.IsNullOrEmpty(err2.Msg) ? err1\n                                           : Pos.Compare(\n                                               err1.Pos, err2.Pos,\n                                               EQ: () =>\n                                                       err1 > err2\n                                                           ? new ParserError(err1.Tag, err1.Pos, err1.Msg, List.append(err1.Expected, err2.Expected).ToLst())\n                                                           : new ParserError(err2.Tag, err2.Pos, err2.Msg, List.append(err1.Expected, err2.Expected).ToLst()),\n                                               GT: () => err1,\n                                               LT: () => err2);\n\n    public static Reply<T> mergeErrorReply<T>(ParserError err, Reply<T> reply) =>\n        reply.Tag == ReplyTag.OK\n            ? Reply.OK(reply.Result!, reply.State!, mergeError(err, reply.Error))\n            : Reply.Error<T>(mergeError(err, reply.Error));\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Exceptions.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Parsec\n{\n#if !COREFX13\n    [Serializable]\n#endif\n    public class ParserException : Exception\n    {\n        public ParserException()\n        {\n        }\n\n        public ParserException(string message) : base(message)\n        {\n        }\n\n        public ParserException(string message, Exception innerException) : base(message, innerException)\n        {\n        }\n    }\n}"
  },
  {
    "path": "LanguageExt.Parsec/GenLanguageDef.cs",
    "content": "﻿using System.Linq;\nusing static LanguageExt.Parsec.Prim;\n\nnamespace LanguageExt.Parsec;\n\n/// <summary>\n/// The GenLanguageDef type is a record that contains all parameteridable\n/// features of the \"Parsec.Text.Token\" module.  The module \"Parsec.Text.Language\"\n/// contains some default definitions.\n/// </summary>\npublic class GenLanguageDef\n{\n    /// <summary>\n    /// Describes the start of a block comment. Use the empty string if the\n    /// language doesn't support block comments. For example \"/*\". \n    /// </summary>\n    public readonly string CommentStart;\n\n    /// <summary>\n    /// Describes the end of a block comment. Use the empty string if the\n    /// language doesn't support block comments. For example \"*\\\". \n    /// </summary>\n    public readonly string CommentEnd;\n\n    /// <summary>\n    /// Describes the start of a line comment. Use the empty string if the\n    /// language doesn't support line comments. For example \"//\". \n    /// </summary>\n    public readonly string CommentLine;\n\n    /// <summary>\n    /// Set to 'True' if the language supports nested block comments. \n    /// </summary>\n    public readonly bool NestedComments;\n\n    /// <summary>\n    /// This parser should accept any start characters of identifiers. For\n    /// example either(letter,char('_')). \n    /// </summary>\n    public readonly Parser<char> IdentStart;\n\n    /// <summary>\n    /// This parser should accept any legal tail characters of identifiers.\n    /// For example either(alphaNum, char('_')). \n    /// </summary>\n    public readonly Parser<char> IdentLetter;\n\n    /// <summary>\n    /// This parser should accept any start characters of operators. For\n    /// example oneOf(\":!#$%＆*+.\\/\\〈=〉?\\@\\\\\\\\^|-~\")\n    /// </summary>\n    public readonly Parser<char> OpStart;\n\n    /// <summary>\n    /// This parser should accept any legal tail characters of operators.\n    /// Note that this parser should even be defined if the language doesn't\n    /// support user-defined operators, or otherwise the 'reservedOp'\n    /// parser won't work correctly. \n    /// </summary>\n    public readonly Parser<char> OpLetter;\n\n    /// <summary>\n    /// The list of reserved identifiers. \n    /// </summary>\n    public readonly Lst<string> ReservedNames;\n\n    /// <summary>\n    /// The list of reserved operators.\n    /// </summary>\n    public readonly Lst<string> ReservedOpNames;\n\n    /// <summary>\n    /// Set to 'True' if the language is case sensitive. \n    /// </summary>\n    public readonly bool CaseSensitive;\n\n    /// <summary>\n    /// Empty definition, use With to build\n    /// </summary>\n    public static readonly GenLanguageDef Empty =\n        new (\"\", \"\", \"\", true, zero<char>(), zero<char>(), zero<char>(), zero<char>(), List.empty<string>(), List.empty<string>(), true);\n\n    GenLanguageDef(\n        string commentStart,\n        string commentEnd,\n        string commentLine,\n        bool nestedComments,\n        Parser<char> identStart,\n        Parser<char> identLetter,\n        Parser<char> opStart,\n        Parser<char> opLetter,\n        Lst<string> reservedNames,\n        Lst<string> reservedOpNames,\n        bool caseSensitive\n        )\n    {\n        CommentStart    = commentStart;\n        CommentEnd      = commentEnd;\n        CommentLine     = commentLine;\n        NestedComments  = nestedComments;\n        IdentStart      = identStart;\n        IdentLetter     = identLetter;\n        OpStart         = opStart;\n        OpLetter        = opLetter;\n        ReservedNames   = reservedNames.OrderBy(x => x).AsIterable().ToLst();\n        ReservedOpNames = reservedOpNames.OrderBy(x=> x).AsIterable().ToLst();\n        CaseSensitive   = caseSensitive;\n    }\n\n    public GenLanguageDef With(\n        string? CommentStart = null,\n        string? CommentEnd = null,\n        string? CommentLine = null,\n        bool? NestedComments = null,\n        Parser<char>? IdentStart = null,\n        Parser<char>? IdentLetter = null,\n        Parser<char>? OpStart = null,\n        Parser<char>? OpLetter = null,\n        Lst<string>? ReservedNames = null,\n        Lst<string>? ReservedOpNames = null,\n        bool? CaseSensitive = null\n        ) =>\n        new GenLanguageDef(\n            CommentStart    ?? this.CommentStart,\n            CommentEnd      ?? this.CommentEnd,\n            CommentLine     ?? this.CommentLine,\n            NestedComments  ?? this.NestedComments,\n            IdentStart      ?? this.IdentStart,\n            IdentLetter     ?? this.IdentLetter,\n            OpStart         ?? this.OpStart,\n            OpLetter        ?? this.OpLetter,\n            ReservedNames   ?? this.ReservedNames,\n            ReservedOpNames ?? this.ReservedOpNames,\n            CaseSensitive   ?? this.CaseSensitive\n        );\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/GenTokenParser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.ParserResult;\nusing static LanguageExt.Parsec.Internal;\nusing static LanguageExt.Parsec.Prim;\nusing static LanguageExt.Parsec.Char;\n\nnamespace LanguageExt.Parsec\n{\n    public class GenTokenParser\n    {\n        /// <summary>\n        /// This lexeme parser parses a legal identifier. Returns the identifier\n        /// string. This parser will fail on identifiers that are reserved\n        /// words. Legal identifier (start) characters and reserved words are\n        /// defined in the 'LanguageDef' that is passed to\n        /// 'makeTokenParser'. An identifier is treated as\n        /// a single token using 'try'.\n        /// </summary>\n        public readonly Parser<string> Identifier;\n\n        /// <summary>\n        /// The lexeme parser reserved(name) parses a symbol \n        /// name, but it also checks that the name is not a prefix of a\n        /// valid identifier. A reserved word is treated as a single token\n        /// using 'try'. \n        /// </summary>\n        public readonly Func<string, Parser<string>> Reserved;\n\n        /// <summary>\n        /// This lexeme parser parses a legal operator. Returns the name of the\n        /// operator. This parser will fail on any operators that are reserved\n        /// operators. Legal operator (start) characters and reserved operators\n        /// are defined in the 'LanguageDef' that is passed to\n        /// 'makeTokenParser'. An operator is treated as a\n        /// single token using 'try'. \n        /// </summary>\n        public readonly Parser<string> Operator;\n\n        /// <summary>\n        /// The lexeme parser reservedOp name parses symbol\n        /// name, but it also checks that the name is not a prefix of a\n        /// valid operator. A reservedOp is treated as a single token using\n        /// 'try'. \n        /// </summary>\n        public readonly Func<string, Parser<Unit>> ReservedOp;\n\n        /// <summary>\n        /// This lexeme parser parses a single literal character. Returns the\n        /// literal character value. This parsers deals correctly with escape\n        /// sequences. The literal character is parsed according to the grammar\n        /// rules defined in the Haskell report (which matches most programming\n        /// languages quite closely). \n        /// </summary>\n        public readonly Parser<char> CharLiteral;\n\n        /// <summary>\n        /// This lexeme parser parses a literal string. Returns the literal\n        /// string value. This parsers deals correctly with escape sequences and\n        /// gaps. The literal string is parsed according to the grammar rules\n        /// defined in the Haskell report (which matches most programming\n        /// languages quite closely). \n        /// </summary>\n        public readonly Parser<string> StringLiteral;\n\n        /// <summary>\n        /// This lexeme parser parses a natural number (a positive whole\n        /// number). Returns the value of the number. The number can be\n        /// specified in 'decimal', 'hexadecimal' or\n        /// 'octal'. The number is parsed according to the grammar\n        /// rules in the Haskell report. \n        /// </summary>\n        public readonly Parser<int> Natural;\n\n        /// <summary>\n        /// This lexeme parser parses an integer (a whole number). This parser\n        /// is like 'natural' except that it can be prefixed with\n        /// sign (i.e. \\'-\\' or \\'+\\'). Returns the value of the number. The\n        /// number can be specified in 'decimal', 'hexadecimal'\n        /// or 'octal'. The number is parsed according\n        /// to the grammar rules in the Haskell report. \n        /// </summary>\n        public readonly Parser<int> Integer;\n\n        /// <summary>\n        /// This lexeme parser parses a floating point value. Returns the value\n        /// of the number. The number is parsed according to the grammar rules\n        /// defined in the Haskell report. \n        /// </summary>\n        public readonly Parser<double> Float;\n\n        /// <summary>\n        /// This lexeme parser parses either 'natural' or a 'float'.\n        /// Returns the value of the number. This parsers deals with\n        /// any overlap in the grammar rules for naturals and floats. The number\n        /// is parsed according to the grammar rules defined in the Haskell report. \n        /// </summary>\n        public readonly Parser<Either<int,double>> NaturalOrFloat;\n\n        /// <summary>\n        /// Parses a positive whole number in the decimal system. Returns the\n        /// value of the number. \n        /// </summary>\n        public readonly Parser<int> Decimal;\n\n        /// <summary>\n        /// Parses a positive whole number in the hexadecimal system. The number\n        /// should be prefixed with \"0x\" or \"0X\". Returns the value of the\n        /// number.\n        /// </summary>\n        public readonly Parser<int> Hexadecimal;\n\n        /// <summary>\n        /// Parses a positive whole number in the octal system. The number\n        /// should be prefixed with \"0o\" or \"0O\". Returns the value of the\n        /// number. \n        /// </summary>\n        public readonly Parser<int> Octal;\n\n        /// <summary>\n        /// Lexeme parser symbol(s) parses 'string' s and skips\n        /// trailing white space. \n        /// </summary>\n        public readonly Func<string, Parser<string>> Symbol;\n\n        /// <summary>\n        /// lexeme(p) first applies parser p and than the 'whiteSpace'\n        /// parser, returning the value of p. Every lexical\n        /// token (lexeme) is defined using lexeme, this way every parse\n        /// starts at a point without white space. Parsers that use lexeme are\n        /// called lexeme parsers in this document.\n        /// \n        /// The only point where the 'whiteSpace' parser should be\n        /// called explicitly is the start of the main parser in order to skip\n        /// any leading white space.\n        /// </summary>\n        public Parser<T> Lexeme<T>(Parser<T> p) =>\n            from x in p\n            from _ in WhiteSpace\n            select x;\n\n        /// <summary>\n        /// Parses any white space. White space consists of /zero/ or more\n        /// occurrences of a 'space', a line comment or a block (multi\n        /// line) comment. Block comments may be nested. How comments are\n        /// started and ended is defined in the 'LanguageDef'\n        /// that is passed to 'makeTokenParser'. \n        /// </summary>\n        public readonly Parser<Unit> WhiteSpace;\n\n        /// <summary>\n        /// Lexeme parser parens(p) parses p enclosed in parenthesis,\n        /// returning the value of p.\n        /// </summary>\n        public Parser<T> Parens<T>(Parser<T> p) =>\n            from o in Symbol(\"(\")\n            from x in p\n            from c in Symbol(\")\")\n            select x;\n\n        /// <summary>\n        /// Lexeme parser braces(p) parses p enclosed in braces { and\n        /// }, returning the value of p. \n        /// </summary>\n        public Parser<T> Braces<T>(Parser<T> p) =>\n            from o in Symbol(\"{\")\n            from x in p\n            from c in Symbol(\"}\")\n            select x;\n\n        /// <summary>\n        /// Lexeme parser angles(p) parses p enclosed in angle brackets 〈\n        /// and 〉, returning the value of p. \n        /// </summary>\n        public Parser<T> Angles<T>(Parser<T> p) =>\n            from o in Symbol(\"<\")\n            from x in p\n            from c in Symbol(\">\")\n            select x;\n\n        /// <summary>\n        /// Lexeme parser brackets(p) parses p enclosed in brackets [\n        /// and ], returning the value of p. \n        /// </summary>\n        public Parser<T> Brackets<T>(Parser<T> p) =>\n            from o in Symbol(\"[\")\n            from x in p\n            from c in Symbol(\"]\")\n            select x;\n\n        /// <summary>\n        /// Lexeme parser semi parses the character ; and skips any\n        /// trailing white space. Returns the string \";\". \n        /// </summary>\n        public readonly Parser<string> Semi;\n\n        /// <summary>\n        /// Lexeme parser comma parses the character , and skips any\n        /// trailing white space. Returns the string \",\". \n        /// </summary>\n        public readonly Parser<string> Comma;\n\n        /// <summary>\n        /// Lexeme parser colon parses the character : and skips any\n        /// trailing white space. Returns the string \":\". \n        /// </summary>\n        public readonly Parser<string> Colon;\n\n        /// <summary>\n        /// Lexeme parser dot parses the character . and skips any\n        /// trailing white space. Returns the string \".\". \n        /// </summary>\n        public readonly Parser<string> Dot;\n\n        /// <summary>\n        /// Lexeme parser semiSep(p) parses /zero/ or more occurrences of p\n        /// separated by semi. Returns a list of values returned by\n        /// p.\n        /// </summary>\n        public Parser<Seq<T>> SemiSep<T>(Parser<T> p) =>\n            sepBy(p, Semi);\n\n        /// <summary>\n        /// Lexeme parser semiSep1(p) parses /one/ or more occurrences of p\n        /// separated by 'semi'. Returns a list of values returned by p. \n        /// </summary>\n        public Parser<Seq<T>> SemiSep1<T>(Parser<T> p) =>\n            sepBy1(p, Semi);\n\n        /// <summary>\n        /// Lexeme parser commaSep(p) parses /zero/ or more occurrences of\n        /// p separated by 'comma'. Returns a list of values returned\n        /// by p. \n        /// </summary>\n        public Parser<Seq<T>> CommaSep<T>(Parser<T> p) =>\n            sepBy(p, Comma);\n\n        /// <summary>\n        /// Lexeme parser commaSep1(p) parses /one/ or more occurrences of\n        /// p separated by 'comma'. Returns a list of values returned\n        /// by p. \n        /// </summary>\n        public Parser<Seq<T>> CommaSep1<T>(Parser<T> p) =>\n            sepBy1(p, Comma);\n\n        public Parser<Seq<T>> BracketsCommaSep1<T>(Parser<T> p) =>\n            Brackets(sepBy1(p, Comma));\n\n        public Parser<Seq<T>> BracketsCommaSep<T>(Parser<T> p) =>\n            Brackets(sepBy(p, Comma));\n\n        public Parser<Seq<T>> ParensCommaSep1<T>(Parser<T> p) =>\n            Parens(sepBy1(p, Comma));\n\n        public Parser<Seq<T>> ParensCommaSep<T>(Parser<T> p) =>\n            Parens(sepBy(p, Comma));\n\n        public Parser<Seq<T>> AnglesCommaSep1<T>(Parser<T> p) =>\n            Angles(sepBy1(p, Comma));\n\n        public Parser<Seq<T>> AnglesCommaSep<T>(Parser<T> p) =>\n            Angles(sepBy(p, Comma));\n\n        public Parser<Seq<T>> BracesCommaSep1<T>(Parser<T> p) =>\n            Braces(sepBy1(p, Comma));\n\n        public Parser<Seq<T>> BracesCommaSep<T>(Parser<T> p) =>\n            Braces(sepBy(p, Comma));\n\n\n        public Parser<Seq<T>> BracketsSemiSep1<T>(Parser<T> p) =>\n            Brackets(sepBy1(p, Semi));\n\n        public Parser<Seq<T>> BracketsSemiSep<T>(Parser<T> p) =>\n            Brackets(sepBy(p, Semi));\n\n        public Parser<Seq<T>> ParensSemiSep1<T>(Parser<T> p) =>\n            Parens(sepBy1(p, Semi));\n\n        public Parser<Seq<T>> ParensSemiSep<T>(Parser<T> p) =>\n            Parens(sepBy(p, Semi));\n\n        public Parser<Seq<T>> AnglesSemiSep1<T>(Parser<T> p) =>\n            Angles(sepBy1(p, Semi));\n\n        public Parser<Seq<T>> AnglesSemiSep<T>(Parser<T> p) =>\n            Angles(sepBy(p, Semi));\n\n        public Parser<Seq<T>> BracesSemiSep1<T>(Parser<T> p) =>\n            Braces(sepBy1(p, Semi));\n\n        public Parser<Seq<T>> BracesSemiSep<T>(Parser<T> p) =>\n            Braces(sepBy(p, Semi));\n\n        internal GenTokenParser(\n            Parser<string> indentifier,\n            Func<string, Parser<string>> reserved,\n            Parser<string> op,\n            Func<string, Parser<Unit>> reservedOp,\n            Parser<char> charLiteral,\n            Parser<string> stringLiteral,\n            Parser<int> natural,\n            Parser<int> integer,\n            Parser<double> floating,\n            Parser<Either<int, double>> naturalOrFloat,\n            Parser<int> dec,\n            Parser<int> hexadecimal,\n            Parser<int> octal,\n            Func<string, Parser<string>> symbol,\n            Parser<Unit> whiteSpace,\n            Parser<string> semi,\n            Parser<string> comma,\n            Parser<string> colon,\n            Parser<string> dot\n            )\n        {\n            Identifier = indentifier;\n            this.Reserved = reserved;\n            this.Operator = op;\n            this.ReservedOp = reservedOp;\n            this.CharLiteral = charLiteral;\n            this.StringLiteral = stringLiteral;\n            this.Natural = natural;\n            this.Integer = integer;\n            this.Float = floating;\n            this.NaturalOrFloat = naturalOrFloat;\n            this.Decimal = dec;\n            Hexadecimal = hexadecimal;\n            Octal = octal;\n            this.Symbol = symbol;\n            this.WhiteSpace = whiteSpace;\n            this.Semi = semi;\n            this.Comma = comma;\n            this.Colon = colon;\n            this.Dot = dot;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/GenTokenParser2.cs",
    "content": "﻿using System;\nusing LanguageExt.UnsafeValueAccess;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Prim;\n\nnamespace LanguageExt.Parsec;\n\npublic class GenTokenParser2\n{\n    /// <summary>\n    /// This lexeme parser parses a legal identifier. Returns the identifier\n    /// string. This parser will fail on identifiers that are reserved\n    /// words. Legal identifier (start) characters and reserved words are\n    /// defined in the 'LanguageDef' that is passed to\n    /// 'makeTokenParser'. An identifier is treated as\n    /// a single token using 'try'.\n    /// </summary>\n    public readonly Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Identifier;\n\n    /// <summary>\n    /// The lexeme parser reserved(name) parses a symbol \n    /// name, but it also checks that the name is not a prefix of a\n    /// valid identifier. A reserved word is treated as a single token\n    /// using 'try'. \n    /// </summary>\n    public readonly Func<string, Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>> Reserved;\n\n    /// <summary>\n    /// This lexeme parser parses a legal operator. Returns the name of the\n    /// operator. This parser will fail on any operators that are reserved\n    /// operators. Legal operator (start) characters and reserved operators\n    /// are defined in the 'LanguageDef' that is passed to\n    /// 'makeTokenParser'. An operator is treated as a\n    /// single token using 'try'. \n    /// </summary>\n    public readonly Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Operator;\n\n    /// <summary>\n    /// The lexeme parser reservedOp name parses symbol\n    /// name, but it also checks that the name is not a prefix of a\n    /// valid operator. A reservedOp is treated as a single token using\n    /// 'try'. \n    /// </summary>\n    public readonly Func<string, Parser<(Unit Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>> ReservedOp;\n\n    /// <summary>\n    /// This lexeme parser parses a single literal character. Returns the\n    /// literal character value. This parsers deals correctly with escape\n    /// sequences. The literal character is parsed according to the grammar\n    /// rules defined in the Haskell report (which matches most programming\n    /// languages quite closely). \n    /// </summary>\n    public readonly Parser<(char Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> CharLiteral;\n\n    /// <summary>\n    /// This lexeme parser parses a literal string. Returns the literal\n    /// string value. This parsers deals correctly with escape sequences and\n    /// gaps. The literal string is parsed according to the grammar rules\n    /// defined in the Haskell report (which matches most programming\n    /// languages quite closely). \n    /// </summary>\n    public readonly Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> StringLiteral;\n\n    /// <summary>\n    /// This lexeme parser parses a natural number (a positive whole\n    /// number). Returns the value of the number. The number can be\n    /// specified in 'decimal', 'hexadecimal' or\n    /// 'octal'. The number is parsed according to the grammar\n    /// rules in the Haskell report. \n    /// </summary>\n    public readonly Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Natural;\n\n    /// <summary>\n    /// This lexeme parser parses an integer (a whole number). This parser\n    /// is like 'natural' except that it can be prefixed with\n    /// sign (i.e. \\'-\\' or \\'+\\'). Returns the value of the number. The\n    /// number can be specified in 'decimal', 'hexadecimal'\n    /// or 'octal'. The number is parsed according\n    /// to the grammar rules in the Haskell report. \n    /// </summary>\n    public readonly Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Integer;\n\n    /// <summary>\n    /// This lexeme parser parses a floating point value. Returns the value\n    /// of the number. The number is parsed according to the grammar rules\n    /// defined in the Haskell report. \n    /// </summary>\n    public readonly Parser<(double Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Float;\n\n    /// <summary>\n    /// This lexeme parser parses either 'natural' or a 'float'.\n    /// Returns the value of the number. This parsers deals with\n    /// any overlap in the grammar rules for naturals and floats. The number\n    /// is parsed according to the grammar rules defined in the Haskell report. \n    /// </summary>\n    public readonly Parser<(Either<int, double> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> NaturalOrFloat;\n\n    /// <summary>\n    /// Parses a positive whole number in the decimal system. Returns the\n    /// value of the number. \n    /// </summary>\n    public readonly Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Decimal;\n\n    /// <summary>\n    /// Parses a positive whole number in the hexadecimal system. The number\n    /// should be prefixed with \"0x\" or \"0X\". Returns the value of the\n    /// number.\n    /// </summary>\n    public readonly Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Hexadecimal;\n\n    /// <summary>\n    /// Parses a positive whole number in the octal system. The number\n    /// should be prefixed with \"0o\" or \"0O\". Returns the value of the\n    /// number. \n    /// </summary>\n    public readonly Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Octal;\n\n    /// <summary>\n    /// Lexeme parser symbol(s) parses 'string' s and skips\n    /// trailing white space. \n    /// </summary>\n    public readonly Func<string, Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>> Symbol;\n\n    /// <summary>\n    /// lexeme(p) first applies parser p and than the 'whiteSpace'\n    /// parser, returning the value of p. Every lexical\n    /// token (lexeme) is defined using lexeme, this way every parse\n    /// starts at a point without white space. Parsers that use lexeme are\n    /// called lexeme parsers in this document.\n    /// \n    /// The only point where the 'whiteSpace' parser should be\n    /// called explicitly is the start of the main parser in order to skip\n    /// any leading white space.\n    /// </summary>\n    public Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Lexeme<A>(Parser<A> p) =>\n        Token2.lexemeDef<A>(WhiteSpace)(p);\n\n    /// <summary>\n    /// Parses any white space. White space consists of /zero/ or more\n    /// occurrences of a 'space', a line comment or a block (multi\n    /// line) comment. Block comments may be nested. How comments are\n    /// started and ended is defined in the 'LanguageDef'\n    /// that is passed to 'makeTokenParser'. \n    /// </summary>\n    public readonly Parser<Unit> WhiteSpace;\n\n    /// <summary>\n    /// Lexeme parser parens(p) parses p enclosed in parenthesis,\n    /// returning the value of p.\n    /// </summary>\n    public Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Parens<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        from o in Symbol(\"(\")\n        from x in p\n        from c in Symbol(\")\")\n        select x;\n\n    /// <summary>\n    /// Lexeme parser braces(p) parses p enclosed in braces { and\n    /// }, returning the value of p. \n    /// </summary>\n    public Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Braces<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        from o in Symbol(\"{\")\n        from x in p\n        from c in Symbol(\"}\")\n        select x;\n\n    /// <summary>\n    /// Lexeme parser angles(p) parses p enclosed in angle brackets〈\n    /// and 〉, returning the value of p. \n    /// </summary>\n    public Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Angles<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        from o in Symbol(\"<\")\n        from x in p\n        from c in Symbol(\">\")\n        select x;\n\n    /// <summary>\n    /// Lexeme parser brackets(p) parses p enclosed in brackets [\n    /// and ], returning the value of p. \n    /// </summary>\n    public Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Brackets<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        from o in Symbol(\"[\")\n        from x in p\n        from c in Symbol(\"]\")\n        select x;\n\n    /// <summary>\n    /// Lexeme parser semi parses the character ; and skips any\n    /// trailing white space. Returns the string \";\". \n    /// </summary>\n    public readonly Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Semi;\n\n    /// <summary>\n    /// Lexeme parser comma parses the character , and skips any\n    /// trailing white space. Returns the string \",\". \n    /// </summary>\n    public readonly Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Comma;\n\n    /// <summary>\n    /// Lexeme parser colon parses the character : and skips any\n    /// trailing white space. Returns the string \":\". \n    /// </summary>\n    public readonly Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Colon;\n\n    /// <summary>\n    /// Lexeme parser dot parses the character . and skips any\n    /// trailing white space. Returns the string \".\". \n    /// </summary>\n    public readonly Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> Dot;\n\n    /// <summary>\n    /// Lexeme parser semiSep(p) parses /zero/ or more occurrences of p\n    /// separated by semi. Returns a list of values returned by\n    /// p.\n    /// </summary>\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> SepBy<A, S>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p, Parser<S> sep) =>\n        from bp in getPos\n        from bi in getIndex\n        from xs in sepBy(p, sep)\n        select xs.IsEmpty\n                   ? (Seq<A>(), bp, bp, bi, bi)\n                   : (xs.Map(static x => x.Value), xs.Head.ValueUnsafe()!.BeginPos, xs.Last.ValueUnsafe()!.EndPos, xs.Head.ValueUnsafe()!.BeginIndex, xs.Head.ValueUnsafe()!.EndIndex);\n\n    /// <summary>\n    /// Lexeme parser semiSep1(p) parses /one/ or more occurrences of p\n    /// separated by 'semi'. Returns a list of values returned by p. \n    /// </summary>\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> SepBy1<A, S>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p, Parser<S> sep) =>\n        sepBy1(p, sep)\n           .Map(static xs => (xs.Map(static x => x.Value), xs.Head.ValueUnsafe().BeginPos, xs.Last.ValueUnsafe().EndPos, xs.Head.ValueUnsafe().BeginIndex, xs.Head.ValueUnsafe().EndIndex));        \n\n    /// <summary>\n    /// Lexeme parser semiSep(p) parses /zero/ or more occurrences of p\n    /// separated by semi. Returns a list of values returned by\n    /// p.\n    /// </summary>\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> SemiSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        SepBy(p, Semi);\n\n    /// <summary>\n    /// Lexeme parser semiSep1(p) parses /one/ or more occurrences of p\n    /// separated by 'semi'. Returns a list of values returned by p. \n    /// </summary>\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> SemiSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        SepBy1(p, Semi);\n\n    /// <summary>\n    /// Lexeme parser commaSep(p) parses /zero/ or more occurrences of\n    /// p separated by 'comma'. Returns a list of values returned\n    /// by p. \n    /// </summary>\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> CommaSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        SepBy(p, Comma);\n        \n    /// <summary>\n    /// Lexeme parser commaSep1(p) parses /one/ or more occurrences of\n    /// p separated by 'comma'. Returns a list of values returned\n    /// by p. \n    /// </summary>\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> CommaSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        SepBy1(p, Comma);\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> BracketsCommaSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Brackets(SepBy1(p, Comma));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> BracketsCommaSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Brackets(SepBy(p, Comma));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> ParensCommaSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Parens(SepBy1(p, Comma));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> ParensCommaSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Parens(SepBy(p, Comma));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> AnglesCommaSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Angles(SepBy1(p, Comma));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> AnglesCommaSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Angles(SepBy(p, Comma));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> BracesCommaSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Braces(SepBy1(p, Comma));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> BracesCommaSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Braces(SepBy(p, Comma));\n\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> BracketsSemiSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Brackets(SepBy1(p, Semi));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> BracketsSemiSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Brackets(SepBy(p, Semi));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> ParensSemiSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Parens(SepBy1(p, Semi));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> ParensSemiSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Parens(SepBy(p, Semi));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> AnglesSemiSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Angles(SepBy1(p, Semi));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> AnglesSemiSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Angles(SepBy(p, Semi));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> BracesSemiSep1<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Braces(SepBy1(p, Semi));\n\n    public Parser<(Seq<A> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> BracesSemiSep<A>(Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> p) =>\n        Braces(SepBy(p, Semi));\n\n    internal GenTokenParser2(\n        Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> indentifier,\n        Func<string, Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>> reserved,\n        Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> op,\n        Func<string, Parser<(Unit Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>> reservedOp,\n        Parser<(char Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> charLiteral,\n        Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> stringLiteral,\n        Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> natural,\n        Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> integer,\n        Parser<(double Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> floating,\n        Parser<(Either<int, double> Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> naturalOrFloat,\n        Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> dec,\n        Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> hexadecimal,\n        Parser<(int Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> octal,\n        Func<string, Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>> symbol,\n        Parser<Unit> whiteSpace,\n        Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> semi,\n        Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> comma,\n        Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> colon,\n        Parser<(string Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)> dot\n        )\n    {\n        Identifier          = indentifier;\n        this.Reserved       = reserved;\n        this.Operator       = op;\n        this.ReservedOp     = reservedOp;\n        this.CharLiteral    = charLiteral;\n        this.StringLiteral  = stringLiteral;\n        this.Natural        = natural;\n        this.Integer        = integer;\n        this.Float          = floating;\n        this.NaturalOrFloat = naturalOrFloat;\n        this.Decimal        = dec;\n        Hexadecimal         = hexadecimal;\n        Octal               = octal;\n        this.Symbol         = symbol;\n        this.WhiteSpace     = whiteSpace;\n        this.Semi           = semi;\n        this.Comma          = comma;\n        this.Colon          = colon;\n        this.Dot            = dot;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Language.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Prim;\nusing static LanguageExt.Parsec.Char;\nusing static LanguageExt.Parsec.Expr;\nusing static LanguageExt.Parsec.Token;\n\nnamespace LanguageExt.Parsec\n{\n    public static class Language\n    {\n        /// <summary>\n        /// This is a minimal token definition for Haskell style languages. It\n        /// defines the style of comments, valid identifiers and case\n        /// sensitivity.  It does not define any reserved words or operators.\n        /// </summary>\n        public readonly static GenLanguageDef HaskellStyle =\n            GenLanguageDef.Empty.With(\n                CommentStart: \"{-\",\n                CommentEnd: \"-}\",\n                CommentLine: \"--\",\n                NestedComments: true,\n                IdentStart: letter,\n                IdentLetter: either(alphaNum, oneOf(\"_'\")),\n                OpStart: oneOf(\":!#$%&*+./<=>?@\\\\^|-~\"),\n                OpLetter: oneOf(\":!#$%&*+./<=>?@\\\\^|-~\"),\n                ReservedOpNames: List<string>(),\n                ReservedNames: List<string>(),\n                CaseSensitive: true\n                );\n\n        /// <summary>\n        /// This is a minimal token definition for Java style languages. It\n        /// defines the style of comments, valid identifiers and case\n        /// sensitivity.  It does not define any reserved words.\n        /// </summary>\n        public readonly static GenLanguageDef JavaStyle =\n            GenLanguageDef.Empty.With(\n                CommentStart: \"/*\",\n                CommentEnd: \"*/\",\n                CommentLine: \"//\",\n                NestedComments: true,\n                IdentStart: letter,\n                IdentLetter: either(alphaNum, oneOf(\"_'\")),\n                OpStart: oneOf(@\"!%&*+.<=>?@\\^|-~\"),\n                OpLetter: oneOf(@\"!%&*+.<=>?@\\^|-~\"),\n                ReservedOpNames: List<string>(),\n                ReservedNames: List<string>(),\n                CaseSensitive: true\n                );\n\n        /// <summary>\n        /// The language definition for the language Haskell98.\n        /// </summary>\n        public readonly static GenLanguageDef Haskell98Def =\n            HaskellStyle.With(\n                ReservedOpNames: List.create(\"::\", \"..\", \"=\", \"\\\\\", \"|\", \"<-\", \"->\", \"@\", \"~\", \"=>\"),\n                ReservedNames: List.create(\n                    \"let\", \"in\", \"case\", \"of\", \"if\", \"then\", \"else\",\n                    \"data\", \"type\",\n                    \"class\", \"default\", \"deriving\", \"do\", \"import\",\n                    \"infix\", \"infixl\", \"infixr\", \"instance\", \"module\",\n                    \"newtype\", \"where\",\n                    \"primitive\"));\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/LanguageExt.Parsec.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)'=='Debug'\">\n        <DefineConstants>TRACE;DEBUG</DefineConstants>\n    </PropertyGroup>\n    <PropertyGroup Label=\"Configuration\">\n        <NoWarn>1701;1702;1705;IDE1006;CS1591;CS1573;CS1712;CS1711;CS1572;CS1587</NoWarn>\n        <DefineConstants>CONTRACTS_FULL</DefineConstants>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <PackageVersion>5.0.0-beta-77</PackageVersion>\n        <PackageId>LanguageExt.Parsec</PackageId>\n        <Title>LanguageExt.Parsec</Title>\n        <Authors>Paul Louth</Authors>\n        <Summary>Functional language extensions for C#</Summary>\n        <Copyright>Copyright (c) Paul Louth. All rights reserved.</Copyright>\n        <PackageReadmeFile>README.nuget.md</PackageReadmeFile>\n        <Description>Parser combinators library based on Haskell Parsec.  This is part of the LanguageExt functional framework and requires LanguageExt.Core</Description>\n        <PackageTags>C#, Functional, Language Extension, Monad, Option, Either, Reader, Writer, State, List, Set, Map, Queue, Memo, Memoization, Immutable, Lambda, Pattern Matching, Tuple</PackageTags>\n        <PackageIcon>lang-ext-small.png</PackageIcon>\n        <PackageProjectUrl>https://github.com/louthy/language-ext</PackageProjectUrl>\n        <PackageLicenseExpression>MIT</PackageLicenseExpression>\n        <EnableDefaultCompileItems>false</EnableDefaultCompileItems>\n        <DocumentationFile>bin\\$(Configuration)\\$(TargetFramework)\\$(AssemblyName).xml</DocumentationFile>\n        <OutputType>library</OutputType>\n        <AssemblyVersion>5.0.0.0</AssemblyVersion>\n        <FileVersion>5.0.0.0</FileVersion>\n        <LangVersion>default</LangVersion>\n    </PropertyGroup>\n    <ItemGroup>\n        <InternalsVisibleTo Include=\"LanguageExt.Tests\" />\n    </ItemGroup>\n    <ItemGroup>\n        <None Include=\"README.nuget.md\" Pack=\"true\" PackagePath=\"\\\"/>\n        <None Include=\"..\\Images\\lang-ext-small.png\" Pack=\"true\" PackagePath=\"\\\"/>\n    </ItemGroup>\n\n    <ItemGroup>\n        <Compile Include=\"**\\*.cs\" />\n        <EmbeddedResource Include=\"**\\*.resx\" />\n    </ItemGroup>\n    <ItemGroup>\n        <Compile Remove=\"obj\\**\" />\n        <EmbeddedResource Remove=\"obj\\**\" />\n        <None Remove=\"obj\\**\" />\n    </ItemGroup>\n    <ItemGroup>\n        <PackageReference Include=\"System.ValueTuple\" Version=\"[4.5.0,)\" />\n    </ItemGroup>\n    <ItemGroup>\n        <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n        <ProjectReference Include=\"..\\LanguageExt.Streaming\\LanguageExt.Streaming.csproj\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "LanguageExt.Parsec/OperatorIOs.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Parsec\n{\n    public static partial class Operator\n    {\n        public static Operator<I, O> Infix<I, O>(Assoc assoc, Parser<I, Func<O, O, O>> p) =>\n            new InfixOp<I, O>(assoc, p);\n\n        public static Operator<I, O> Prefix<I, O>(Parser<I, Func<O, O>> p) =>\n            new PrefixOp<I, O>(p);\n\n        public static Operator<I, O> Postfix<I, O>(Parser<I, Func<O, O>> p) =>\n            new PostfixOp<I, O>(p);\n    }\n\n    public abstract class Operator<I, O>\n    {\n        public readonly OperatorTag Tag;\n\n        public Operator(OperatorTag tag)\n        {\n            Tag = tag;\n        }\n\n        public abstract (Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O>>>, Seq<Parser<I, Func<O, O>>>) SplitOp(\n            (Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O>>>, Seq<Parser<I, Func<O, O>>>) state);\n    }\n\n    public class InfixOp<I, O> : Operator<I, O>\n    {\n        public readonly Assoc Assoc;\n        public readonly Parser<I, Func<O, O, O>> Op;\n\n        internal InfixOp(Assoc assoc, Parser<I, Func<O, O, O>> p)\n            :\n            base(OperatorTag.Infix)\n        {\n            Assoc = assoc;\n            Op = p;\n        }\n\n        public override (Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O>>>, Seq<Parser<I, Func<O, O>>>) SplitOp(\n            (Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O>>>, Seq<Parser<I, Func<O, O>>>) state) =>\n            state.Map(\n                (rassoc, lassoc, nassoc, prefix, postfix) =>\n                    Assoc == Assoc.None ? (rassoc, lassoc, Op.Cons(nassoc), prefix, postfix)\n                  : Assoc == Assoc.Left ? (rassoc, Op.Cons(lassoc), nassoc, prefix, postfix)\n                  : (Op.Cons(rassoc), lassoc, nassoc, prefix, postfix));\n    }\n\n    public class PrefixOp<I, O> : Operator<I, O>\n    {\n        public readonly Parser<I, Func<O, O>> Op;\n\n        internal PrefixOp(Parser<I, Func<O, O>> p)\n            :\n            base(OperatorTag.Prefix)\n        {\n            Op = p;\n        }\n\n        public override (Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O>>>, Seq<Parser<I, Func<O, O>>>) SplitOp(\n            (Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O>>>, Seq<Parser<I, Func<O, O>>>) state) =>\n            state.Map(\n                (rassoc, lassoc, nassoc, prefix, postfix) =>\n                    (rassoc, lassoc, nassoc, Op.Cons(prefix), postfix));\n\n    }\n\n    public class PostfixOp<I, O> : Operator<I, O>\n    {\n        public readonly Parser<I, Func<O, O>> Op;\n\n        internal PostfixOp(Parser<I, Func<O, O>> p)\n            :\n            base(OperatorTag.Postfix)\n        {\n            Op = p;\n        }\n\n        public override (Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O>>>, Seq<Parser<I, Func<O, O>>>) SplitOp(\n            (Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O, O>>>, Seq<Parser<I, Func<O, O>>>, Seq<Parser<I, Func<O, O>>>) state) =>\n            state.Map(\n                (rassoc, lassoc, nassoc, prefix, postfix) =>\n                    (rassoc, lassoc, nassoc, prefix, Op.Cons(postfix)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Operators.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Parsec\n{\n    public enum Assoc\n    {\n        None,\n        Left,\n        Right\n    }\n\n    public enum OperatorTag\n    {\n        Infix,\n        Prefix,\n        Postfix\n    }\n\n    public static partial class Operator\n    {\n        public static Operator<A> Infix<A>(Assoc assoc, Parser<Func<A, A, A>> p) =>\n            new InfixOp<A>(assoc, p);\n\n        public static Operator<A> Prefix<A>(Parser<Func<A, A>> p) =>\n            new PrefixOp<A>(p);\n\n        public static Operator<A> Postfix<A>(Parser<Func<A, A>> p) =>\n            new PostfixOp<A>(p);\n    }\n\n    public abstract class Operator<A>\n    {\n        public readonly OperatorTag Tag;\n\n        public Operator(OperatorTag tag)\n        {\n            Tag = tag;\n        }\n\n        public abstract (Seq<Parser<Func<A,A,A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) SplitOp(\n            (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) state);\n    }\n\n    public class InfixOp<A> : Operator<A>\n    {\n        public readonly Assoc Assoc;\n        public readonly Parser<Func<A, A, A>> Op;\n\n        internal InfixOp(Assoc assoc, Parser<Func<A, A, A>> p)\n            :\n            base(OperatorTag.Infix)\n        {\n            Assoc = assoc;\n            Op = p;\n        }\n\n        public override (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) SplitOp(\n            (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) state) =>\n            state.Map(\n                (rassoc, lassoc, nassoc, prefix, postfix) =>\n                    Assoc == Assoc.None ? (rassoc, lassoc, Op.Cons(nassoc), prefix, postfix)\n                  : Assoc == Assoc.Left ? (rassoc, Op.Cons(lassoc), nassoc, prefix, postfix)\n                  : (Op.Cons(rassoc), lassoc, nassoc, prefix, postfix));\n\n    }\n\n    public class PrefixOp<A> : Operator<A>\n    {\n        public readonly Parser<Func<A, A>> Op;\n\n        internal PrefixOp(Parser<Func<A, A>> p)\n            :\n            base(OperatorTag.Prefix)\n        {\n            Op = p;\n        }\n\n        public override (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) SplitOp(\n            (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) state) =>\n            state.Map(\n                (rassoc, lassoc, nassoc, prefix, postfix) =>\n                    (rassoc, lassoc, nassoc, Op.Cons(prefix), postfix));\n\n    }\n\n    public class PostfixOp<A> : Operator<A>\n    {\n        public readonly Parser<Func<A, A>> Op;\n\n        internal PostfixOp(Parser<Func<A, A>> p)\n            :\n            base(OperatorTag.Postfix)\n        {\n            Op = p;\n        }\n\n        public override (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) SplitOp(\n            (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) state) =>\n            state.Map(\n                (rassoc, lassoc, nassoc, prefix, postfix) =>\n                    (rassoc, lassoc, nassoc, prefix, Op.Cons(postfix)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/PString.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Parsec\n{\n    /// <summary>\n    /// Represents the parser source text and the parser's \n    /// positional state.\n    /// </summary>\n    public class PString\n    {\n        public readonly string Value;\n        public readonly int Index;\n        public readonly int EndIndex;\n        public readonly Pos Pos;\n        public readonly Pos DefPos;\n        public readonly Sidedness Side;\n        public readonly Option<object> UserState;\n\n        public PString(string value, int index, int endIndex, Pos pos, Pos defPos, Sidedness side, Option<object> userState)\n        {\n            Value     = value ?? throw new ArgumentNullException(nameof(value));\n            Index     = index;\n            EndIndex  = endIndex;\n            Pos       = pos;\n            DefPos    = defPos;\n            Side      = side;\n            UserState = userState;\n        }\n\n        public PString SetDefPos(Pos defpos) =>\n            new PString(Value, Index, EndIndex, Pos, defpos, Side, UserState);\n\n        public PString SetPos(Pos pos) =>\n            new PString(Value, Index, EndIndex, pos, DefPos, Side, UserState);\n\n        public PString SetSide(Sidedness side) =>\n            new PString(Value, Index, EndIndex, Pos, DefPos, side, UserState);\n\n        public PString SetValue(string value) =>\n            new PString(value, Index, value.Length, Pos, DefPos, Side, UserState);\n\n        public PString SetIndex(int index) =>\n            new PString(Value, index, EndIndex, Pos, DefPos, Side, UserState);\n\n        public PString SetUserState(object? state) =>\n            new PString(Value, Index, EndIndex, Pos, DefPos, Side, state);\n\n        public PString SetEndIndex(int endIndex) =>\n            new PString(Value, Index, endIndex, Pos, DefPos, Side, UserState);\n\n        public override string ToString() =>\n            Value.Substring(Index, EndIndex - Index);\n\n        public static readonly PString Zero =\n            new PString(\"\", 0, 0, Pos.Zero, Pos.Zero, Sidedness.Onside, None);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/PStringIO.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Parsec\n{\n    /// <summary>\n    /// Represents the parser source string and the parser's \n    /// positional state.\n    /// </summary>\n    public class PString<T>\n    {\n        public readonly T[] Value;\n        public readonly int Index;\n        public readonly int EndIndex;\n        public readonly Option<object> UserState;\n        public readonly Func<T, Pos> TokenPos;\n\n        public PString(T[] value, int index, int endIndex, Option<object> userState, Func<T, Pos> tokenPos)\n        {\n            Value     = value ?? throw new ArgumentNullException(nameof(value));\n            Index     = index;\n            EndIndex  = endIndex;\n            UserState = userState;\n            TokenPos  = tokenPos;\n        }\n\n        public Pos Pos =>\n            Value.Length == 0\n                ? Pos.Zero\n                : Index < Value.Length\n                    ? TokenPos(Value[Index])\n                    : TokenPos(Value[Value.Length - 1]);\n\n        public PString<T> SetValue(T[] value) =>\n            new PString<T>(value, Index, value.Length, UserState, TokenPos);\n\n        public PString<T> SetIndex(int index) =>\n            new PString<T>(Value, index, EndIndex, UserState, TokenPos);\n\n        public PString<T> SetUserState(object? state) =>\n            new PString<T>(Value, Index, EndIndex, state, TokenPos);\n\n        public PString<T> SetEndIndex(int endIndex) =>\n            new PString<T>(Value, Index, endIndex, UserState, TokenPos);\n\n        public override string ToString() =>\n            $\"{typeof(T).Name}({Index}, {EndIndex})\";\n\n        public static PString<T> Zero(Func<T, Pos> tokenPos) =>\n            new PString<T>(System.Array.Empty<T>(), 0, 0, None, tokenPos);\n\n        public PString<U> Cast<U>() where U : T =>\n            new PString<U>(Value.Cast<U>().ToArray(), Index, EndIndex, UserState, u => TokenPos((T)u));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Parsec.Internal.cs",
    "content": "﻿using System.Collections.Generic;\nusing LanguageExt.UnsafeValueAccess;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Common;\nusing static LanguageExt.Parsec.Prim;\nusing static LanguageExt.Parsec.ParserResult;\n\nnamespace LanguageExt.Parsec;\n\nstatic class Internal\n{\n    public static ParserResult<char> newstate(PString inp)\n    {\n        var x = inp.Value[inp.Index];\n\n        var newpos = x   == '\\n' ? new Pos(inp.Pos.Line + 1, 0)\n                     : x == '\\t' ? new Pos(inp.Pos.Line, ((inp.Pos.Column / 4) + 1) * 4)\n                                   : new Pos(inp.Pos.Line, inp.Pos.Column + 1);\n\n        return ConsumedOK(x,\n                          new PString(\n                              inp.Value,\n                              inp.Index + 1,\n                              inp.EndIndex,\n                              newpos,\n                              inp.DefPos,\n                              onside(newpos, inp.DefPos)\n                                  ? Sidedness.Onside\n                                  : Sidedness.Offside,\n                              inp.UserState));\n    }\n\n    /// <summary>\n    /// Imperative implementation of the choice parser, which in a non-stack \n    /// overflow utopia would look similar to this:\n    /// \n    ///     either(ps[index], choicei(ps, index + 1))\n    /// \n    /// </summary>\n    public static Parser<T> choicei<T>(Seq<Parser<T>> ps) =>\n        ps.IsEmpty\n            ? unexpected<T>(\"choice parser with no choices\")\n            : inp =>\n              {\n                  List<T>      results = new List<T>();\n                  ParserError? error   = null;\n\n                  foreach (var p in ps)\n                  {\n                      var t = p(inp);\n\n                      // cok\n                      if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                      {\n                          return t;\n                      }\n\n                      // eok\n                      if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                      {\n                          return EmptyOK(t.Reply.Result, t.Reply.State, mergeError(error, t.Reply.Error));\n                      }\n\n                      // cerr\n                      if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                      {\n                          return ConsumedError<T>(mergeError(error, t.Reply.Error));\n                      }\n\n                      error = mergeError(error, t.Reply.Error);\n                  }\n\n                  return EmptyError<T>(error);\n              };\n\n    /// <summary>\n    /// Imperative implementation of chain, which in a non-stack overflow utopia\n    /// would look similar to this:\n    /// \n    ///     from x in ps[index]\n    ///     from y in chaini(ps, index + 1)\n    ///     select x.Cons(y);\n    /// \n    /// </summary>\n    public static Parser<Seq<T>> chaini<T>(Seq<Parser<T>> ps) =>\n        ps.IsEmpty\n            ? unexpected<Seq<T>>(\"chain parser with 0 items\")\n            : inp =>\n              {\n                  if( ps.Count == 1)\n                  {\n                      return ps.Head.ValueUnsafe()!.Map(x => x.Cons())(inp);\n                  }\n\n                  var             current = inp;\n                  List<T>         results = new List<T>();\n                  ParserError     error   = null;\n                  ParserResult<T> last    = null;\n                  int             count   = ps.Count;\n\n                  foreach (var p in ps)\n                  {\n                      count--;\n                      var t = p(current);\n\n                      if( last == null)\n                      {\n                          // cerr\n                          if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                          {\n                              return ConsumedError<Seq<T>>(t.Reply.Error);\n                          }\n                          // eerr\n                          else if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.Error)\n                          {\n                              return EmptyError<Seq<T>>(t.Reply.Error);\n                          }\n                          // cok\n                          else if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                          {\n                              results.Add(t.Reply.Result);\n                              last    = t;\n                              error   = t.Reply.Error;\n                              current = t.Reply.State;\n                          }\n                          // eok\n                          else //if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                          {\n                              results.Add(t.Reply.Result);\n                              last  = t;\n                              error = t.Reply.Error;\n                          }\n                      }\n                      else\n                      {\n                          if (last.Tag == ResultTag.Consumed)\n                          {\n                              // cok, cerr\n                              if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                              {\n                                  return ConsumedError<Seq<T>>(t.Reply.Error);\n                              }\n                              // cok, eerr\n                              else if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.Error)\n                              {\n                                  return ConsumedError<Seq<T>>(mergeError(error, t.Reply.Error));\n                              }\n                              // cok, cok\n                              else if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                              {\n                                  if (count == 0)\n                                  {\n                                      results.Add(t.Reply.Result);\n                                      return ConsumedOK(toSeq(results), t.Reply.State, t.Reply.Error);\n                                  }\n                                  else\n                                  {\n                                      results.Add(t.Reply.Result);\n                                      last    = t;\n                                      error   = t.Reply.Error;\n                                      current = t.Reply.State;\n                                  }\n                              }\n                              // cok, eok\n                              else //if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                              {\n                                  if (count == 0)\n                                  {\n                                      // cok, eok -> cok  (not a typo, this should be -> cok)\n                                      results.Add(t.Reply.Result);\n                                      return ConsumedOK(toSeq(results), t.Reply.State, mergeError(error, t.Reply.Error));\n                                  }\n                                  else\n                                  {\n                                      results.Add(t.Reply.Result);\n                                      last  = t;\n                                      error = mergeError(error, t.Reply.Error);\n                                  }\n                              }\n                          }\n                          else if (last.Tag == ResultTag.Empty)\n                          {\n                              // eok, cerr\n                              if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                              {\n                                  return ConsumedError<Seq<T>>(t.Reply.Error);\n                              }\n                              // eok, eerr\n                              else if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.Error)\n                              {\n                                  return EmptyError<Seq<T>>(mergeError(error, t.Reply.Error));\n                              }\n                              // eok, cok\n                              else if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                              {\n                                  if (count == 0)\n                                  {\n                                      results.Add(t.Reply.Result);\n                                      return ConsumedOK(toSeq(results), t.Reply.State, t.Reply.Error);\n                                  }\n                                  else\n                                  {\n                                      results.Add(t.Reply.Result);\n                                      last    = t;\n                                      error   = t.Reply.Error;\n                                      current = t.Reply.State;\n                                  }\n                              }\n                              // eok, eok\n                              else //if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                              {\n                                  if (count == 0)\n                                  {\n                                      results.Add(t.Reply.Result);\n                                      return EmptyOK(toSeq(results), t.Reply.State, mergeError(error, t.Reply.Error));\n                                  }\n                                  else\n                                  {\n                                      results.Add(t.Reply.Result);\n                                      last  = t;\n                                      error = mergeError(error, t.Reply.Error);\n                                  }\n                              }\n                          }\n                      }\n                  }\n                  return ConsumedOK(toSeq(results), current, error);\n              };\n\n\n    public static Parser<Seq<T>> counti<T>(int n, Parser<T> p) =>\n        n <= 0\n            ? result(Seq<T>.Empty)\n            : from x in p\n              from y in counti(n -1, p)\n              select x.Cons(y);\n\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParsecIO.Internal.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.UnsafeValueAccess;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Common;\nusing static LanguageExt.Parsec.PrimIO;\nusing static LanguageExt.Parsec.ParserResultIO;\n\nnamespace LanguageExt.Parsec\n{\n    static class InternalIO\n    {\n        public static ParserResult<I, I> newstate<I>(PString<I> inp)\n        {\n            var x = inp.Value[inp.Index];\n\n            return ConsumedOK(x,\n                new PString<I>(\n                    inp.Value,\n                    inp.Index + 1,\n                    inp.EndIndex,\n                    inp.UserState,\n                    inp.TokenPos));\n        }\n\n        /// <summary>\n        /// Imperative implementation of the choice parser, which in a non-stack \n        /// overflow utopia would look similar to this:\n        /// \n        ///     either(ps[index], choicei(ps, index + 1))\n        /// \n        /// </summary>\n        public static Parser<I,O> choicei<I, O>(Seq<Parser<I, O>> ps) =>\n            ps.IsEmpty\n                ? unexpected<I, O>(\"choice parser with no choices\")\n                : inp =>\n            {\n                var results = new List<O>();\n                ParserError? error = null;\n\n                foreach (var p in ps)\n                {\n                    var t = p(inp);\n\n                    // cok\n                    if (t is { Tag: ResultTag.Consumed, Reply.Tag: ReplyTag.OK })\n                    {\n                        return t;\n                    }\n\n                    // eok\n                    if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                    {\n                        return EmptyOK<I, O>(t.Reply.Result!, t.Reply.State, mergeError(error, t.Reply.Error));\n                    }\n\n                    // cerr\n                    if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                    {\n                        return ConsumedError<I, O>(mergeError(error, t.Reply.Error), inp.TokenPos);\n                    }\n\n                    error = mergeError(error, t.Reply.Error);\n                }\n\n                return EmptyError<I, O>(error!, inp.TokenPos);\n            };\n\n        /// <summary>\n        /// Imperative implementation of chain, which in a non-stack overflow utopia\n        /// would look similar to this:\n        /// \n        ///     from x in ps[index]\n        ///     from y in chaini(ps, index + 1)\n        ///     select x.Cons(y);\n        /// \n        /// </summary>\n        public static Parser<I, Seq<O>> chaini<I, O>(Seq<Parser<I, O>> ps) =>\n            ps.IsEmpty\n                ? unexpected<I, Seq<O>>(\"chain parser with 0 items\")\n                : inp =>\n            {\n                if( ps.Count == 1)\n                {\n                    return ps.Head.ValueUnsafe()!.Map(x => x.Cons())(inp);\n                }\n\n                var current = inp;\n                var results = new List<O>();\n                ParserError error = null;\n                ParserResult<I,O> last = null;\n                int count = ps.Count;\n\n                foreach (var p in ps)\n                {\n                    count--;\n                    var t = p(current);\n\n                    if( last == null)\n                    {\n                        // cerr\n                        if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                        {\n                            return ConsumedError<I, Seq<O>>(t.Reply.Error, inp.TokenPos);\n                        }\n                        // eerr\n                        else if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.Error)\n                        {\n                            return EmptyError<I, Seq<O>>(t.Reply.Error, inp.TokenPos);\n                        }\n                        // cok\n                        else if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                        {\n                            results.Add(t.Reply.Result);\n                            last = t;\n                            error = t.Reply.Error;\n                            current = t.Reply.State;\n                        }\n                        // eok\n                        else //if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                        {\n                            results.Add(t.Reply.Result);\n                            last = t;\n                            error = t.Reply.Error;\n                        }\n                    }\n                    else\n                    {\n                        if (last.Tag == ResultTag.Consumed)\n                        {\n                            // cok, cerr\n                            if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                            {\n                                return ConsumedError<I, Seq<O>>(t.Reply.Error, inp.TokenPos);\n                            }\n                            // cok, eerr\n                            else if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.Error)\n                            {\n                                return ConsumedError<I, Seq<O>>(mergeError(error, t.Reply.Error), inp.TokenPos);\n                            }\n                            // cok, cok\n                            else if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                            {\n                                if (count == 0)\n                                {\n                                    results.Add(t.Reply.Result);\n                                    return ConsumedOK(toSeq(results), t.Reply.State, t.Reply.Error);\n                                }\n                                else\n                                {\n                                    results.Add(t.Reply.Result);\n                                    last = t;\n                                    error = t.Reply.Error;\n                                    current = t.Reply.State;\n                                }\n                            }\n                            // cok, eok\n                            else //if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                            {\n                                if (count == 0)\n                                {\n                                    // cok, eok -> cok  (not a typo, this should be -> cok)\n                                    results.Add(t.Reply.Result);\n                                    return ConsumedOK(toSeq(results), t.Reply.State, mergeError(error, t.Reply.Error));\n                                }\n                                else\n                                {\n                                    results.Add(t.Reply.Result);\n                                    last = t;\n                                    error = mergeError(error, t.Reply.Error);\n                                }\n                            }\n                        }\n                        else if (last.Tag == ResultTag.Empty)\n                        {\n                            // eok, cerr\n                            if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                            {\n                                return ConsumedError<I, Seq<O>>(t.Reply.Error, inp.TokenPos);\n                            }\n                            // eok, eerr\n                            else if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.Error)\n                            {\n                                return EmptyError<I, Seq<O>>(mergeError(error, t.Reply.Error), inp.TokenPos);\n                            }\n                            // eok, cok\n                            else if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                            {\n                                if (count == 0)\n                                {\n                                    results.Add(t.Reply.Result);\n                                    return ConsumedOK(toSeq(results), t.Reply.State, t.Reply.Error);\n                                }\n                                else\n                                {\n                                    results.Add(t.Reply.Result);\n                                    last = t;\n                                    error = t.Reply.Error;\n                                    current = t.Reply.State;\n                                }\n                            }\n                            // eok, eok\n                            else //if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                            {\n                                if (count == 0)\n                                {\n                                    results.Add(t.Reply.Result);\n                                    return EmptyOK(toSeq(results), t.Reply.State, mergeError(error, t.Reply.Error));\n                                }\n                                else\n                                {\n                                    results.Add(t.Reply.Result);\n                                    last = t;\n                                    error = mergeError(error, t.Reply.Error);\n                                }\n                            }\n                        }\n                    }\n                }\n                return ConsumedOK(toSeq(results), current, error);\n            };\n\n\n        public static Parser<I, Seq<O>> counti<I, O>(int n, Parser<I, O> p) =>\n           n <= 0\n                ? result<I, Seq<O>>(Seq<O>.Empty)\n                : from x in p\n                  from y in counti(n-1, p)\n                  select x.Cons(y);\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Parser.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing LanguageExt.Parsec;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Prim;\nusing static LanguageExt.Parsec.Common;\nusing static LanguageExt.Parsec.ParserResult;\nusing static LanguageExt.Parsec.ParserResultIO;\nusing System.Diagnostics;\n\nnamespace LanguageExt.Parsec\n{\n    /// <summary>\n    /// Parser delegate type - Parses an input PString and returns a ParserResult\n    /// </summary>\n    /// <typeparam name=\"T\">Parsed value result type</typeparam>\n    /// <param name=\"input\">Input string</param>\n    /// <returns>Parsed value or error report</returns>\n    public delegate ParserResult<T> Parser<T>(PString input);\n}\n\npublic static class ParserExtensions\n{\n    /// <summary>\n    /// A label for the parser\n    /// </summary>\n    /// <param name=\"expected\">What was expected</param>\n    public static Parser<T> label<T>(this Parser<T> p, string expected) =>\n        inp =>\n        {\n            var res = p(inp);\n            if (res.Tag == ResultTag.Consumed)\n            {\n                return res;\n            }\n            if (res.Reply.Tag == ReplyTag.Error)\n            {\n                return EmptyError<T>(ParserError.Expect(inp.Pos, res.Reply.Error?.Msg ?? \"<error>\", expected));\n            }\n            if (res.Reply.Error is null || res.Reply.Error.Tag == ParserErrorTag.Unknown)\n            {\n                return res;\n            }\n            else\n            {\n                return EmptyOK(res.Reply.Result!, res.Reply.State!, ParserError.Expect(inp.Pos, res.Reply.Error.Msg, expected));\n            }\n        };\n\n    public static ParserResult<T> Parse<T>(this Parser<T> self, PString input) =>\n        self(input);\n\n    public static ParserResult<T> Parse<T>(this Parser<T> self, string input) =>\n        self(PString.Zero.SetValue(input));\n\n    public static Parser<T> Filter<T>(this Parser<T> self, Func<T, bool> pred) =>\n        self.Where(pred);\n\n    public static Parser<T> Where<T>(this Parser<T> self, Func<T, bool> pred) =>\n        inp =>\n            self(inp).Match(\n                EmptyOK: (x, rem, msg) => pred(x) ? EmptyOK(x, rem, msg) : EmptyError<T>(ParserError.SysUnexpect(inp.Pos, $\"\\\"{x}\\\"\")),\n                EmptyError: EmptyError<T>,\n                ConsumedOK: (x, rem, msg) => pred(x) ? ConsumedOK(x, rem, msg) : EmptyError<T>(ParserError.SysUnexpect(inp.Pos, $\"\\\"{x}\\\"\")),\n                ConsumedError: ConsumedError<T>);\n\n    public static Parser<U> Map<T, U>(this Parser<T> self, Func<T, U> map) =>\n        self.Select(map);\n\n    public static Parser<U> Select<T, U>(this Parser<T> self, Func<T, U> map) =>\n        inp => self(inp).Select(map);\n\n    public static Parser<B> Bind<A, B>(this Parser<A> self, Func<A, Parser<B>> f) =>\n        self.SelectMany(f);\n \n    public static Parser<B> SelectMany<A, B>(\n        this Parser<A> self,\n        Func<A, Parser<B>> f) =>\n        inp =>\n        {\n            Debug.Assert(inp != null);\n\n            var t = self(inp);\n\n            // cok\n            if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n            {\n                return f(t.Reply.Result)(t.Reply.State);\n            }\n\n            // eok\n            if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n            {\n                return f(t.Reply.Result)(t.Reply.State);\n            }\n\n            // cerr\n            if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n            {\n                return ConsumedError<B>(t.Reply.Error);\n            }\n\n            // eerr\n            return EmptyError<B>(t.Reply.Error);\n        };\n\n    public static Parser<V> SelectMany<T, U, V>(\n        this Parser<T> self,\n        Func<T, Parser<U>> bind,\n        Func<T, U, V> project) =>\n            inp =>\n            {\n                Debug.Assert(inp != null);\n\n                var t = self(inp);\n\n                // cok\n                if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                {\n                    var u = bind(t.Reply.Result)(t.Reply.State);\n\n                    if (u.Tag == ResultTag.Consumed && u.Reply.Tag == ReplyTag.OK)\n                    {\n                        // cok, cok -> cok\n                        var v = project(t.Reply.Result, u.Reply.Result);\n                        return ConsumedOK(v, u.Reply.State, u.Reply.Error);\n                    }\n\n                    if (u.Tag == ResultTag.Consumed && u.Reply.Tag == ReplyTag.Error)\n                    {\n                        // cok, cerr -> cerr\n                        return ConsumedError<V>(u.Reply.Error);\n                    }\n\n                    if (u.Tag == ResultTag.Empty && u.Reply.Tag == ReplyTag.OK)\n                    {\n                        // cok, eok -> cok  (not a typo, this should be -> cok)\n                        var v = project(t.Reply.Result, u.Reply.Result);\n                        return ConsumedOK(v, u.Reply.State, mergeError(t.Reply.Error, u.Reply.Error));\n                    }\n\n                    // cok, eerr\n                    return ConsumedError<V>(mergeError(t.Reply.Error, u.Reply.Error));\n                }\n\n                // eok\n                if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                {\n                    var u = bind(t.Reply.Result)(t.Reply.State);\n\n                    if (u.Tag == ResultTag.Consumed && u.Reply.Tag == ReplyTag.OK)\n                    {\n                        // eok, cok -> cok\n                        var v = project(t.Reply.Result, u.Reply.Result);\n                        return ConsumedOK(v, u.Reply.State, u.Reply.Error);\n                    }\n\n                    if (u.Tag == ResultTag.Empty && u.Reply.Tag == ReplyTag.OK)\n                    {\n                        // eok, eok -> eok\n                        var v = project(t.Reply.Result, u.Reply.Result);\n                        return EmptyOK(v, u.Reply.State, mergeError(t.Reply.Error, u.Reply.Error));\n                    }\n\n                    if (u.Tag == ResultTag.Consumed && u.Reply.Tag == ReplyTag.Error)\n                    {\n                        // eok, cerr -> cerr\n                        return ConsumedError<V>(u.Reply.Error);\n                    }\n\n                    // eok, eerr\n                    return EmptyError<V>(mergeError(t.Reply.Error, u.Reply.Error));\n                }\n\n                // cerr\n                if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                {\n                    return ConsumedError<V>(t.Reply.Error);\n                }\n\n                // eerr\n                return EmptyError<V>(t.Reply.Error);\n            };\n\n    public static Parser<A> Flatten<A>(this Parser<Parser<A>> mma) =>\n        mma.Bind(identity);\n \n    public static Parser<T> Flatten<T>(this Parser<Option<T>> p, Func<string> failureText) =>\n        from value in p\n        from returnValue in value.Match(result, compose(failureText, failure<T>))\n        select returnValue;\n\n    public static Parser<R> Flatten<L, R>(this Parser<Either<L, R>> p, Func<L, string> failureText) =>\n        from value in p\n        from returnValue in value.Match(compose(failureText, failure<R>), result)\n        select returnValue;\n    \n    public static Parser<R> Flatten<R>(this Parser<Either<string,R>> p) => Flatten(p, identity);\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParserError.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing LanguageExt.UnsafeValueAccess;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Parsec;\n\npublic enum ParserErrorTag\n{\n    Unknown     = 0, // numbered because the\n    SysUnexpect = 1, // order is important\n    Unexpect    = 2,\n    Expect      = 3,\n    Message     = 4\n}\n\npublic class ParserError : IEquatable<ParserError>, IComparable<ParserError>\n{\n    public readonly ParserErrorTag Tag;\n    public readonly Pos Pos;\n    public readonly string Msg;\n    public readonly Lst<string> Expected;\n    public readonly ParserError? Inner;\n\n    public ParserError(ParserErrorTag tag, Pos pos, string message, Lst<string> expected, ParserError? inner = null)\n    {\n        Tag = tag;\n        Pos = pos;\n        Msg = message;\n        Expected = expected;\n        Inner = inner;\n    }\n\n    public static ParserError Unknown(Pos pos) =>\n        new ParserError(ParserErrorTag.Unknown, pos, \"\", List.empty<string>());\n\n    public static ParserError SysUnexpect(Pos pos, string message) =>\n        new ParserError(ParserErrorTag.SysUnexpect, pos, message, List.empty<string>());\n\n    public static ParserError Unexpect(Pos pos, string message) =>\n        new ParserError(ParserErrorTag.Unexpect, pos, message, List.empty<string>());\n\n    public static ParserError Expect(Pos pos, string message, string expected) =>\n        new ParserError(ParserErrorTag.Expect, pos, message, List.create(expected));\n\n    public static ParserError Message(Pos pos, string message) =>\n        new ParserError(ParserErrorTag.Message, pos, message, List.empty<string>());\n\n    private static string FormatExpects(Lst<string> expects) =>\n        expects.Count == 0\n            ? \"\"\n            : expects.Count == 1\n                ? $\"expecting {expects.Head.ValueUnsafe()}\"\n                : $\"expecting {string.Join(\", \", expects.Take(expects.Count - 1))} or {expects.Last.ValueUnsafe()}\";\n\n    public override string ToString() =>\n        $\"error at {Pos}: {ToStringNoPosition()}\";\n\n    public string ToStringNoPosition() =>\n        (Tag == ParserErrorTag.Unexpect ? $\"unexpected {Msg}\"\n         : Tag == ParserErrorTag.SysUnexpect ? $\"unexpected {Msg}\"\n         : Tag == ParserErrorTag.Message ? Msg\n         : Tag == ParserErrorTag.Expect ? $\"unexpected {Msg}, {FormatExpects(Expected.Filter(x => !string.IsNullOrEmpty(x)).Distinct().AsIterable().ToLst())}\"\n                                          : \"unknown error\");\n\n    public bool Equals(ParserError? other) =>\n        other is not null && Tag == other.Tag && Msg == other.Msg;\n\n    public override bool Equals(object? obj) =>\n        ((obj as ParserError)?.Equals(this)).GetValueOrDefault();\n\n    public override int GetHashCode() =>\n        (Tag,Pos,Msg).GetHashCode();\n\n    public int CompareTo(ParserError? other) =>\n        Tag.CompareTo(other?.Tag);\n\n    public static bool operator ==(ParserError lhs, ParserError rhs) =>\n        isnull(lhs) && isnull(rhs) || (!isnull(lhs) && !isnull(rhs) && !lhs.Equals(rhs));\n\n    public static bool operator !=(ParserError lhs, ParserError rhs) =>\n        !(lhs == rhs);\n\n    public static bool operator <(ParserError lhs, ParserError rhs) =>\n        lhs.CompareTo(rhs) < 0;\n\n    public static bool operator >(ParserError lhs, ParserError rhs) =>\n        lhs.CompareTo(rhs) > 0;\n\n    public static bool operator <=(ParserError lhs, ParserError rhs) =>\n        lhs.CompareTo(rhs) <= 0;\n\n    public static bool operator >=(ParserError lhs, ParserError rhs) =>\n        lhs.CompareTo(rhs) >= 0;\n\n    public static R Compare<R>(\n        ParserError lhs,\n        ParserError rhs,\n        Func<R> EQ,\n        Func<R> GT,\n        Func<R> LT\n        )\n    {\n        var res = lhs.CompareTo(rhs);\n        if (res < 0)\n        {\n            return LT();\n        }\n        if (res > 0)\n        {\n            return GT();\n        }\n        return EQ();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParserIO.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Collections.Generic;\nusing LanguageExt;\nusing LanguageExt.Parsec;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Prim;\nusing static LanguageExt.Parsec.Common;\nusing static LanguageExt.Parsec.ParserResultIO;\nusing System.Diagnostics;\n\nnamespace LanguageExt.Parsec\n{\n    /// <summary>\n    /// Parser delegate type - Parses an input PString and returns a ParserResult\n    /// </summary>\n    /// <typeparam name=\"I\">Input stream element type</typeparam>\n    /// <typeparam name=\"O\">Parsed value result type</typeparam>\n    /// <param name=\"input\">Input string</param>\n    /// <returns>Parsed value or error report</returns>\n    public delegate ParserResult<I, O> Parser<I, O>(PString<I> input);\n}\n\npublic static class ParserIOExtensions\n{\n    /// <summary>\n    /// A label for the parser\n    /// </summary>\n    /// <param name=\"expected\">What was expected</param>\n    public static Parser<I, O> label<I, O>(this Parser<I, O> p, string expected) =>\n        inp =>\n        {\n            var res = p(inp);\n            if (res.Tag == ResultTag.Consumed)\n            {\n                return res;\n            }\n            if (res.Reply.Tag == ReplyTag.Error)\n            {\n                return EmptyError<I, O>(ParserError.Expect(inp.Pos, res.Reply.Error?.Msg ?? \"<error>\", expected), inp.TokenPos);\n            }\n            if (res.Reply.Error is null || res.Reply.Error.Tag == ParserErrorTag.Unknown)\n            {\n                return res;\n            }\n            else\n            {\n                return EmptyOK(res.Reply.Result!, res.Reply.State, ParserError.Expect(inp.Pos, res.Reply.Error.Msg, expected));\n            }\n        };\n\n    public static ParserResult<I, O> Parse<I, O>(this Parser<I, O> self, PString<I> input) =>\n        self(input);\n\n    public static ParserResult<I, O> Parse<I, O>(this Parser<I, O> self, Seq<I> input, Func<I, Pos> tokenPos) =>\n        self(PString<I>.Zero(tokenPos).SetValue(input.ToArray()));\n\n    public static ParserResult<I, O> Parse<I, O>(this Parser<I, O> self, IEnumerable<I> input, Func<I, Pos> tokenPos) =>\n        self(PString<I>.Zero(tokenPos).SetValue(input.ToArray()));\n\n    public static Parser<I, O> Filter<I, O>(this Parser<I, O> self, Func<O, bool> pred) =>\n        self.Where(pred);\n\n    public static Parser<I, O> Where<I, O>(this Parser<I, O> self, Func<O, bool> pred) =>\n        inp =>\n            self(inp).Match(\n                EmptyOK: (x, rem, msg) => pred(x) ? EmptyOK(x, rem, msg) : EmptyError<I, O>(ParserError.SysUnexpect(inp.Pos, $\"\\\"{x}\\\"\"), inp.TokenPos),\n                EmptyError: msg => EmptyError<I, O>(msg, inp.TokenPos),\n                ConsumedOK: (x, rem, msg) => pred(x) ? ConsumedOK(x, rem, msg) : EmptyError<I, O>(ParserError.SysUnexpect(inp.Pos, $\"\\\"{x}\\\"\"), inp.TokenPos),\n                ConsumedError: msg => ConsumedError<I, O>(msg, inp.TokenPos));\n\n    public static Parser<I, U> Map<I, O, U>(this Parser<I, O> self, Func<O, U> map) =>\n        self.Select(map);\n\n    public static Parser<I, U> Select<I, O, U>(this Parser<I, O> self, Func<O, U> map) =>\n        inp => self(inp).Select(map);\n    \n    public static Parser<I, B> Bind<I, A, B>(this Parser<I, A> self, Func<A, Parser<I, B>> f) =>\n        self.SelectMany(f);\n \n    public static Parser<I, B> SelectMany<I, A, B>(\n        this Parser<I, A> self,\n        Func<A, Parser<I, B>> f) =>\n        inp =>\n        {\n            Debug.Assert(inp != null);\n\n            var t = self(inp);\n\n            // cok\n            if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n            {\n                return f(t.Reply.Result)(t.Reply.State);\n            }\n\n            // eok\n            if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n            {\n                return f(t.Reply.Result)(t.Reply.State);\n            }\n\n            // cerr\n            if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n            {\n                return ConsumedError<I, B>(t.Reply.Error, inp.TokenPos);\n            }\n\n            // eerr\n            return EmptyError<I, B>(t.Reply.Error, inp.TokenPos);\n        };    \n\n    public static Parser<I, V> SelectMany<I, O, U, V>(\n        this Parser<I, O> self,\n        Func<O, Parser<I, U>> bind,\n        Func<O, U, V> project) =>\n            inp =>\n            {\n                Debug.Assert(inp != null);\n\n                var t = self(inp);\n\n                // cok\n                if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                {\n                    var u = bind(t.Reply.Result)(t.Reply.State);\n\n                    if (u.Tag == ResultTag.Consumed && u.Reply.Tag == ReplyTag.OK)\n                    {\n                        // cok, cok -> cok\n                        var v = project(t.Reply.Result, u.Reply.Result);\n                        return ConsumedOK(v, u.Reply.State, u.Reply.Error);\n                    }\n\n                    if (u.Tag == ResultTag.Consumed && u.Reply.Tag == ReplyTag.Error)\n                    {\n                        // cok, cerr -> cerr\n                        return ConsumedError<I, V>(u.Reply.Error, inp.TokenPos);\n                    }\n\n                    if (u.Tag == ResultTag.Empty && u.Reply.Tag == ReplyTag.OK)\n                    {\n                        // cok, eok -> cok  (not a typo, this should be -> cok)\n                        var v = project(t.Reply.Result, u.Reply.Result);\n                        return ConsumedOK(v, u.Reply.State, mergeError(t.Reply.Error, u.Reply.Error));\n                    }\n\n                    // cok, eerr\n                    return ConsumedError<I, V>(mergeError(t.Reply.Error, u.Reply.Error), inp.TokenPos);\n                }\n\n                // eok\n                if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                {\n                    var u = bind(t.Reply.Result)(t.Reply.State);\n\n                    if (u.Tag == ResultTag.Consumed && u.Reply.Tag == ReplyTag.OK)\n                    {\n                        // eok, cok -> cok\n                        var v = project(t.Reply.Result, u.Reply.Result);\n                        return ConsumedOK(v, u.Reply.State, u.Reply.Error);\n                    }\n\n                    if (u.Tag == ResultTag.Empty && u.Reply.Tag == ReplyTag.OK)\n                    {\n                        // eok, eok -> eok\n                        var v = project(t.Reply.Result, u.Reply.Result);\n                        return EmptyOK(v, u.Reply.State, mergeError(t.Reply.Error, u.Reply.Error));\n                    }\n\n                    if (u.Tag == ResultTag.Consumed && u.Reply.Tag == ReplyTag.Error)\n                    {\n                        // eok, cerr -> cerr\n                        return ConsumedError<I, V>(u.Reply.Error, inp.TokenPos);\n                    }\n\n                    // eok, eerr\n                    return EmptyError<I, V>(mergeError(t.Reply.Error, u.Reply.Error), inp.TokenPos);\n                }\n\n                // cerr\n                if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                {\n                    return ConsumedError<I, V>(t.Reply.Error, inp.TokenPos);\n                }\n\n                // eerr\n                return EmptyError<I, V>(t.Reply.Error, inp.TokenPos);\n            };\n    \n    public static Parser<I, A> Flatten<I, A>(this Parser<I, Parser<I, A>> mma) =>\n        mma.Bind(identity);\n \n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParserIOs/Expr.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.PrimIO;\n\nnamespace LanguageExt.Parsec;\n\npublic static class ExprIO\n{\n    /// <summary>\n    ///  Convert an OperatorTable and basic term parser into a fully fledged \n    ///  expression parser\n    /// \n    ///  buildExpressionParser(table,term) builds an expression parser for\n    ///  terms term with operators from table, taking the associativity\n    ///  and precedence specified in table into account.  Prefix and postfix\n    ///  operators of the same precedence can only occur once (i.e. --2 is\n    ///  not allowed if '-' is prefix negate).  Prefix and postfix operators\n    ///  of the same precedence associate to the left  (i.e. if ++ is\n    ///  postfix increment, than -2++ equals -1, not -3).\n    /// \n    ///  The buildExpressionParser function takes care of all the complexity\n    ///  involved in building expression parser.\n    ///  \n    ///  See remarks.\n    ///  </summary>\n    ///  <example>\n    ///  This is an example of an expression parser that handles prefix signs, \n    ///  postfix increment and basic arithmetic.\n    /// \n    ///    Parser〈int〉 expr = null;\n    /// \n    ///    var binary = fun((string name, Func〈int, int, int〉 f, Assoc assoc) =〉\n    ///         Operator.Infix〈int〉( assoc,\n    ///                              from x in reservedOp(name)\n    ///                              select fun );\n    ///                              \n    ///    var prefix = fun((string name, Func〈int, int〉 f) =〉\n    ///         Operator.Prefix〈int〉(from x in reservedOp(name)\n    ///                              select fun );\n    /// \n    ///    var postfix = fun((string name, Func〈int, int〉 f) =〉\n    ///         Operator.Postfix〈int〉(from x in reservedOp(name)\n    ///                               select fun );\n    ///         \n    ///    Operator〈int〉[][] table = [ [ prefix(\"-\",negate), prefix(\"+\",id) ]\n    ///                               , [ postfix(\"++\", incr) ]\n    ///                               , [ binary(\"*\", mult) Assoc.Left), binary(\"/\", div, Assoc.Left) ]\n    ///                               , [ binary(\"+\", add, Assoc.Left), binary(\"-\", subtr, Assoc.Left) ] ];\n    ///              \n    ///    var term              = either(parens(expr),natural).label(\"simple expression\")\n    ///            \n    ///    expr                  = buildExpressionParser(table,term).label(\"expression\")\n    ///    \n    ///    var res = parse(expr, \"(50 + 20) / 2\");\n    /// </example>\n    public static Parser<I, O> buildExpressionParser<I, O>(\n        Operator<I, O>[][] operators,\n        Parser<I, O> simpleExpr) =>\n        operators.AsIterable().FoldBack(\n            simpleExpr, \n            (term, ops) => makeParser(ops, term));\n\n    static Parser<I, O> makeParser<I, O>(\n        Operator<I, O>[] ops,\n        Parser<I, O> term)\n    {\n        var e3 = Seq.empty<Parser<I, Func<O,O,O>>>();\n        var e2 = Seq.empty<Parser<I, Func<O,O>>>();\n\n        return ops.AsIterable()\n                  .Fold((e3, e3, e3, e2, e2), (state, op) => op.SplitOp(state))\n                  .Map((rassoc, lassoc, nassoc, prefix, postfix) =>\n                       {\n                           var rassocOp  = choice(rassoc);\n                           var lassocOp  = choice(lassoc);\n                           var nassocOp  = choice(nassoc);\n                           var prefixOp  = choice(prefix).label(\"\");\n                           var postfixOp = choice(postfix).label(\"\");\n\n                           var ambigious = fun((string assoc, Parser<I, Func<O, O, O>> op) =>\n                                                   attempt(\n                                                       from x in op\n                                                       from y in failure<I, O>($\"ambiguous use of a {assoc} associative operator\")\n                                                       select y));\n\n                           var ambigiousRight = ambigious(\"right\", rassocOp);\n                           var ambigiousLeft  = ambigious(\"left\", lassocOp);\n                           var ambigiousNon   = ambigious(\"non\", nassocOp);\n\n                           var postfixP = either(postfixOp, result<I, Func<O, O>>(x => x));\n\n                           var prefixP = either(prefixOp, result<I, Func<O,O>>(x => x));\n\n                           var termP = from pre in prefixP\n                                       from x in term\n                                       from post in postfixP\n                                       select post(pre(x));\n\n                           Func<O, Parser<I, O>> rassocP  = null;\n                           Func<O, Parser<I, O>> rassocP1 = null;\n\n                           rassocP1 = fun((O x) => either(rassocP(x), result<I, O>(x)));\n\n                           rassocP = fun((O x) =>\n                                             choice(\n                                                 from f in rassocOp\n                                                 from y in (from z in termP\n                                                            from z1 in rassocP1(z)\n                                                            select z1)\n                                                 select f(x, y),\n                                                 ambigiousLeft,\n                                                 ambigiousNon));\n\n                           Func<O, Parser<I, O>> lassocP  = null;\n                           Func<O, Parser<I, O>> lassocP1 = null;\n\n                           lassocP1 = fun((O x) => either(lassocP(x), result<I, O>(x)));\n\n                           lassocP = fun((O x) =>\n                                             choice(\n                                                 from f in lassocOp\n                                                 from y in termP\n                                                 from r in lassocP1(f(x, y))\n                                                 select r,\n                                                 ambigiousRight,\n                                                 ambigiousNon));\n\n                           var nassocP = fun((O x) =>\n                                                 from f in nassocOp\n                                                 from y in termP\n                                                 from r in choice(ambigiousRight, ambigiousLeft, ambigiousNon, result<I, O>(f(x, y)))\n                                                 select r);\n\n                           return from x in termP\n                                  from r in choice(rassocP(x), lassocP(x), nassocP(x), result<I, O>(x)).label(\"operator\")\n                                  select r;\n                       });\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParserIOs/Indent.cs",
    "content": "using System;\n\nnamespace LanguageExt.Parsec\n{\n    public static class IndentIO\n    {\n        /// <summary>\n        /// Parses only when indented past the level of the reference\n        /// </summary>\n        /// <remarks>\n        /// You must have provided a TokenPos to the initial PString〈TOKEN〉 that gives accurate\n        /// column and line values for this function to work.\n        /// </remarks>\n        public static Parser<TOKEN, A> indented<TOKEN, A>(int offset, Parser<TOKEN, A> p) =>\n            inp =>\n            {\n                var pos   = inp.Pos;\n                var col   = pos.Column + offset;\n                var ln    = pos.Line;\n                var toks  = inp.Value;\n                var ix    = inp.Index;\n                var start = inp.Index;\n                var tpos  = inp.TokenPos;\n\n                for (; ix < inp.EndIndex; ix++)\n                {\n                    var npos = tpos(toks[ix]);\n                    if (npos.Line != ln && npos.Column < col)\n                    {\n                        break;\n                    }\n                }\n\n                return parseBlock(p, start, ix, inp);                \n            };\n\n        /// <summary>\n        /// Parses only when indented zero or more characters past the level of the reference\n        /// </summary>\n        /// <remarks>\n        /// You must have provided a TokenPos to the initial PString〈TOKEN〉 that gives accurate\n        /// column and line values for this function to work.\n        /// </remarks>\n        public static Parser<TOKEN, A> indented<TOKEN, A>(Parser<TOKEN, A> p) =>\n            indented(0, p);\n\n        /// <summary>\n        /// Parses only when indented one or more characters past the level of the reference\n        /// </summary>\n        /// <remarks>\n        /// You must have provided a TokenPos to the initial PString〈TOKEN〉 that gives accurate\n        /// column and line values for this function to work.\n        /// </remarks>\n        public static Parser<TOKEN, A> indented1<TOKEN, A>(Parser<TOKEN, A> p) =>\n            indented(1, p);\n\n        /// <summary>\n        /// Parses only when indented two or more characters past the level of the reference\n        /// </summary>\n        /// <remarks>\n        /// You must have provided a TokenPos to the initial PString〈TOKEN〉 that gives accurate\n        /// column and line values for this function to work.\n        /// </remarks>\n        public static Parser<TOKEN, A> indented2<TOKEN, A>(Parser<TOKEN, A> p) =>\n            indented(2, p);\n\n        /// <summary>\n        /// Parses only when indented four or more characters past the level of the reference\n        /// </summary>\n        /// <remarks>\n        /// You must have provided a TokenPos to the initial PString〈TOKEN〉 that gives accurate\n        /// column and line values for this function to work.\n        /// </remarks>\n        public static Parser<TOKEN, A> indented4<TOKEN, A>(Parser<TOKEN, A> p) =>\n            indented(4, p);\n\n        /// <summary>\n        /// Sets a new context for the parser p which represents a span of the input tokens\n        /// </summary>\n        /// <remarks>\n        /// The parse fails if it doesn't consume all tokens in the block\n        /// </remarks>\n        static ParserResult<TOKEN, A> parseBlock<TOKEN, A>(Parser<TOKEN, A> p, int start, int end, PString<TOKEN> inp)\n        {\n            var pstr = new PString<TOKEN>(inp.Value, start, end, inp.UserState, inp.TokenPos);\n            var pres = p.Parse(pstr);\n            \n            return new ParserResult<TOKEN, A>(\n                      pres.Tag,\n                      new Reply<TOKEN, A>(\n                          pres.Reply.Tag,\n                          pres.Reply.Result!,\n                          new PString<TOKEN>(inp.Value, pres.Reply.State.Index, inp.EndIndex, pres.Reply.State.UserState, pres.Reply.State.TokenPos),\n                          pres.Reply.Error!));\n        }  \n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParserIOs/Item.cs",
    "content": "﻿using System;\nusing static LanguageExt.Parsec.ParserResultIO;\nusing static LanguageExt.Parsec.InternalIO;\nusing static LanguageExt.Parsec.PrimIO;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Parsec\n{\n    /// <summary>\n    /// Commonly used character parsers.\n    /// </summary>\n    public static class ItemIO\n    {\n        /// <summary>\n        /// item(c) parses a single I\n        /// </summary>\n        /// <returns>The parsed character</returns>\n        public static Parser<A, A> item<A>(A c) =>\n            satisfy<A>(x => EqDefault<A>.Equals(x,c)).label($\"'{c}'\");\n\n        /// <summary>\n        /// The parser satisfy(pred) succeeds for any character for which the\n        /// supplied function pred returns 'True'. \n        /// </summary>\n        /// <returns>\n        /// The character that is actually parsed.</returns>\n        public static Parser<A, A> satisfy<A>(Func<A, bool> pred) =>\n            inp =>\n            {\n                if (inp.Index >= inp.EndIndex)\n                {\n                    return EmptyError<A, A>(ParserError.SysUnexpect(inp.Pos, \"end of stream\"), inp.TokenPos);\n                }\n                else\n                {\n                    var ns = newstate(inp);\n\n                    if (ns.Tag == ResultTag.Consumed)\n                    {\n                        if (pred(ns.Reply.Result!))\n                        {\n                            return ns;\n                        }\n                        else\n                        {\n                            return EmptyError<A, A>(ParserError.SysUnexpect(inp.Pos, $\"\\\"{ns.Reply.Result}\\\"\"), inp.TokenPos);\n                        }\n                    }\n                    else\n                    {\n                        return EmptyError<A, A>(ParserError.SysUnexpect(inp.Pos, \"end of stream\"), inp.TokenPos);\n                    }\n                }\n            };\n\n        /// <summary>\n        /// oneOf(str) succeeds if the current character is in the supplied list of \n        /// characters str. Returns the parsed character. See also satisfy\n        /// </summary>\n        public static Parser<A, A> oneOf<A>(Seq<A> str) =>\n            satisfy<A>(a => str.Exists(b => EqDefault<A>.Equals(a, b)));\n\n        /// <summary>\n        /// As the dual of 'oneOf', noneOf(str) succeeds if the current\n        /// character not in the supplied list of characters str. \n        /// \n        ///     var consonant = noneOf(\"aeiou\")\n        /// </summary>\n        /// <returns>\n        /// The parsed character.</returns>\n        public static Parser<A, A> noneOf<A>(Seq<A> str) =>\n            satisfy<A>(a => str.ForAll(b => !EqDefault<A>.Equals(a, b)));\n\n        /// <summary>\n        /// The parser anyChar accepts any kind of character.\n        /// </summary>\n        public static Parser<A, A> anyItem<A>() =>\n            satisfy<A>(_ => true);\n\n        /// <summary>\n        /// Parse a string\n        /// </summary>\n        public static Parser<A, Seq<A>> str<A>(Seq<A> s) =>\n            chain(s.Map(item));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParserIOs/Prim.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Common;\nusing static LanguageExt.Parsec.InternalIO;\nusing static LanguageExt.Parsec.ItemIO;\nusing static LanguageExt.Parsec.ParserResultIO;\n\nnamespace LanguageExt.Parsec\n{\n    /// <summary>\n    /// The primitive parser combinators\n    /// </summary>\n    public static class PrimIO\n    {\n        /// <summary>\n        /// Run the parser p with the input provided\n        /// </summary>\n        public static ParserResult<I, O> parse<I, O>(Parser<I, O> p, PString<I> input) =>\n            p.Parse(input);\n\n        /// <summary>\n        /// Run the parser p with the input provided\n        /// </summary>\n        public static ParserResult<I, O> parse<I, O>(Parser<I, O> p, Seq<I> input, Func<I, Pos> tokenPos) =>\n            p.Parse(input, tokenPos);\n\n        /// <summary>\n        /// Lazy parser - useful in recursive scenarios.\n        /// </summary>\n        public static Parser<I, O> lazyp<I, O>(Func<Parser<I, O>> fn) =>\n            inp => fn()(inp);\n\n        /// <summary>\n        /// This parser is useful to put at the top of LINQ expressions, it\n        /// makes it easier to put breakpoints on the actual first parser\n        /// in an expression.  It returns unit\n        /// </summary>\n        public static Parser<I, Unit> unitp<I>() =>\n            inp => EmptyOK(unit, inp);\n\n        /// <summary>\n        /// Special parser for setting user-state that propagates \n        /// through the computation.\n        /// </summary>\n        public static Parser<I, Unit> setState<I, S>(S state) =>\n            inp => ConsumedOK(unit, inp.SetUserState(state));\n\n        /// <summary>\n        /// Special parser for getting user-state that was previously\n        /// set with setState\n        /// </summary>\n        public static Parser<I, S> getState<I, S>() =>\n            inp =>\n                match(inp.UserState,\n                    Some: x => x is S\n                        ? ConsumedOK((S)x, inp)\n                        : EmptyError<I, S>(ParserError.Message(inp.Pos, \"User state type-mismatch\"), inp.TokenPos),\n                    None: () => EmptyError<I, S>(ParserError.Message(inp.Pos, \"No user state set\"), inp.TokenPos));\n\n        /// <summary>\n        /// Get the current position of the parser in the source as a line\n        /// and column index (starting at 1 for both)\n        /// </summary>\n        public static Parser<I, Pos> getPos<I>() =>\n            (PString<I> inp) => ConsumedOK(inp.Pos, inp);\n\n        /// <summary>\n        /// Get the current index into the source\n        /// </summary>\n        public static Parser<I, int> getIndex<I>() =>\n            (PString<I> inp) => ConsumedOK(inp.Index, inp);\n\n        /// <summary>\n        /// The parser unexpected(msg) always fails with an Unexpect error\n        /// message msg without consuming any input.\n        /// </summary>\n        /// <remarks>\n        /// The parsers 'failure', 'label' and 'unexpected' are the three parsers\n        /// used to generate error messages.  Of these, only 'label' is commonly\n        /// used.  For an example of the use of unexpected, see the definition\n        /// of 'notFollowedBy'.\n        /// </remarks>\n        /// <param name=\"msg\">Error message to use when parsed</param>\n        public static Parser<I, O> unexpected<I, O>(string msg) =>\n            inp => EmptyError<I, O>(ParserError.Unexpect(inp.Pos, msg), inp.TokenPos);\n\n        /// <summary>\n        /// The parser failure(msg) always fails with a Message error\n        /// without consuming any input.\n        /// \n        /// The parsers 'failure', 'label' and 'unexpected' are the three parsers\n        /// used to generate error messages.  Of these, only 'label' is commonly\n        /// used.  For an example of the use of unexpected, see the definition\n        /// of 'notFollowedBy'.\n        /// </summary>\n        /// <param name=\"msg\">Error message to use when parsed</param>\n        public static Parser<I, O> failure<I, O>(string msg) =>\n            inp => EmptyError<I, O>(ParserError.Message(inp.Pos, msg), inp.TokenPos);\n\n        /// <summary>\n        /// Always success parser.  Returns the value provided.  \n        /// This is monad return for the Parser monad\n        /// </summary>\n        public static Parser<I, O> result<I, O>(O value) =>\n            inp => EmptyOK(value, inp);\n\n        /// <summary>\n        /// Always fails (with an Unknown error) without consuming any input\n        /// </summary>\n        public static Parser<I, O> zero<I, O>() =>\n            inp => EmptyError<I, O>(ParserError.Unknown(inp.Pos), inp.TokenPos);\n\n        /// <summary>\n        /// This combinator implements choice. The parser either(p,q) first\n        /// applies p.  If it succeeds, the value of p is returned.  If p\n        /// fails /without consuming any input/, parser q is tried.  \n        /// </summary>\n        /// <remarks>\n        /// This combinator is the mplus behaviour of the Parser monad.\n        /// \n        /// The parser is called /predictive/ since q is only tried when\n        /// parser p didn't consume any input (i.e.. the look ahead is 1).\n        /// \n        /// This non-backtracking behaviour allows for both an efficient\n        /// implementation of the parser combinators and the generation of good\n        /// error messages.\n        /// </remarks>\n        public static Parser<I, O> either<I, O>(Parser<I, O> p, Parser<I, O> q) =>\n            inp =>\n            {\n                var m = p(inp);\n\n                // meerr\n                if (m.Tag == ResultTag.Empty && m.Reply.Tag == ReplyTag.Error)\n                {\n                    var n = q(inp);\n\n                    // neok\n                    if (n.Tag == ResultTag.Empty && n.Reply.Tag == ReplyTag.OK)\n                    {\n                        return EmptyOK(n.Reply.Result, n.Reply.State, mergeError(m.Reply.Error, n.Reply.Error));\n                    }\n\n                    // nerr\n                    if (n.Tag == ResultTag.Empty && n.Reply.Tag == ReplyTag.Error)\n                    {\n                        return EmptyError<I, O>(mergeError(m.Reply.Error, n.Reply.Error), inp.TokenPos);\n                    }\n\n                    // cerr, cok\n                    return n;\n                }\n\n                // cok, cerr, eok\n                return m;\n            };\n\n        /// <summary>\n        /// choice(ps) tries to apply the parsers in the list ps in order, until one \n        /// of them succeeds. \n        /// </summary>\n        /// <returns>\n        /// The value of the succeeding parser.\n        /// </returns>\n        public static Parser<I, O> choice<I, O>(params Parser<I, O>[] ps) =>\n            choicei(toSeq(ps));\n\n        /// <summary>\n        /// choice(ps) tries to apply the parsers in the list ps in order, until one \n        /// of them succeeds. \n        /// </summary>\n        /// <returns>\n        /// The value of the succeeding parser.\n        /// </returns>\n        public static Parser<I, O> choice<I, O>(Seq<Parser<I, O>> ps) =>\n            choicei(ps);\n\n        /// <summary>\n        /// Runs a sequence of parsers, if any fail then the failure state is\n        /// returned immediately and subsequence parsers are not run.  \n        /// </summary>\n        /// <returns>\n        /// The result of each parser as an enumerable.\n        /// </returns>\n        public static Parser<I, Seq<O>> chain<I, O>(params Parser<I, O>[] ps) =>\n            chaini(toSeq(ps));\n\n        /// <summary>\n        /// Runs a sequence of parsers, if any fail then the failure state is\n        /// returned immediately and subsequence parsers are not run.  \n        /// </summary>\n        /// <returns>\n        /// The result of each parser as an enumerable.\n        /// </returns>\n        public static Parser<I, Seq<O>> chain<I, O>(Seq<Parser<I, O>> ps) =>\n            chaini(ps);\n\n        /// <summary>\n        /// The parser attempt(p) behaves like parser p, except that it\n        /// pretends that it hasn't consumed any input when an error occurs.\n        /// \n        /// This combinator is used whenever arbitrary look ahead is needed.\n        /// Since it pretends that it hasn't consumed any input when p fails,\n        /// the either combinator will try its second alternative even when the\n        /// first parser failed while consuming input.\n        /// \n        /// See remarks.\n        /// </summary>\n        /// <remarks>\n        /// The attempt combinator can for example be used to distinguish\n        /// identifiers and reserved words.  Both reserved words and identifiers\n        /// are a sequence of letters.  Whenever we expect a certain reserved\n        /// word where we can also expect an identifier we have to use the attempt\n        /// combinator.  Suppose we write:\n        /// \n        ///    var expr        = either(letExpr, identifier).label(\"expression\");\n        ///  \n        ///    var letExpr     = from x in str(\"let\")\n        ///                      ...\n        ///                      select ...;\n        ///                      \n        ///    var identifier  = many1(letter);\n        /// \n        ///  If the user writes \"lexical\", the parser fails with: unexpected\n        ///  \"x\", expecting \"t\" in \"let\".  Indeed, since the either combinator\n        ///  only tries alternatives when the first alternative hasn't consumed\n        ///  input, the identifier parser is never tried  (because the prefix\n        ///  \"le\" of the str(\"let\") parser is already consumed). The right behaviour \n        ///  can be obtained by adding the attempt combinator:\n        /// \n        ///    var expr        = either(letExpr, identifier).label(\"expression\");\n        ///  \n        ///    var letExpr     = from x in attempt(str(\"let\"))\n        ///                      ...\n        ///                      select ...;\n        ///                      \n        ///    var identifier  = many1(letter);\n        ///  \n        ///  </remarks>\n        public static Parser<I, O> attempt<I, O>(Parser<I, O> p) =>\n            inp =>\n            {\n                var res = p(inp);\n                if (res.Tag == ResultTag.Consumed && res.Reply.Tag == ReplyTag.Error)\n                {\n                    return EmptyError<I, O>(res.Reply.Error, inp.TokenPos);\n                }\n                else\n                {\n                    return res;\n                }\n            };\n\n        /// <summary>\n        /// lookAhead(p) parses p without consuming any input.\n        /// \n        /// If p fails and consumes some input, so does lookAhead(p). Combine with \n        /// 'attempt' if this is undesirable.\n        /// </summary>\n        public static Parser<I, O> lookAhead<I, O>(Parser<I, O> p) =>\n            inp =>\n            {\n                var res = p(inp);\n                if (res.Reply.Tag == ReplyTag.OK)\n                {\n                    return EmptyOK(res.Reply.Result, inp);\n                }\n                else\n                {\n                    return res;\n                }\n            };\n\n        /// <summary>\n        /// many(p) applies the parser p zero or more times.\n        /// </summary>\n        /// <example>\n        ///     var identifier  = from c in letter\n        ///                       from cs in many(letterOrDigit)\n        ///                       select c.Cons(cs)\n        /// </example>\n        /// <returns>\n        /// Enumerable of the returned values of p.\n        /// </returns>\n        public static Parser<I, Seq<O>> many<I, O>(Parser<I, O> p) =>\n            inp =>\n            {\n                var current = inp;\n                var results = new List<O>();\n                ParserError error = null;\n\n                while(true)\n                {\n                    var t = p(current);\n\n                    // cok\n                    if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                    {\n                        results.Add(t.Reply.Result);\n                        current = t.Reply.State;\n                        error = t.Reply.Error;\n                        continue;\n                    }\n\n                    // eok\n                    if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                    {\n                        // eok, eerr\n                        return EmptyError<I, Seq<O>>(new ParserError(ParserErrorTag.SysUnexpect, current.Pos, \"many: combinator 'many' is applied to a parser that accepts an empty string.\", List.empty<string>()), inp.TokenPos);\n                    }\n\n                    // cerr\n                    if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                    {\n                        return ConsumedError<I, Seq<O>>(mergeError(error, t.Reply.Error), inp.TokenPos);\n                    }\n\n                    // eerr\n                    return EmptyOK(toSeq(results), current, mergeError(error, t.Reply.Error));\n                }\n            };\n\n        /// <summary>\n        /// many1(p) applies the parser p one or more times.\n        /// </summary>\n        /// <returns>\n        /// Enumerable of the returned values of p.\n        /// </returns>\n        public static Parser<I, Seq<O>> many1<I, O>(Parser<I, O> p) =>\n            from x in p\n            from xs in many(p)\n            select x.Cons(xs);\n\n        /// <summary>\n        /// skipMany(p) applies the parser p zero or more times, skipping\n        /// its result.\n        /// </summary>\n        public static Parser<I, Unit> skipMany<I, O>(Parser<I, O> p) =>\n            either(skipMany1(p), result<I,Unit>(unit));\n\n        /// <summary>\n        /// skipMany(p) applies the parser p one or more times, skipping\n        /// its result.\n        /// </summary>\n        public static Parser<I, Unit> skipMany1<I, O>(Parser<I, O> p) =>\n            from x  in p\n            from xs in many(p)\n            select unit;\n\n        /// <summary>\n        /// optionOrElse(x, p) tries to apply parser p. If p fails without\n        /// consuming input, it returns the value x, otherwise the value\n        /// returned by p.\n        /// </summary>\n        public static Parser<I, O> optionOrElse<I, O>(O x, Parser<I, O> p) =>\n            either(p, result<I, O>(x));\n\n        /// <summary>\n        /// optional(p) tries to apply parser p.  If p fails without\n        /// consuming input, it return 'None', otherwise it returns\n        /// 'Some' the value returned by p.\n        /// </summary>\n        public static Parser<I, Option<O>> optional<I, O>(Parser<I, O> p) =>\n            inp =>\n            {\n                var r = p.Map(Option.Some)(inp);\n                return r.Reply.Tag == ReplyTag.OK\n                    ? r\n                    : EmptyOK(Option<O>.None, inp);\n            };\n\n        /// <summary>\n        /// optionalSeq(p) tries to apply parser p.  If p fails without\n        /// consuming input, it return an empty IEnumerable, otherwise it returns \n        /// a one item IEnumerable with the result of p.\n        /// </summary>\n        /// <returns>A list of 0 or 1 parsed items</returns>\n        public static Parser<I, Seq<O>> optionalSeq<I, O>(Parser<I, O> p) =>\n            inp =>\n            {\n                var r = p.Map(x => x.Cons(Seq<O>.Empty))(inp);\n                return r.Reply.Tag == ReplyTag.OK\n                    ? r\n                    : EmptyOK(Seq<O>.Empty, inp);\n            };\n\n        /// <summary>\n        /// optionalList(p) tries to apply parser p.  If p fails without\n        /// consuming input, it return [], otherwise it returns a one \n        /// item Lst with the result of p.\n        /// </summary>\n        /// <returns>A list of 0 or 1 parsed items</returns>\n        public static Parser<I, Lst<O>> optionalList<I, O>(Parser<I, O> p) =>\n            inp =>\n            {\n                var r = p.Map(x => List.create(x))(inp);\n                return r.Reply.Tag == ReplyTag.OK\n                    ? r\n                    : EmptyOK(List.empty<O>(), inp);\n            };\n\n        /// <summary>\n        /// optionalArray(p) tries to apply parser p.  If p fails without\n        /// consuming input, it return [], otherwise it returns a one \n        /// item array with the result of p.\n        /// </summary>\n        /// <returns>A list of 0 or 1 parsed items</returns>\n        public static Parser<I, O[]> optionalArray<I, O>(Parser<I, O> p) =>\n            inp =>\n            {\n                var r = p.Map(x => new[] { x })(inp);\n                return r.Reply.Tag == ReplyTag.OK\n                    ? r\n                    : EmptyOK(new O [0], inp);\n            };\n\n        /// <summary>\n        /// between(open,close,p) parses open, followed by p and close.\n        /// </summary>\n        /// <returns>\n        /// The value returned by p.\n        /// </returns>\n        public static Parser<I, O> between<L, R, I, O>(Parser<I, L> open, Parser<I, R> close, Parser<I, O> inner) =>\n            from l in open\n            from v in inner\n            from r in close\n            select v;\n\n        /// <summary>\n        /// sepBy1(p,sep) parses one or more occurrences of p, separated\n        /// by sep. \n        /// </summary>\n        /// <returns>\n        /// A list of values returned by p.\n        /// </returns>\n        public static Parser<I, Seq<O>> sepBy1<S, I, O>(Parser<I, O> p, Parser<I, S> sep) =>\n            from x in p\n            from xs in many(from _ in sep\n                            from y in p\n                            select y)\n            select x.Cons(xs);\n\n        /// <summary>\n        /// sepBy(p,sep) parses zero or more occurrences of p, separated\n        /// by sep. \n        /// </summary>\n        /// <returns>\n        /// A list of values returned by p.\n        /// </returns>\n        public static Parser<I, Seq<O>> sepBy<S, I, O>(Parser<I, O> p, Parser<I, S> sep) =>\n            either(sepBy1(p, sep), result<I, Seq<O>>(Seq<O>.Empty));\n\n        /// <summary>\n        /// sepEndBy1(p,sep) parses one or more occurrences of p,\n        /// separated and optionally ended by sep. \n        /// </summary>\n        /// <returns>\n        /// A list of values returned by p.\n        /// </returns>\n        public static Parser<I, Seq<O>> sepEndBy1<S, I, O>(Parser<I, O> p, Parser<I, S> sep) =>\n            from x in p\n            from xs in either(from _ in sep\n                              from ys in sepEndBy(p, sep)\n                              select ys,\n                              result<I, Seq<O>>(Seq<O>.Empty))\n            select x.Cons(xs);\n\n        /// <summary>\n        /// sepEndBy(p,sep) parses zero or more occurrences of p,\n        /// separated and optionally ended by sep. \n        /// </summary>\n        /// <returns>\n        /// A list of values returned by p.\n        /// </returns>\n        public static Parser<I, Seq<O>> sepEndBy<S, I, O>(Parser<I, O> p, Parser<I, S> sep) =>\n            either(sepEndBy1(p, sep), result<I, Seq<O>>(Seq<O>.Empty));\n\n        /// <summary>\n        /// endBy1(p,sep) parses one or more occurrences of p, separated\n        /// and ended by sep.\n        /// </summary>\n        /// <returns>\n        /// A list of values returned by p.\n        /// </returns>\n        public static Parser<I, Seq<O>> endBy1<S, I, O>(Parser<I, O> p, Parser<I, S> sep) =>\n            many1(from x in p\n                  from _ in sep\n                  select x);\n\n        /// <summary>\n        /// endBy(p,sep) parses zerp or more occurrences of p, separated\n        /// and ended by sep.\n        /// </summary>\n        /// <returns>\n        /// A list of values returned by p.\n        /// </returns>\n        public static Parser<I, Seq<O>> endBy<S, I, O>(Parser<I, O> p, Parser<I, S> sep) =>\n            many(from x in p\n                 from _ in sep\n                 select x);\n\n        /// <summary>\n        /// count(n,p) parses n occurrences of p. If n is smaller or\n        /// equal to zero, the parser equals to result([]). \n        /// </summary>\n        /// <returns>\n        /// A list of values returned by p.\n        /// </returns>\n        public static Parser<I, Seq<O>> count<S, I, O>(int n, Parser<I, O> p) =>\n            counti(n, p);\n\n        /// <summary>\n        /// chainr(p,op,x) parses zero or more occurrences of p, separated by op \n        /// </summary>\n        /// <returns>\n        /// a value obtained by a right associative application of all functions \n        /// returned by op to the values returned by p. If there are no occurrences \n        /// of p, the value x is returned.</returns>\n        public static Parser<I, O> chainr<I, O>(Parser<I, O> p, Parser<I, Func<O, O, O>> op, O x) =>\n            either(chainr1(p, op), result<I, O>(x));\n\n        /// <summary>\n        /// chainl(p,op,x) parses zero or more occurrences of p, separated by op \n        /// </summary>\n        /// <returns>\n        /// a value obtained by a left associative application of all functions \n        /// returned by op to the values returned by p. If there are no occurrences \n        /// of p, the value x is returned.</returns>\n        public static Parser<I, O> chainl<I, O>(Parser<I, O> p, Parser<I, Func<O, O, O>> op, O x) =>\n            either(chainr1(p, op), result<I, O>(x));\n\n        /// <summary>\n        /// chainr1(p,op) parses one or more occurrences of p, separated by op. \n        /// </summary>\n        /// <returns>\n        /// A value obtained by a right associative application of all functions \n        /// returned by op to the values returned by p\n        /// </returns>\n        public static Parser<I, O> chainr1<I, O>(Parser<I, O> p, Parser<I, Func<O, O, O>> op)\n        {\n            Parser<I, O> scan = null;\n\n            var rest = fun((O x) => either(from f in op\n                                           from y in scan\n                                           select f(x, y),\n                                           result<I, O>(x)));\n\n            scan = from x in p\n                   from y in rest(x)\n                   select y;\n\n            return scan;\n        }\n\n        /// <summary>\n        /// chainl1(p,op) parses one or more occurrences of p, separated by op. \n        /// </summary>\n        /// <returns>\n        /// A value obtained by a left associative application of all functions \n        /// returned by op to the values returned by p\n        /// </returns>\n        public static Parser<I, O> chainl1<I, O>(Parser<I, O> p, Parser<I, Func<O, O, O>> op)\n        {\n            Func<O, Parser<I, O>> rest = null;\n\n            rest = fun((O x) => either(from f in op\n                                       from y in p\n                                       from r in rest(f(x, y))\n                                       select r,\n                                       result<I, O>(x)));\n\n            return from x in p\n                   from y in rest(x)\n                   select y;\n        }\n\n        /// <summary>\n        /// This parser only succeeds at the end of the input. This is not a\n        /// primitive parser but it is defined using 'notFollowedBy'.\n        /// </summary>\n        public static Parser<I, Unit> eof<I>() =>\n            notFollowedBy(anyItem<I>()).label(\"end of input\");\n\n        /// <summary>\n        /// notFollowedBy(p) only succeeds when parser p fails. This parser\n        /// does not consume any input.This parser can be used to implement the\n        /// 'longest match' rule. \n        /// </summary>\n        /// <example>For example, when recognizing keywords (for\n        /// example 'let'), we want to make sure that a keyword is not followed\n        /// by a legal identifier character, in which case the keyword is\n        /// actually an identifier(for example 'lets'). We can program this\n        /// behaviour as follows:\n        /// \n        ///     var keywordLet  = attempt (from x in str(\"let\")\n        ///                                from _ in notFollowedBy letterOrDigit\n        ///                                select x);\n        ///                                \n        /// </example>\n        public static Parser<I, Unit> notFollowedBy<I, O>(Parser<I, O> p) =>\n            attempt(\n                either(from c in attempt(p)\n                       from u in unexpected<I, Unit>(c.ToString())\n                       select u,\n                       result<I, Unit>(unit)));\n\n        /// <summary>\n        /// Parse a char list and convert into a string\n        /// </summary>\n        public static Parser<I, string> asString<I>(Parser<I, Seq<char>> p) =>\n            p.Select(x => new string(x.ToArray()));\n\n        /// <summary>\n        /// Parse a T list and convert into a string\n        /// </summary>\n        public static Parser<I, string> asString<I, O>(Parser<I, Seq<O>> p) =>\n            p.Select(x => String.Join(\"\",x.Select(o =>o.ToString())));\n\n        /// <summary>\n        /// Parse a T list and convert into a string\n        /// </summary>\n        public static Parser<I, string> asString<I, O>(Parser<I, O> p) =>\n            p.Select(toString);\n\n        /// <summary>\n        /// Parse a char list and convert into an integer\n        /// </summary>\n        public static Parser<I, Option<int>> asInteger<I>(Parser<I, Seq<char>> p) =>\n            p.Select(x => parseInt(new string(x.ToArray())));\n\n        /// <summary>\n        /// Parse a char list and convert into an integer\n        /// </summary>\n        public static Parser<I, Option<int>> asInteger<I>(Parser<I, string> p) =>\n            p.Select(parseInt);\n\n        /// <summary>\n        /// Parse a char list and convert into an integer\n        /// </summary>\n        public static Parser<I, Option<int>> asInteger<I>(Parser<I, Seq<char>> p, int fromBase) =>\n            p.Select(x => parseInt(new string(x.ToArray()), fromBase));\n\n        /// <summary>\n        /// Parse a char list and convert into an integer\n        /// </summary>\n        public static Parser<I, Option<int>> asInteger<I>(Parser<I, string> p, int fromBase) =>\n            p.Select(x => parseInt(x, fromBase));\n\n        /// <summary>\n        /// Parse a char list and convert into an double precision floating point value\n        /// </summary>\n        public static Parser<I, Option<double>> asDouble<I>(Parser<I, Seq<char>> p) =>\n            p.Select(x => parseDouble(new string(x.ToArray())));\n\n        /// <summary>\n        /// Parse a char list and convert into an double precision floating point value\n        /// </summary>\n        public static Parser<I, Option<double>> asDouble<I>(Parser<I, string> p) =>\n            p.Select(parseDouble);\n\n        /// <summary>\n        /// Parse a char list and convert into an double precision floating point value\n        /// </summary>\n        public static Parser<I, Option<float>> asFloat<I>(Parser<I, Seq<char>> p) =>\n            p.Select(x => parseFloat(new string(x.ToArray())));\n\n        /// <summary>\n        /// Parse a char list and convert into an double precision floating point value\n        /// </summary>\n        public static Parser<I, Option<float>> asFloat<I>(Parser<I, string> p) =>\n            p.Select(parseFloat);\n\n        public static Parser<I, Seq<O>> manyUntil<I, O, U>(Parser<I, O> p, Parser<I, U> end)\n        {\n            Parser<I, Seq<O>> scan = null;\n\n            scan = either(\n                from _ in end\n                select Seq<O>.Empty,\n                from x  in p\n                from xs in scan\n                select x.Cons(xs));\n\n            return scan;\n        }\n\n        /// <summary>\n        /// Parse child tokens\n        /// </summary>\n        /// <param name=\"children\">Parser that gets the child tokens</param>\n        /// <param name=\"p\">Parser to run on the child tokens</param>\n        /// <typeparam name=\"TOKEN\">Token type</typeparam>\n        /// <typeparam name=\"A\">Type of the value to parse</typeparam>\n        /// <returns>Parser that parses a set of tokens then uses them as a new stream to parse</returns>\n        public static Parser<TOKEN, A> children<TOKEN, A>(Parser<TOKEN, Seq<TOKEN>> children, Parser<TOKEN, A> p) =>\n            inp =>\n            {\n                var cres = children(inp);\n                if (cres.Reply.Tag == ReplyTag.OK)\n                {\n                    var kids = cres.Reply.Result.ToArray();\n                    var pres = p(new PString<TOKEN>(kids, 0, kids.Length, cres.Reply.State.UserState, inp.TokenPos));\n                    \n                    return pres.Reply.Tag == ReplyTag.OK && pres.Reply.State.Index < kids.Length\n                               ? new ParserResult<TOKEN, A>(\n                                   pres.Tag,\n                                   new Reply<TOKEN, A>(\n                                       ReplyTag.Error,\n                                       pres.Reply.Result,\n                                       new PString<TOKEN>(inp.Value, cres.Reply.State.Index, inp.EndIndex, pres.Reply.State.UserState, pres.Reply.State.TokenPos),\n                                       ParserError.Unexpect(pres.Reply.State.Pos, \"extra tokens in element that can't be parsed\")))\n                               : new ParserResult<TOKEN, A>(\n                                   pres.Tag,\n                                   new Reply<TOKEN, A>(\n                                       pres.Reply.Tag,\n                                       pres.Reply.Result,\n                                       new PString<TOKEN>(inp.Value, cres.Reply.State.Index, inp.EndIndex, pres.Reply.State.UserState, pres.Reply.State.TokenPos),\n                                       pres.Reply.Error));\n                }\n                else\n                {\n                    return new ParserResult<TOKEN, A>(\n                        cres.Tag,\n                        new Reply<TOKEN, A>(\n                            cres.Reply.Tag,\n                            default(A),\n                            cres.Reply.State,\n                            cres.Reply.Error));\n                }\n            };        \n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParserResult.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics;\n\nnamespace LanguageExt.Parsec\n{\n    public static class ParserResult\n    {\n        public static ParserResult<T> Consumed<T>(Reply<T> reply) =>\n            new ParserResult<T>(ResultTag.Consumed, reply);\n\n        public static ParserResult<T> Empty<T>(Reply<T> reply) =>\n            new ParserResult<T>(ResultTag.Empty, reply);\n\n        public static ParserResult<T> EmptyOK<T>(T value, PString input, ParserError? error = null) =>\n            new ParserResult<T>(ResultTag.Empty, Reply.OK(value, input, error));\n\n        public static ParserResult<T> EmptyError<T>(ParserError error) =>\n            new ParserResult<T>(ResultTag.Empty, Reply.Error<T>(error));\n\n        public static ParserResult<T> ConsumedOK<T>(T value, PString input) =>\n            new ParserResult<T>(ResultTag.Consumed, Reply.OK(value, input));\n\n        public static ParserResult<T> ConsumedOK<T>(T value, PString input, ParserError error) =>\n            new ParserResult<T>(ResultTag.Consumed, Reply.OK(value, input, error));\n\n        public static ParserResult<T> ConsumedError<T>(ParserError error) =>\n            new ParserResult<T>(ResultTag.Consumed, Reply.Error<T>(error));\n\n    }\n\n    public enum ResultTag\n    {\n        Consumed,\n        Empty\n    }\n\n    public class ParserResult<T>\n    {\n        public readonly ResultTag Tag;\n        public readonly Reply<T> Reply;\n\n        internal ParserResult(ResultTag tag, Reply<T> reply)\n        {\n            Tag = tag;\n            Reply = reply;\n        }\n\n        public ParserResult<T> SetEndIndex(int endIndex) =>\n            new ParserResult<T>(Tag, Reply.SetEndIndex(endIndex));\n\n        public ParserResult<U> Project<S, U>(S s, Func<S, T, U> project) =>\n            new ParserResult<U>(Tag, Reply.Project(s, project));\n\n        public override string ToString() =>\n            IsFaulted\n                ? Reply?.Error?.ToString() ?? \"Error\"\n                : $\"Success({Reply.Result})\";\n\n        public bool IsFaulted =>\n            Reply.Tag == ReplyTag.Error;\n\n        public R Match<R>(\n            Func<ParserError, R> EmptyError,\n            Func<ParserError, R> ConsumedError,\n            Func<ParserResult<T>, R> Otherwise\n            )\n        {\n            if (Tag == ResultTag.Empty && Reply.Tag == ReplyTag.Error)\n            {\n                return EmptyError(Reply.Error!);\n            }\n            if (Tag == ResultTag.Consumed && Reply.Tag == ReplyTag.Error)\n            {\n                return ConsumedError(Reply.Error!);\n            }\n            return Otherwise(this);\n        }\n\n        public R Match<R>(\n            Func<ParserError, R> EmptyError,\n            Func<ParserResult<T>, R> Otherwise\n            )\n        {\n            if (Tag == ResultTag.Empty && Reply.Tag == ReplyTag.Error)\n            {\n                return EmptyError(Reply.Error!);\n            }\n            return Otherwise(this);\n        }\n\n        public R Match<R>(\n            Func<Reply<T>, R> Empty,\n            Func<ParserResult<T>, R> Otherwise\n            )\n        {\n            if (Tag == ResultTag.Empty)\n            {\n                return Empty(Reply);\n            }\n            return Otherwise(this);\n        }\n\n        public R Match<R>(\n            Func<Reply<T>, R> Empty,\n            Func<Reply<T>, R> Consumed\n            )\n        {\n            if (Tag == ResultTag.Empty)\n            {\n                return Empty(Reply);\n            }\n            return Consumed(Reply);\n        }\n\n        public R Match<R>(\n            Func<T, PString, ParserError, R> ConsumedOK,\n            Func<ParserError, R> ConsumedError,\n            Func<T, PString, ParserError, R> EmptyOK,\n            Func<ParserError, R> EmptyError\n            )\n        {\n            if (Tag == ResultTag.Empty && Reply.Tag == ReplyTag.OK)\n            {\n                return EmptyOK(Reply.Result, Reply.State, Reply.Error);\n            }\n            if (Tag == ResultTag.Empty && Reply.Tag == ReplyTag.Error)\n            {\n                return EmptyError(Reply.Error);\n            }\n            if (Tag == ResultTag.Consumed && Reply.Tag == ReplyTag.OK)\n            {\n                return ConsumedOK(Reply.Result, Reply.State, Reply.Error);\n            }\n            return ConsumedError(Reply.Error);\n        }\n\n        public ParserResult<U> Select<U>(Func<T,U> map) =>\n            new ParserResult<U>(Tag, Reply.Select(map));\n\n        public Either<string, T> ToEither() =>\n            IsFaulted\n                ? Left<string, T>(ToString())\n                : Right(Reply.Result);\n\n        public Either<ERROR, T> ToEither<ERROR>(Func<string, ERROR> f) =>\n            IsFaulted\n                ? Left<ERROR, T>(f(ToString()))\n                : Right(Reply.Result);\n\n        public Option<T> ToOption() =>\n            IsFaulted\n                ? None\n                : Some(Reply.Result);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ParserResultIO.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Parsec;\n\npublic static class ParserResultIO\n{\n    public static ParserResult<I, O> Consumed<I, O>(Reply<I, O> reply) =>\n        new ParserResult<I, O>(ResultTag.Consumed, reply);\n\n    public static ParserResult<I, O> Empty<I, O>(Reply<I, O> reply) =>\n        new ParserResult<I, O>(ResultTag.Empty, reply);\n\n    public static ParserResult<I, O> EmptyOK<I, O>(O value, PString<I> input, ParserError? error = null) =>\n        new ParserResult<I, O>(ResultTag.Empty, Reply.OK(value, input, error));\n\n    public static ParserResult<I, O> EmptyError<I, O>(ParserError error, Func<I, Pos> tokenPos) =>\n        new ParserResult<I, O>(ResultTag.Empty, Reply.Error<I, O>(error, tokenPos));\n\n    public static ParserResult<I, O> ConsumedOK<I, O>(O value, PString<I> input) =>\n        new ParserResult<I, O>(ResultTag.Consumed, Reply.OK(value, input));\n\n    public static ParserResult<I, O> ConsumedOK<I, O>(O value, PString<I> input, ParserError error) =>\n        new ParserResult<I, O>(ResultTag.Consumed, Reply.OK(value, input, error));\n\n    public static ParserResult<I, O> ConsumedError<I, O>(ParserError error, Func<I, Pos> tokenPos) =>\n        new ParserResult<I, O>(ResultTag.Consumed, Reply.Error<I, O>(error, tokenPos));\n\n}\n\npublic class ParserResult<I, O>\n{\n    public readonly ResultTag Tag;\n    public readonly Reply<I, O> Reply;\n\n    internal ParserResult(ResultTag tag, Reply<I, O> reply)\n    {\n        Tag = tag;\n        Reply = reply;\n    }\n\n    public ParserResult<I, O> SetEndIndex(int endIndex) =>\n        new ParserResult<I, O>(Tag, Reply.SetEndIndex(endIndex));\n\n    public ParserResult<I, U> Project<S, U>(S s, Func<S, O, U> project) =>\n        new ParserResult<I, U>(Tag, Reply.Project(s, project));\n\n    public override string ToString() =>\n        Reply.Error is null\n            ? \"success\"\n            : Reply.Error.ToString();\n\n    public bool IsFaulted =>\n        Reply.Tag == ReplyTag.Error;\n\n    public R Match<R>(\n        Func<ParserError, R> EmptyError,\n        Func<ParserError, R> ConsumedError,\n        Func<ParserResult<I, O>, R> Otherwise\n        )\n    {\n        if (Tag == ResultTag.Empty && Reply.Tag == ReplyTag.Error)\n        {\n            return EmptyError(Reply.Error!);\n        }\n        if (Tag == ResultTag.Consumed && Reply.Tag == ReplyTag.Error)\n        {\n            return ConsumedError(Reply.Error!);\n        }\n        return Otherwise(this);\n    }\n\n    public R Match<R>(\n        Func<ParserError, R> EmptyError,\n        Func<ParserResult<I, O>, R> Otherwise\n        )\n    {\n        if (Tag == ResultTag.Empty && Reply.Tag == ReplyTag.Error)\n        {\n            return EmptyError(Reply.Error!);\n        }\n        return Otherwise(this);\n    }\n\n    public R Match<R>(\n        Func<Reply<I, O>, R> Empty,\n        Func<ParserResult<I, O>, R> Otherwise\n        )\n    {\n        if (Tag == ResultTag.Empty)\n        {\n            return Empty(Reply);\n        }\n        return Otherwise(this);\n    }\n\n    public R Match<R>(\n        Func<Reply<I, O>, R> Empty,\n        Func<Reply<I, O>, R> Consumed\n        )\n    {\n        if (Tag == ResultTag.Empty)\n        {\n            return Empty(Reply);\n        }\n        return Consumed(Reply);\n    }\n\n    public R Match<R>(\n        Func<O, PString<I>, ParserError, R> ConsumedOK,\n        Func<ParserError, R> ConsumedError,\n        Func<O, PString<I>, ParserError, R> EmptyOK,\n        Func<ParserError, R> EmptyError\n        )\n    {\n        if (Tag == ResultTag.Empty && Reply.Tag == ReplyTag.OK)\n        {\n            return EmptyOK(Reply.Result!, Reply.State, Reply.Error!);\n        }\n        if (Tag == ResultTag.Empty && Reply.Tag == ReplyTag.Error)\n        {\n            return EmptyError(Reply.Error!);\n        }\n        if (Tag == ResultTag.Consumed && Reply.Tag == ReplyTag.OK)\n        {\n            return ConsumedOK(Reply.Result!, Reply.State, Reply.Error!);\n        }\n        return ConsumedError(Reply.Error!);\n    }\n\n    public ParserResult<I, U> Select<U>(Func<O, U> map) =>\n        new ParserResult<I, U>(Tag, Reply.Select(map));\n\n    public Either<string, O> ToEither() =>\n        IsFaulted\n            ? Left<string, O>(ToString())\n            : Right(Reply.Result!);\n\n    public Either<ERROR, O> ToEither<ERROR>(Func<string, ERROR> f) =>\n        IsFaulted\n            ? Left<ERROR, O>(f(ToString()))\n            : Right(Reply.Result!);\n\n    public Option<O> ToOption() =>\n        IsFaulted\n            ? None\n            : Some(Reply.Result!);\n\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Parsers/Char.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.ParserResult;\nusing static LanguageExt.Parsec.Internal;\nusing static LanguageExt.Parsec.Prim;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Parsec;\n\n/// <summary>\n/// Commonly used character parsers.\n/// </summary>\npublic static class Char\n{\n    static Char()\n    {\n        space = satisfy(System.Char.IsWhiteSpace).label(\"space\");\n        spaces = skipMany(space).label(\"white space\");\n        control = satisfy(System.Char.IsControl).label(\"control\");\n        tab = satisfy(c => c == '\\t').label(\"tab\");\n#pragma warning disable CS0618 // Type or member is obsolete\n        newline = satisfy(c => c == '\\n').label(\"lf new-line\");\n#pragma warning restore CS0618 // Type or member is obsolete\n        LF = satisfy(c => c == '\\n').label(\"lf new-line\");\n        CR = satisfy(c => c == '\\r').label(\"cr carriage-return\");\n        CRLF = (from cr in ch('\\r')\n                from nl in ch('\\n')\n                select nl)\n           .label(\"crlf new-line\");\n        endOfLine = either(LF, CRLF).label(\"new-line\");\n        digit = satisfy(System.Char.IsDigit).label(\"digit\");\n        letter = satisfy(System.Char.IsLetter).label(\"letter\");\n        alphaNum = satisfy(System.Char.IsLetterOrDigit).label(\"letter or digit\");\n        lower = satisfy(System.Char.IsLower).label(\"lowercase letter\");\n        upper = satisfy(System.Char.IsUpper).label(\"uppercase letter\");\n        punctuation = satisfy(System.Char.IsPunctuation).label(\"punctuation\");\n        separator = satisfy(System.Char.IsSeparator).label(\"separator\");\n        symbolchar = satisfy(System.Char.IsSymbol).label(\"symbolchar\");\n        octDigit = satisfy(c => \"01234567\".Contains(c)).label(\"octal digit\");\n        hexDigit = satisfy(c => System.Char.IsDigit(c) || \"abcdefABCDEF\".Contains(c)).label(\"hexadecimal digit\");\n        anyChar = satisfy(_ => true);\n    }\n\n    /// <summary>\n    /// ch(c) parses a single character c\n    /// </summary>\n    /// <returns>The parsed character</returns>\n    public static Parser<char> ch(char c) =>\n        satisfy(x => x == c).label($\"'{c}'\");\n\n    /// <summary>\n    /// ch(c) parses a single character c\n    /// </summary>\n    /// <typeparam name=\"EQ\">Eq〈char〉 trait</typeparam>\n    /// <returns>The parsed character</returns>\n    public static Parser<char> ch<EQ>(char c) where EQ : Eq<char> =>\n        satisfy(x => EQ.Equals(x, c)).label($\"'{c}'\");\n\n    /// <summary>\n    /// The parser satisfy(pred) succeeds for any character for which the\n    /// supplied function pred returns 'True'. \n    /// </summary>\n    /// <returns>\n    /// The character that is actually parsed.</returns>\n    public static Parser<char> satisfy(Func<char, bool> pred) =>\n        inp =>\n        {\n            if (inp.Index >= inp.EndIndex)\n            {\n                return EmptyError<char>(ParserError.SysUnexpect(inp.Pos, \"end of stream\"));\n            }\n            else\n            {\n                var ns = newstate(inp);\n\n                if (ns.Tag == ResultTag.Consumed)\n                {\n                    if (pred(ns.Reply.Result))\n                    {\n                        return ns;\n                    }\n                    else\n                    {\n                        return EmptyError<char>(ParserError.SysUnexpect(inp.Pos, $\"\\\"{ns.Reply.Result}\\\"\"));\n                    }\n                }\n                else\n                {\n                    return EmptyError<char>(ParserError.SysUnexpect(inp.Pos, \"end of stream\"));\n                }\n            }\n        };\n\n    /// <summary>\n    /// oneOf(str) succeeds if the current character is in the supplied list of \n    /// characters str. Returns the parsed character. See also satisfy\n    /// </summary>\n    public static Parser<char> oneOf(string str) =>\n        satisfy(c => str.Contains(c));\n\n    /// <summary>\n    /// oneOf(str) succeeds if the current character is in the supplied list of \n    /// characters str. Returns the parsed character. See also satisfy\n    /// </summary>\n    public static Parser<char> oneOf(params char[] str) =>\n        satisfy(c => str.Contains(c));\n\n    /// <summary>\n    /// As the dual of 'oneOf', noneOf(str) succeeds if the current\n    /// character not in the supplied list of characters str. \n    /// \n    ///     var consonant = noneOf(\"aeiou\")\n    /// </summary>\n    /// <returns>\n    /// The parsed character.</returns>\n    public static Parser<char> noneOf(string str) =>\n        satisfy(c => !str.Contains(c));\n\n    /// <summary>\n    /// As the dual of 'oneOf', noneOf(str) succeeds if the current\n    /// character not in the supplied list of characters str. \n    /// \n    ///     var consonant = noneOf(\"aeiou\")\n    /// </summary>\n    /// <returns>\n    /// The parsed character.</returns>\n    public static Parser<char> noneOf(params char[] str) =>\n        satisfy(c => !str.Contains(c));\n\n    /// <summary>\n    /// Parses a white space character (any character which satisfies 'System.Char.IsWhiteSpace')\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> space;\n\n    /// <summary>\n    /// Skips zero or more white space characters. See also 'skipMany'.\n    /// </summary>\n    public static readonly Parser<Unit> spaces;\n\n    /// <summary>\n    /// Parses a control character\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> control;\n\n    /// <summary>\n    /// Parses a tab\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> tab;\n\n    /// <summary>\n    /// Equivalent to `LF`. Parses a line-feed newline char (\\n). \n    /// Returns the parsed character.\n    /// </summary>\n    [Obsolete(\"This parses only \\\\n (regardless of environment). Use (explicit) parser `LF` instead. Related parsers: `CRLF` and `endOfLine` (parsing CRLF or LF).\")]\n    public static readonly Parser<char> newline;\n\n    /// <summary>\n    /// Parses a carriage-return char (\\r)\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> CR;\n\n    /// <summary>\n    /// Parses a line-feed newline char (\\n)\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> LF;\n \n    /// <summary>\n    /// Parses a carriage-return then line-feed\n    /// Returns the new-line.\n    /// </summary>\n    public static readonly Parser<char> CRLF;\n\n    /// <summary>\n    /// Parses a CRLF (see 'crlf') or LF (see 'newline') end-of-line.\n    /// Returns a newline character(\\'\\\\n\\').\n    /// </summary>\n    public static readonly Parser<char> endOfLine;\n\n    /// <summary>\n    /// Parses a digit\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> digit;\n\n    /// <summary>\n    /// Parses a letter\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> letter;\n\n    /// <summary>\n    /// Parses a letter or digit\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> alphaNum;\n\n    /// <summary>\n    /// Parses a lowercase letter\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> lower;\n\n    /// <summary>\n    /// Parses a uppercase letter\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> upper;\n\n    /// <summary>\n    /// Parses a punctuation character\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> punctuation;\n\n    /// <summary>\n    /// Parses a separator character\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> separator;\n\n    /// <summary>\n    /// Parses a symbol character\n    /// Returns the parsed character.\n    /// </summary>\n    public static readonly Parser<char> symbolchar;\n\n    /// <summary>\n    /// Parses an octal digit (0-7)\n    /// </summary>\n    public readonly static Parser<char> octDigit;\n\n    /// <summary>\n    /// Parses a hex digit (0-F | 0-f)\n    /// </summary>\n    public readonly static Parser<char> hexDigit;\n\n    /// <summary>\n    /// The parser anyChar accepts any kind of character.\n    /// </summary>\n    public readonly static Parser<char> anyChar;\n\n    /// <summary>\n    /// Parse a string\n    /// </summary>\n    public static Parser<string> str(string s) =>\n        asString(chain(toSeq(s.AsIterable().Map(ch)))).label($\"'{s}'\");\n\n    /// <summary>\n    /// Parse a string case insensitive (char by char)\n    /// <typeparam name=\"EQ\">Eq〈char〉 trait</typeparam>\n    /// </summary>\n    public static Parser<string> str<EQ>(string s) where EQ: Eq<char>  =>\n        asString(chain(toSeq(s.AsIterable().Map(ch<EQ>)))).label($\"'{s}'\");\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Parsers/Expr.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Prim;\n\nnamespace LanguageExt.Parsec;\n\npublic static class Expr\n{\n    /// <summary>\n    ///  Convert an OperatorTable and basic term parser into a fully fledged \n    ///  expression parser\n    /// \n    ///  buildExpressionParser(table,term) builds an expression parser for\n    ///  terms term with operators from table, taking the associativity\n    ///  and precedence specified in table into account.  Prefix and postfix\n    ///  operators of the same precedence can only occur once (i.e. --2 is\n    ///  not allowed if '-' is prefix negate).  Prefix and postfix operators\n    ///  of the same precedence associate to the left  (i.e. if ++ is\n    ///  postfix increment, than -2++ equals -1, not -3).\n    /// \n    ///  The buildExpressionParser function takes care of all the complexity\n    ///  involved in building expression parser.\n    ///  \n    ///  See remarks.\n    ///  </summary>\n    ///  <example>\n    ///  This is an example of an expression parser that handles prefix signs, \n    ///  postfix increment and basic arithmetic.\n    /// \n    ///    Parser〈int〉 expr = null;\n    /// \n    ///    var binary = fun((string name, Func〈int, int, int〉 f, Assoc assoc) =〉\n    ///         Operator.Infix〈int〉( assoc,\n    ///                              from x in reservedOp(name)\n    ///                              select fun );\n    ///                              \n    ///    var prefix = fun((string name, Func〈int, int〉 f) =〉\n    ///         Operator.Prefix〈int〉(from x in reservedOp(name)\n    ///                              select fun );\n    /// \n    ///    var postfix = fun((string name, Func〈int, int〉 f) =〉\n    ///         Operator.Postfix〈int〉(from x in reservedOp(name)\n    ///                               select fun );\n    ///         \n    ///    Operator〈int〉[][] table = [ [ prefix(\"-\",negate), prefix(\"+\",id) ]\n    ///                               , [ postfix(\"++\", incr) ]\n    ///                               , [ binary(\"*\", mult) Assoc.Left), binary(\"/\", div, Assoc.Left) ]\n    ///                               , [ binary(\"+\", add, Assoc.Left), binary(\"-\", subtr, Assoc.Left) ] ];\n    ///              ]\n    ///    var term              = either(parens(expr),natural).label(\"simple expression\")\n    ///            \n    ///    expr                  = buildExpressionParser(table,term).label(\"expression\")\n    ///    \n    ///    var res = parse(expr, \"(50 + 20) / 2\");\n    /// </example>\n    public static Parser<T> buildExpressionParser<T>(\n        Operator<T>[][] operators,\n        Parser<T> simpleExpr\n        )\n    {\n        return operators.AsIterable().FoldBack(\n            simpleExpr, \n            (term, ops) => makeParser(ops, term)\n        );\n    }\n\n    static Parser<T> makeParser<T>(\n        Operator<T>[] ops,\n        Parser<T> term\n        )\n    {\n        var e3 = Seq.empty<Parser<Func<T,T,T>>>();\n        var e2 = Seq.empty<Parser<Func<T,T>>>();\n\n        return ops.AsIterable()\n                  .Fold((e3, e3, e3, e2, e2), (state, op) => op.SplitOp(state))\n                  .Map((rassoc, lassoc, nassoc, prefix, postfix) =>\n                       {\n                           var rassocOp  = choice(rassoc);\n                           var lassocOp  = choice(lassoc);\n                           var nassocOp  = choice(nassoc);\n                           var prefixOp  = choice(prefix).label(\"\");\n                           var postfixOp = choice(postfix).label(\"\");\n\n                           var ambigious = fun((string assoc, Parser<Func<T, T, T>> op) =>\n                                                   attempt(\n                                                       from x in op\n                                                       from y in failure<T>($\"ambiguous use of a {assoc} associative operator\")\n                                                       select y));\n\n                           var ambigiousRight = ambigious(\"right\", rassocOp);\n                           var ambigiousLeft  = ambigious(\"left\", lassocOp);\n                           var ambigiousNon   = ambigious(\"non\", nassocOp);\n\n                           var postfixP = either(postfixOp, result<Func<T, T>>(x => x));\n\n                           var prefixP = either(prefixOp, result<Func<T,T>>(x => x));\n\n                           var termP = from pre in prefixP\n                                       from x in term\n                                       from post in postfixP\n                                       select post(pre(x));\n\n                           Func<T, Parser<T>> rassocP  = null;\n                           Func<T, Parser<T>> rassocP1 = null;\n\n                           rassocP1 = fun((T x) => either(rassocP(x), result(x)));\n\n                           rassocP = fun((T x) =>\n                                             choice(\n                                                 from f in rassocOp\n                                                 from y in (from z in termP\n                                                            from z1 in rassocP1(z)\n                                                            select z1)\n                                                 select f(x, y),\n                                                 ambigiousLeft,\n                                                 ambigiousNon));\n\n                           Func<T, Parser<T>> lassocP  = null;\n                           Func<T, Parser<T>> lassocP1 = null;\n\n                           lassocP1 = fun((T x) => either(lassocP(x), result(x)));\n\n                           lassocP = fun((T x) =>\n                                             choice(\n                                                 from f in lassocOp\n                                                 from y in termP\n                                                 from r in lassocP1(f(x, y))\n                                                 select r,\n                                                 ambigiousRight,\n                                                 ambigiousNon));\n\n                           var nassocP = fun((T x) =>\n                                                 from f in nassocOp\n                                                 from y in termP\n                                                 from r in choice(ambigiousRight, ambigiousLeft, ambigiousNon, result(f(x, y)))\n                                                 select r);\n\n                           return from x in termP\n                                  from r in choice(rassocP(x), lassocP(x), nassocP(x), result(x)).label(\"operator\")\n                                  select r;\n                       });\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Parsers/Indent.cs",
    "content": "﻿using System;\n\nnamespace LanguageExt.Parsec\n{\n    public static class Indent\n    {\n        /// <summary>\n        /// Parses only when indented past the level of the reference\n        /// </summary>\n        public static Parser<T> indented<T>(int offset, Parser<T> p) =>\n            inp =>\n            {\n                var col = inp.Pos.Column + offset;\n                var newpos = inp.Pos;\n\n                for (var index = inp.Index; index < inp.EndIndex; index++)\n                {\n                    var x = inp.Value[index];\n\n                    if(newpos.Column < col && newpos.Line > inp.Pos.Line && x != ' ' && x != '\\t' && x != '\\n' && x != '\\r')\n                    {\n                        // first char that's not white-space and is left of the reference\n                        var block = inp.SetEndIndex(index);\n                        var res = p(block);\n                        return res.SetEndIndex(inp.EndIndex);\n                    }\n\n                    newpos = x == '\\n' ? new Pos(newpos.Line + 1, 0)\n                           : x == '\\t' ? new Pos(newpos.Line, ((newpos.Column / 4) + 1) * 4)\n                           : new Pos(newpos.Line, newpos.Column + 1);\n                }\n\n                return p(inp);\n            };\n\n        /// <summary>\n        /// Parses only when indented zero or more characters past the level of the reference\n        /// </summary>\n        public static Parser<T> indented<T>(Parser<T> p) =>\n            indented(0, p);\n\n        /// <summary>\n        /// Parses only when indented one or more characters past the level of the reference\n        /// </summary>\n        public static Parser<T> indented1<T>(Parser<T> p) =>\n            indented(1, p);\n\n        /// <summary>\n        /// Parses only when indented two or more characters past the level of the reference\n        /// </summary>\n        public static Parser<T> indented2<T>(Parser<T> p) =>\n            indented(2, p);\n\n        /// <summary>\n        /// Parses only when indented four or more characters past the level of the reference\n        /// </summary>\n        public static Parser<T> indented4<T>(Parser<T> p) =>\n            indented(4, p);\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Parsers/Prim.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Common;\nusing static LanguageExt.Parsec.Internal;\nusing static LanguageExt.Parsec.Char;\nusing static LanguageExt.Parsec.ParserResult;\n\nnamespace LanguageExt.Parsec;\n\n/// <summary>\n/// The primitive parser combinators\n/// </summary>\npublic static class Prim\n{\n    static Prim()\n    {\n        unitp = inp => EmptyOK(unit, inp);\n        getPos = inp => ConsumedOK(inp.Pos, inp);\n        getIndex = inp => ConsumedOK(inp.Index, inp);\n        eof = notFollowedBy(satisfy(_ => true), \"end of input\").label(\"end of input\");\n    }\n\n    /// <summary>\n    /// Run the parser p with the input provided\n    /// </summary>\n    public static ParserResult<T> parse<T>(Parser<T> p, PString input) =>\n        p.Parse(input);\n\n    /// <summary>\n    /// Run the parser p with the input provided\n    /// </summary>\n    public static ParserResult<T> parse<T>(Parser<T> p, string input) =>\n        p.Parse(input);\n\n    /// <summary>\n    /// Lazy parser - useful in recursive scenarios.\n    /// </summary>\n    public static Parser<T> lazyp<T>(Func<Parser<T>> fn) =>\n        inp => fn()(inp);\n\n    /// <summary>\n    /// This parser is useful to put at the top of LINQ expressions, it\n    /// makes it easier to put breakpoints on the actual first parser\n    /// in an expression.  It returns unit\n    /// </summary>\n    public static readonly Parser<Unit> unitp;\n\n    /// <summary>\n    /// Special parser for setting user-state that propagates \n    /// through the computation.\n    /// </summary>\n    public static Parser<Unit> setState<T>(T state) =>\n        inp => ConsumedOK(unit, inp.SetUserState(state));\n\n    /// <summary>\n    /// Special parser for getting user-state that was previously\n    /// set with setState\n    /// </summary>\n    public static Parser<T> getState<T>() =>\n        inp =>\n            match(inp.UserState,\n                  Some: x => x is T\n                                 ? ConsumedOK((T)x, inp)\n                                 : EmptyError<T>(ParserError.Message(inp.Pos, \"User state type-mismatch\")),\n                  None: () => EmptyError<T>(ParserError.Message(inp.Pos, \"No user state set\")));\n\n    /// <summary>\n    /// Get the current position of the parser in the source as a line\n    /// and column index (starting at 1 for both)\n    /// </summary>\n    public static readonly Parser<Pos> getPos;\n\n    /// <summary>\n    /// Get the current index into the source\n    /// </summary>\n    public static readonly Parser<int> getIndex;\n\n    /// <summary>\n    /// The parser unexpected(msg) always fails with an Unexpect error\n    /// message msg without consuming any input.\n    /// </summary>\n    /// <remarks>\n    /// The parsers 'failure', 'label' and 'unexpected' are the three parsers\n    /// used to generate error messages.  Of these, only 'label' is commonly\n    /// used.  For an example of the use of unexpected, see the definition\n    /// of 'Text.Parsec.Combinator.notFollowedBy'.\n    /// </remarks>\n    /// <param name=\"msg\">Error message to use when parsed</param>\n    public static Parser<T> unexpected<T>(string msg) =>\n        inp => EmptyError<T>(ParserError.Unexpect(inp.Pos, msg));\n\n    /// <summary>\n    /// The parser unexpected(msg) always fails with an Unexpect error\n    /// message msg without consuming any input.\n    /// </summary>\n    /// <remarks>\n    /// The parsers 'failure', 'label' and 'unexpected' are the three parsers\n    /// used to generate error messages.  Of these, only 'label' is commonly\n    /// used.  For an example of the use of unexpected, see the definition\n    /// of 'Text.Parsec.Combinator.notFollowedBy'.\n    /// </remarks>\n    /// <param name=\"pos\">Location of the failure</param>\n    /// <param name=\"msg\">Error message to use when parsed</param>\n    public static Parser<T> unexpected<T>(Pos pos, string msg) =>\n        _ => EmptyError<T>(ParserError.Unexpect(pos, msg));\n\n    /// <summary>\n    /// The parser failure(msg) always fails with a Message error\n    /// without consuming any input.\n    /// \n    /// The parsers 'failure', 'label' and 'unexpected' are the three parsers\n    /// used to generate error messages.  Of these, only 'label' is commonly\n    /// used.  For an example of the use of unexpected, see the definition\n    /// of 'Text.Parsec.Combinator.notFollowedBy'.\n    /// </summary>\n    /// <param name=\"msg\">Error message to use when parsed</param>\n    public static Parser<T> failure<T>(string msg) =>\n        inp => EmptyError<T>(ParserError.Message(inp.Pos, msg));\n\n    /// <summary>\n    /// Always success parser.  Returns the value provided.  \n    /// This is monad return for the Parser monad\n    /// </summary>\n    public static Parser<T> result<T>(T value) =>\n        inp => EmptyOK(value, inp);\n\n    /// <summary>\n    /// Always fails (with an Unknown error) without consuming any input\n    /// </summary>\n    public static Parser<T> zero<T>() =>\n        inp => EmptyError<T>(ParserError.Unknown(inp.Pos));\n\n    /// <summary>\n    /// This combinator implements choice. The parser either(p,q) first\n    /// applies p.  If it succeeds, the value of p is returned.  If p\n    /// fails /without consuming any input/, parser q is tried.  \n    /// </summary>\n    /// <remarks>\n    /// This combinator is the mplus behaviour of the Parser monad.\n    /// \n    /// The parser is called /predictive/ since q is only tried when\n    /// parser p didn't consume any input (i.e.. the look ahead is 1).\n    /// \n    /// This non-backtracking behaviour allows for both an efficient\n    /// implementation of the parser combinators and the generation of good\n    /// error messages.\n    /// </remarks>\n    public static Parser<T> either<T>(Parser<T> p, Parser<T> q) =>\n        inp =>\n        {\n            var m = p(inp);\n\n            // meerr\n            if (m is { Tag: ResultTag.Empty, Reply.Tag: ReplyTag.Error })\n            {\n                var n = q(inp);\n\n                // neok\n                if (n is { Tag: ResultTag.Empty, Reply.Tag: ReplyTag.OK })\n                {\n                    return EmptyOK(n.Reply.Result!, n.Reply.State!, mergeError(m.Reply.Error!, n.Reply.Error!));\n                }\n\n                // nerr\n                if (n.Tag == ResultTag.Empty && n.Reply.Tag == ReplyTag.Error)\n                {\n                    return EmptyError<T>(mergeError(m.Reply.Error!, n.Reply.Error!));\n                }\n\n                // cerr, cok\n                return n;\n            }\n\n            // cok, cerr, eok\n            return m;\n        };\n\n    /// <summary>\n    /// choice(ps) tries to apply the parsers in the list ps in order, until one \n    /// of them succeeds. \n    /// </summary>\n    /// <returns>\n    /// The value of the succeeding parser.\n    /// </returns>\n    public static Parser<T> choice<T>(params Parser<T>[] ps) =>\n        choicei(toSeq(ps));\n\n    /// <summary>\n    /// choice(ps) tries to apply the parsers in the list ps in order, until one \n    /// of them succeeds. \n    /// </summary>\n    /// <returns>\n    /// The value of the succeeding parser.\n    /// </returns>\n    public static Parser<T> choice<T>(Seq<Parser<T>> ps) =>\n        choicei(ps);\n\n    /// <summary>\n    /// Runs a sequence of parsers, if any fail then the failure state is\n    /// returned immediately and subsequence parsers are not run.  \n    /// </summary>\n    /// <returns>\n    /// The result of each parser as an enumerable.\n    /// </returns>\n    public static Parser<Seq<T>> chain<T>(params Parser<T>[] ps) =>\n        chaini(toSeq(ps));\n\n    /// <summary>\n    /// Runs a sequence of parsers, if any fail then the failure state is\n    /// returned immediately and subsequence parsers are not run.  \n    /// </summary>\n    /// <returns>\n    /// The result of each parser as an enumerable.\n    /// </returns>\n    public static Parser<Seq<T>> chain<T>(Seq<Parser<T>> ps) =>\n        chaini(ps);\n\n    /// <summary>\n    /// Cons for parser results\n    /// </summary>\n    /// <param name=\"p\"></param>\n    /// <param name=\"ps\"></param>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <returns></returns>\n    public static Parser<Seq<T>> cons<T>(Parser<T> p, Parser<Seq<T>> ps) =>\n        from x in p\n        from xs in ps\n        select x.Cons(xs);\n        \n    /// <summary>\n    /// Flattens parser result: Seq of Seq of T => Seq of T\n    /// </summary>\n    /// <returns>Parser with flattened result sequence</returns>\n    public static Parser<Seq<T>> flatten<T>(Parser<Seq<Seq<T>>> ssp) =>\n        from xss in ssp\n        select xss.Flatten();\n\n    /// <summary>\n    /// The parser attempt(p) behaves like parser p, except that it\n    /// pretends that it hasn't consumed any input when an error occurs.\n    /// \n    /// This combinator is used whenever arbitrary look ahead is needed.\n    /// Since it pretends that it hasn't consumed any input when p fails,\n    /// the either combinator will try its second alternative even when the\n    /// first parser failed while consuming input.\n    /// \n    /// See remarks.\n    /// </summary>\n    /// <remarks>\n    /// The attempt combinator can for example be used to distinguish\n    /// identifiers and reserved words.  Both reserved words and identifiers\n    /// are a sequence of letters.  Whenever we expect a certain reserved\n    /// word where we can also expect an identifier we have to use the attempt\n    /// combinator.  Suppose we write:\n    /// \n    ///    var expr        = either(letExpr, identifier).label(\"expression\");\n    ///  \n    ///    var letExpr     = from x in str(\"let\")\n    ///                      ...\n    ///                      select ...;\n    ///                      \n    ///    var identifier  = many1(letter);\n    /// \n    ///  If the user writes \"lexical\", the parser fails with: unexpected\n    ///  \"x\", expecting \"t\" in \"let\".  Indeed, since the either combinator\n    ///  only tries alternatives when the first alternative hasn't consumed\n    ///  input, the identifier parser is never tried  (because the prefix\n    ///  \"le\" of the str(\"let\") parser is already consumed). The right behaviour \n    ///  can be obtained by adding the attempt combinator:\n    /// \n    ///    var expr        = either(letExpr, identifier).label(\"expression\");\n    ///  \n    ///    var letExpr     = from x in attempt(str(\"let\"))\n    ///                      ...\n    ///                      select ...;\n    ///                      \n    ///    var identifier  = many1(letter);\n    ///  \n    ///  </remarks>\n    public static Parser<T> attempt<T>(Parser<T> p) =>\n        inp =>\n        {\n            var res = p(inp);\n            if (res.Tag == ResultTag.Consumed && res.Reply.Tag == ReplyTag.Error)\n            {\n                return EmptyError<T>(res.Reply.Error);\n            }\n            else\n            {\n                return res;\n            }\n        };\n\n    /// <summary>\n    /// lookAhead(p) parses p without consuming any input.\n    /// \n    /// If p fails and consumes some input, so does lookAhead(p). Combine with \n    /// 'attempt' if this is undesirable.\n    /// </summary>\n    public static Parser<T> lookAhead<T>(Parser<T> p) =>\n        inp =>\n        {\n            var res = p(inp);\n            if (res.Reply.Tag == ReplyTag.OK)\n            {\n                return EmptyOK(res.Reply.Result, inp);\n            }\n            else\n            {\n                return res;\n            }\n        };\n\n    /// <summary>\n    /// many(p) applies the parser p zero or more times.\n    /// </summary>\n    /// <example>\n    ///     var identifier  = from c in letter\n    ///                       from cs in many(letterOrDigit)\n    ///                       select c.Cons(cs)\n    /// </example>\n    /// <returns>\n    /// Enumerable of the returned values of p.\n    /// </returns>\n    public static Parser<Seq<T>> many<T>(Parser<T> p) =>\n        inp =>\n        {\n            var         current = inp;\n            var         results = new List<T>();\n            ParserError error   = null;\n\n            while(true)\n            {\n                var t = p(current);\n\n                // cok\n                if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                {\n                    results.Add(t.Reply.Result);\n                    current = t.Reply.State;\n                    error = t.Reply.Error;\n                    continue;\n                }\n\n                // eok\n                if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                {\n                    // eok, eerr\n                    return EmptyError<Seq<T>>(new ParserError(ParserErrorTag.SysUnexpect, current.Pos, \"many: combinator 'many' is applied to a parser that accepts an empty string.\", List.empty<string>()));\n                }\n\n                // cerr\n                if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                {\n                    return ConsumedError<Seq<T>>(mergeError(error, t.Reply.Error));\n                }\n\n                // eerr\n                return EmptyOK(toSeq(results), current, mergeError(error, t.Reply.Error));\n            }\n        };\n\n    /// <summary>\n    /// manyn(p, n) applies the parser p n times.\n    /// </summary>\n    /// <example>\n    ///     var identifier  = from c in letter\n    ///                       from cs in manyn(letterOrDigit, 4)\n    ///                       select c.Cons(cs)\n    /// </example>\n    /// <returns>\n    /// Enumerable of the returned values of p.\n    /// </returns>\n    public static Parser<Seq<T>> manyn<T>(Parser<T> p, int n) =>\n        inp =>\n        {\n            var         current = inp;\n            var         results = new List<T>();\n            ParserError error   = null;\n\n            int count = 0;\n\n            while (true)\n            {\n                var t = p(current);\n                count++;\n\n                // cok\n                if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                {\n                    results.Add(t.Reply.Result);\n                    current = t.Reply.State;\n                    error = t.Reply.Error;\n                    if (count == n)\n                    {\n                        return EmptyOK(toSeq(results), current, mergeError(error, t.Reply.Error));\n                    }\n                    continue;\n                }\n\n                // eok\n                if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                {\n                    // eok, eerr\n                    return EmptyError<Seq<T>>(new ParserError(ParserErrorTag.SysUnexpect, current.Pos, \"many: combinator 'manyn' is applied to a parser that accepts an empty string.\", List.empty<string>()));\n                }\n\n                // cerr\n                if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                {\n                    return ConsumedError<Seq<T>>(mergeError(error, t.Reply.Error));\n                }\n\n                // eerr\n                return EmptyError<Seq<T>>(mergeError(error, t.Reply.Error));\n            }\n        };\n\n    /// <summary>\n    /// manyn0(p) applies the parser p zero or up to a maximum of n times.\n    /// </summary>\n    /// <example>\n    ///     var identifier  = from c in letter\n    ///                       from cs in manyn0(letterOrDigit, 4)\n    ///                       select c.Cons(cs)\n    /// </example>\n    /// <returns>\n    /// Enumerable of the returned values of p.\n    /// </returns>\n    public static Parser<Seq<T>> manyn0<T>(Parser<T> p, int n) =>\n        n <= 0 \n            ? result(Seq<T>.Empty)\n            : inp =>\n              {\n                  var         current = inp;\n                  var         results = new List<T>();\n                  ParserError error   = null;\n\n                  int count = 0;\n\n                  while (true)\n                  {\n                      var t = p(current);\n                      count++;\n\n                      // cok\n                      if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.OK)\n                      {\n                          results.Add(t.Reply.Result);\n                          current = t.Reply.State;\n                          error = t.Reply.Error;\n                          if (count == n)\n                          {\n                              return EmptyOK(toSeq(results), current, mergeError(error, t.Reply.Error));\n                          }\n\n                          continue;\n                      }\n\n                      // eok\n                      if (t.Tag == ResultTag.Empty && t.Reply.Tag == ReplyTag.OK)\n                      {\n                          // eok, eerr\n                          return EmptyError<Seq<T>>(new ParserError(ParserErrorTag.SysUnexpect, current.Pos, \"many: combinator 'manyn0' is applied to a parser that accepts an empty string.\", List.empty<string>()));\n                      }\n\n                      // cerr\n                      if (t.Tag == ResultTag.Consumed && t.Reply.Tag == ReplyTag.Error)\n                      {\n                          return ConsumedError<Seq<T>>(mergeError(error, t.Reply.Error));\n                      }\n\n                      // eerr\n                      return EmptyOK(toSeq(results), current, mergeError(error, t.Reply.Error));\n                  }\n              };\n\n    /// <summary>\n    /// manyn1(p) applies the parser p one or up to a maximum of n times.\n    /// </summary>\n    /// <returns>\n    /// Enumerable of the returned values of p.\n    /// </returns>\n    public static Parser<Seq<T>> manyn1<T>(Parser<T> p, int n) =>\n        from x in p\n        from xs in manyn0(p, n - 1)\n        select x.Cons(xs);\n\n    /// <summary>\n    /// many1(p) applies the parser p one or more times.\n    /// </summary>\n    /// <returns>\n    /// Enumerable of the returned values of p.\n    /// </returns>\n    public static Parser<Seq<T>> many1<T>(Parser<T> p) =>\n        from x in p\n        from xs in many(p)\n        select x.Cons(xs);\n\n    /// <summary>\n    /// skipMany(p) applies the parser p zero or more times, skipping\n    /// its result.\n    /// </summary>\n    public static Parser<Unit> skipMany<T>(Parser<T> p) =>\n        either(skipMany1(p), result(unit));\n\n    /// <summary>\n    /// skipMany(p) applies the parser p one or more times, skipping\n    /// its result.\n    /// </summary>\n    public static Parser<Unit> skipMany1<T>(Parser<T> p) =>\n        from x  in p\n        from xs in many(p)\n        select unit;\n\n    /// <summary>\n    /// optionOrElse(x, p) tries to apply parser p. If p fails without\n    /// consuming input, it returns the value x, otherwise the value\n    /// returned by p.\n    /// </summary>\n    public static Parser<T> optionOrElse<T>(T x, Parser<T> p) =>\n        either(p, result(x));\n\n    /// <summary>\n    /// optional(p) tries to apply parser p.  If p fails without\n    /// consuming input, it return 'None', otherwise it returns\n    /// 'Some' the value returned by p.\n    /// </summary>\n    public static Parser<Option<T>> optional<T>(Parser<T> p) =>\n        inp =>\n        {\n            var r = p.Map(Option.Some)(inp);\n            return r.Reply.Tag == ReplyTag.OK\n                       ? r\n                       : EmptyOK(Option<T>.None, inp);\n        };\n\n    /// <summary>\n    /// optionalList(p) tries to apply parser p.  If p fails without\n    /// consuming input, it return [], otherwise it returns a one \n    /// item Lst with the result of p.\n    /// </summary>\n    /// <returns>A list of 0 or 1 parsed items</returns>\n    public static Parser<Lst<T>> optionalList<T>(Parser<T> p) =>\n        inp =>\n        {\n            var r = p.Map(x => List.create(x))(inp);\n            return r.Reply.Tag == ReplyTag.OK\n                       ? r\n                       : EmptyOK(List.empty<T>(), inp);\n        };\n\n    /// <summary>\n    /// optionalSeq(p) tries to apply parser p.  If p fails without\n    /// consuming input, it return an empty IEnumerable, otherwise it returns \n    /// a one item IEnumerable with the result of p.\n    /// </summary>\n    /// <returns>A list of 0 or 1 parsed items</returns>\n    public static Parser<Seq<T>> optionalSeq<T>(Parser<T> p) =>\n        inp =>\n        {\n            var r = p.Map(x => x.Cons())(inp);\n            return r.Reply.Tag == ReplyTag.OK\n                       ? r\n                       : EmptyOK(Seq<T>.Empty, inp);\n        };\n\n    /// <summary>\n    /// optionalArray(p) tries to apply parser p.  If p fails without\n    /// consuming input, it return [], otherwise it returns a one \n    /// item array with the result of p.\n    /// </summary>\n    /// <returns>A list of 0 or 1 parsed items</returns>\n    public static Parser<T[]> optionalArray<T>(Parser<T> p) =>\n        inp =>\n        {\n            var r = p.Map(x => new[] { x })(inp);\n            return r.Reply.Tag == ReplyTag.OK\n                       ? r\n                       : EmptyOK(new T [0], inp);\n        };\n\n    /// <summary>\n    /// between(open,close,p) parses open, followed by p and close.\n    /// </summary>\n    /// <returns>\n    /// The value returned by p.\n    /// </returns>\n    public static Parser<T> between<L, R, T>(Parser<L> open, Parser<R> close, Parser<T> inner) =>\n        from l in open\n        from v in inner\n        from r in close\n        select v;\n\n    /// <summary>\n    /// sepBy1(p,sep) parses one or more occurrences of p, separated\n    /// by sep. \n    /// </summary>\n    /// <returns>\n    /// A list of values returned by p.\n    /// </returns>\n    public static Parser<Seq<T>> sepBy1<S, T>(Parser<T> p, Parser<S> sep) =>\n        from x in p\n        from xs in many(from _ in sep\n                        from y in p\n                        select y)\n        select x.Cons(xs);\n\n    /// <summary>\n    /// sepBy(p,sep) parses zero or more occurrences of p, separated\n    /// by sep. \n    /// </summary>\n    /// <returns>\n    /// A list of values returned by p.\n    /// </returns>\n    public static Parser<Seq<T>> sepBy<S, T>(Parser<T> p, Parser<S> sep) =>\n        either(sepBy1(p, sep), result(Seq<T>.Empty));\n\n    /// <summary>\n    /// sepEndBy1(p,sep) parses one or more occurrences of p,\n    /// separated and optionally ended by sep. \n    /// </summary>\n    /// <returns>\n    /// A list of values returned by p.\n    /// </returns>\n    public static Parser<Seq<T>> sepEndBy1<S, T>(Parser<T> p, Parser<S> sep) =>\n        from x in p\n        from xs in either(from _ in sep\n                          from ys in sepEndBy(p, sep)\n                          select ys,\n                          result(Seq<T>.Empty))\n        select x.Cons(xs);\n\n    /// <summary>\n    /// sepEndBy(p,sep) parses zero or more occurrences of p,\n    /// separated and optionally ended by sep. \n    /// </summary>\n    /// <returns>\n    /// A list of values returned by p.\n    /// </returns>\n    public static Parser<Seq<T>> sepEndBy<S, T>(Parser<T> p, Parser<S> sep) =>\n        either(sepEndBy1(p, sep), result(Seq<T>.Empty));\n\n    /// <summary>\n    /// endBy1(p,sep) parses one or more occurrences of p, separated\n    /// and ended by sep.\n    /// </summary>\n    /// <returns>\n    /// A list of values returned by p.\n    /// </returns>\n    public static Parser<Seq<T>> endBy1<S, T>(Parser<T> p, Parser<S> sep) =>\n        many1(from x in p\n              from _ in sep\n              select x);\n\n    /// <summary>\n    /// endBy(p,sep) parses zero or more occurrences of p, separated\n    /// and ended by sep.\n    /// </summary>\n    /// <returns>\n    /// A list of values returned by p.\n    /// </returns>\n    public static Parser<Seq<T>> endBy<S, T>(Parser<T> p, Parser<S> sep) =>\n        many(from x in p\n             from _ in sep\n             select x);\n\n    /// <summary>\n    /// count(n,p) parses n occurrences of p. If n is smaller or\n    /// equal to zero, the parser equals to result([]). \n    /// </summary>\n    /// <returns>\n    /// A list of values returned by p.\n    /// </returns>\n    public static Parser<Seq<T>> count<T>(int n, Parser<T> p) =>\n        counti(n, p);\n\n    /// <summary>\n    /// chainr(p,op,x) parses zero or more occurrences of p, separated by op \n    /// </summary>\n    /// <returns>\n    /// a value obtained by a right associative application of all functions \n    /// returned by op to the values returned by p. If there are no occurrences \n    /// of p, the value x is returned.</returns>\n    public static Parser<T> chainr<T>(Parser<T> p, Parser<Func<T, T, T>> op, T x) =>\n        either(chainr1(p, op), result(x));\n\n    /// <summary>\n    /// chainl(p,op,x) parses zero or more occurrences of p, separated by op \n    /// </summary>\n    /// <returns>\n    /// a value obtained by a left associative application of all functions \n    /// returned by op to the values returned by p. If there are no occurrences \n    /// of p, the value x is returned.</returns>\n    public static Parser<T> chainl<T>(Parser<T> p, Parser<Func<T, T, T>> op, T x) =>\n        either(chainr1(p, op), result(x));\n\n    /// <summary>\n    /// chainr1(p,op) parses one or more occurrences of p, separated by op. \n    /// </summary>\n    /// <returns>\n    /// A value obtained by a right associative application of all functions \n    /// returned by op to the values returned by p\n    /// </returns>\n    public static Parser<T> chainr1<T>(Parser<T> p, Parser<Func<T, T, T>> op)\n    {\n        Parser<T> scan = null;\n\n        var rest = fun((T x) => either(from f in op\n                                       from y in scan\n                                       select f(x, y),\n                                       result(x)));\n\n        scan = from x in p\n               from y in rest(x)\n               select y;\n\n        return scan;\n    }\n\n    /// <summary>\n    /// chainl1(p,op) parses one or more occurrences of p, separated by op. \n    /// </summary>\n    /// <returns>\n    /// A value obtained by a left associative application of all functions \n    /// returned by op to the values returned by p\n    /// </returns>\n    public static Parser<T> chainl1<T>(Parser<T> p, Parser<Func<T, T, T>> op)\n    {\n        Func<T, Parser<T>> rest = null;\n\n        rest = fun((T x) => either(from f in op\n                                   from y in p\n                                   from r in rest(f(x, y))\n                                   select r,\n                                   result(x)));\n\n        return from x in p\n               from y in rest(x)\n               select y;\n    }\n\n    /// <summary>\n    /// This parser only succeeds at the end of the input. This is not a\n    /// primitive parser but it is defined using 'notFollowedBy'.\n    /// </summary>\n    public static readonly Parser<Unit> eof;\n\n    /// <summary>\n    /// notFollowedBy(p) only succeeds when parser p fails. This parser\n    /// does not consume any input.This parser can be used to implement the\n    /// 'longest match' rule. \n    /// </summary>\n    /// <example>For example, when recognizing keywords (for\n    /// example 'let'), we want to make sure that a keyword is not followed\n    /// by a legal identifier character, in which case the keyword is\n    /// actually an identifier(for example 'lets'). We can program this\n    /// behaviour as follows:\n    /// \n    ///     var keywordLet  = attempt (from x in str(\"let\")\n    ///                                from _ in notFollowedBy letterOrDigit\n    ///                                select x);\n    ///                                \n    /// </example>\n    public static Parser<Unit> notFollowedBy<T>(Parser<T> p, string? label = null) =>\n        attempt(\n            either(from c in attempt(from l in getPos\n                                     from r in p\n                                     select (Pos: l, Value: r))\n                   from u in unexpected<Unit>(c.Pos, label ?? c.Value.ToString())\n                   select u,\n                   result(unit)));\n\n    /// <summary>\n    /// Parse a char list and convert into a string\n    /// </summary>\n    public static Parser<string> asString(Parser<Seq<char>> p) =>\n        p.Select(x => new string(x.ToArray()));\n\n    /// <summary>\n    /// Parse a char list and convert into an integer\n    /// </summary>\n    public static Parser<Option<int>> asInteger(Parser<Seq<char>> p) =>\n        p.Select(x => parseInt(new string(x.ToArray())));\n\n    /// <summary>\n    /// Parse a char list and convert into an integer\n    /// </summary>\n    public static Parser<Option<int>> asInteger(Parser<Seq<char>> p, int fromBase) =>\n        p.Select(x => parseInt(new string(x.ToArray()), fromBase));\n\n    /// <summary>\n    /// Parse a char list and convert into an double precision floating point value\n    /// </summary>\n    public static Parser<Option<double>> asDouble(Parser<Seq<char>> p) =>\n        p.Select(x => parseDouble(new string(x.ToArray())));\n\n    /// <summary>\n    /// Parse a char list and convert into an double precision floating point value\n    /// </summary>\n    public static Parser<Option<float>> asFloat(Parser<Seq<char>> p) =>\n        p.Select(x => parseFloat(new string(x.ToArray())));\n\n    public static Parser<Seq<T>> manyUntil<T, U>(Parser<T> p, Parser<U> end)\n    {\n        Parser<Seq<T>> scan = null;\n\n        scan = either(\n            from _ in end\n            select Seq<T>.Empty,\n            from x  in p\n            from xs in scan\n            select x.Cons(xs));\n\n        return scan;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Parsers/Token.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Prim;\nusing static LanguageExt.Parsec.Char;\n\nnamespace LanguageExt.Parsec;\n\n/// <summary>\n/// A helper module to parse lexical elements (tokens)\n/// </summary>\npublic static class Token\n{\n    /// <summary>\n    ///  Given a LanguageDef, create a token parser.\n    /// \n    ///  The expression makeTokenParser(language) creates a 'GenTokenParser'\n    ///  record that contains lexical parsers that are defined using the \n    ///  definitions in the language record.\n    /// \n    ///  The use of this function is quite stylised - one imports the\n    ///  appropriate language definition and selects the lexical parsers that\n    ///  are needed from the resulting 'GenTokenParser'.\n    /// \n    ///    // The parser\n    ///    ...\n    ///  \n    ///    var expr  =  either(\n    ///                     parens(expr),\n    ///                     identifier,\n    ///                     ...\n    ///                 )\n    ///  \n    ///    // The lexer\n    ///    var lexer       = makeTokenParser(langDef)\n    ///        \n    ///    var parens      = lexer.Parens(p);\n    ///    var braces      = lexer.Braces(p);\n    ///    var identifier  = lexer.Identifier;\n    ///    var reserved    = lexer.Reserved;\n    ///    ...        \n    /// </summary>\n    public static GenTokenParser makeTokenParser(GenLanguageDef def)\n    {\n        var simpleSpace = skipMany1(satisfy(System.Char.IsWhiteSpace));\n\n        Parser<Unit>       multiLineComment = null;\n        Parser<Unit>       inCommentMulti   = null;\n        Parser<Unit>       inCommentSingle  = null;\n        Func<string, bool> isReservedName   = null;\n\n        var startEnd = List.append(def.CommentEnd.ToArray(), def.CommentStart.ToArray()).Distinct().ToArray();\n\n        inCommentMulti =\n            choice(\n                    from x in attempt(str(def.CommentEnd))\n                    select unit,\n                    from x in lazyp(() => multiLineComment)\n                    from y in inCommentMulti\n                    select unit,\n                    from x in skipMany1(noneOf(startEnd))\n                    from y in inCommentMulti\n                    select unit,\n                    from x in oneOf(startEnd)\n                    from y in inCommentMulti\n                    select unit)\n               .label(\"end of comment\");\n\n        inCommentSingle =\n            choice(\n                    from x in attempt(str(def.CommentEnd))\n                    select unit,\n                    from x in skipMany1(noneOf(startEnd))\n                    from y in inCommentSingle\n                    select unit,\n                    from x in oneOf(startEnd)\n                    from y in inCommentSingle\n                    select unit)\n               .label(\"end of comment\");\n\n\n        var inComment = def.NestedComments\n                            ? inCommentMulti\n                            : inCommentSingle;\n\n        multiLineComment =\n            from x in attempt(str(def.CommentStart))\n            from _ in inComment\n            select unit;\n\n        var oneLineComment =\n            from x in attempt(str(def.CommentLine))\n            from _ in skipMany(satisfy(c => c != '\\n'))\n            select unit;\n\n        var whiteSpace =\n            def.CommentLine == null && def.CommentStart == null ? skipMany(simpleSpace.label(\"\"))\n            : def.CommentStart == null                          ? skipMany(either(simpleSpace, multiLineComment).label(\"\"))\n            : def.CommentLine  == null                          ? skipMany(either(simpleSpace, oneLineComment).label(\"\"))\n                                                                  : skipMany(choice(simpleSpace, oneLineComment, multiLineComment).label(\"\"));\n\n        var lexemeStr      = lexemeDef<string>(whiteSpace);\n        var lexemeCh       = lexemeDef<char>(whiteSpace);\n        var lexemeInt      = lexemeDef<int>(whiteSpace);\n        var lexemeDbl      = lexemeDef<double>(whiteSpace);\n        var lexemeUnit     = lexemeDef<Unit>(whiteSpace);\n        var lexemeFnIntInt = lexemeDef<Func<int,int>>(whiteSpace);\n        var lexemeEiIntDbl = lexemeDef<Either<int,double>>(whiteSpace);\n\n        var symbol = fun((string name) => lexemeStr(str(name)));\n\n        var semi  = symbol(\";\");\n        var comma = symbol(\",\");\n        var dot   = symbol(\".\");\n        var colon = symbol(\":\");\n\n        var dec = from x in many1(digit)\n                  let v = parseInt(new string(x.ToArray()))\n                  from n in v.Match(\n                      Some: result,\n                      None: () => failure<int>(\"Not a valid decimal value\"))\n                  select n;\n\n        var octal = (from _ in ch('o')\n                     from x in many1(octDigit)\n                     let v = parseInt(new string(x.ToArray()), 8)\n                     from n in v.Match(\n                         Some: result,\n                         None: () => failure<int>(\"Not a valid octal value\"))\n                     select n)\n           .label(\"octal number\");\n\n        var hexadecimal = (from _ in ch('x')\n                           from x in many1(hexDigit)\n                           let v = parseInt(new string(x.ToArray()), 16)\n                           from n in v.Match(\n                               Some: result,\n                               None: () => failure<int>(\"Not a valid hexadecimal value\"))\n                           select n)\n           .label(\"hexadecimal number\");\n\n        var zeroNumber = (from _ in ch('0')\n                          from r in choice(hexadecimal, octal, dec, result(0))\n                          select r)\n           .label(\"\");\n\n        var nat = either(zeroNumber, dec);\n\n        var sign = choice(from _ in ch('-')\n                          select fun((double d) => -d),\n                          from _ in ch('+')\n                          select fun((double d) => d),\n                          result(fun((double d) => d)));\n\n        var signi = choice(from _ in ch('-')\n                           select fun((int d) => -d),\n                           from _ in ch('+')\n                           select fun((int d) => d),\n                           result(fun((int d) => d)));\n\n        var int_ = from f in lexemeFnIntInt(signi)\n                   from n in nat\n                   select f(n);\n\n        var charEsc = choice(escMap.Map(pair => parseEsc(pair.Item1, pair.Item2)));\n\n        var charNum = choice(dec, hexadecimal, octal)\n                     .Map(System.Char.ConvertFromUtf32)\n                     .Map(x => x[0]);\n\n        var charControl = from _ in ch('^')\n                          from c in upper\n                          select (char)(c - 64);\n\n        var escapeCode = choice(charEsc, charNum, charControl).label(\"escape code\");\n\n        var charEscape = from _ in ch('\\\\')\n                         from c in escapeCode\n                         select c;\n\n        var charLetter = satisfy(c => c != '\\'' && c != '\\\\' && c > 26);\n\n        var characterChar = either(charLetter, charEscape).label(\"literal character\");\n\n        var charLiteral =\n            lexemeCh(\n                    between(\n                        ch('\\''),\n                        ch('\\'').label(\"end of character\"),\n                        characterChar))\n               .label(\"character\");\n\n        var stringLetter = satisfy(c => c != '\"' && c != '\\\\' && c > 26);\n\n        var escapeGap = (from _ in many1(space)\n                         from c in ch('\\\\')\n                         select c)\n           .label(\"end of string gap\");\n\n        var escapeEmpty = ch('&');\n\n        var stringEscape = from _ in ch('\\\\')\n                           from esc in choice(\n                               from x in escapeGap\n                               select Option<char>.None,\n                               from x in escapeEmpty\n                               select Option<char>.None,\n                               from c in escapeCode\n                               select Some(c))\n                           select esc;\n\n\n        var stringChar =\n            either(from c in stringLetter\n                   select Some(c),\n                   stringEscape)\n               .label(\"string character\");\n\n\n        var stringLiteral =\n            lexemeStr(\n                    from s in between(\n                        ch('\"'),\n                        ch('\"'),\n                        many(stringChar)\n                    )\n                    select new string(s.Somes().ToArray()))\n               .label(\"literal string\");\n\n        // -1.05e+003 - optional fractional part\n        var floating = from si in optionOrElse(\"\", oneOf(\"+-\").Select(static x => x.ToString()))\n                       from nu in asString(many(digit))\n                       from frac in optionOrElse(\"\",\n                                                 from pt in dot\n                                                 from fr in asString(many(digit))\n                                                 from ex in optionOrElse(\"\",\n                                                                         from e in oneOf(\"eE\")\n                                                                         from s in oneOf(\"+-\")\n                                                                         from n in asString(many1(digit))\n                                                                         select $\"{e}{s}{n}\"\n                                                 )\n                                                 select $\"{pt}{fr}{ex}\")\n                       let all = $\"{si}{nu}{frac}\"\n                       let opt = parseDouble(all)\n                       from res in opt.Match(\n                           result,\n                           () => failure<double>(\"Invalid floating point value\")\n                       )\n                       select res;\n\n        // -1.05e+003 - must have fractional part\n        var fracfloat = from si in optionOrElse(\"\", from x in oneOf(\"+-\") select x.ToString())\n                        from nu in asString(many(digit))\n                        from frac in from pt in dot\n                                     from fr in asString(many(digit))\n                                     from ex in optionOrElse(\"\",\n                                                             from e in oneOf(\"eE\")\n                                                             from s in oneOf(\"+-\")\n                                                             from n in asString(many1(digit))\n                                                             select $\"{e}{s}{n}\"\n                                     )\n                                     select $\"{pt}{fr}{ex}\"\n                        let all = $\"{si}{nu}{frac}\"\n                        let opt = parseDouble(all)\n                        from res in opt.Match(\n                            result,\n                            () => failure<double>(\"Invalid floating point value\")\n                        )\n                        select res;\n            \n        var natural = lexemeInt(nat).label(\"natural\");\n        var integer = lexemeInt(int_).label(\"integer\");\n        var float_  = lexemeDbl(floating).label(\"float\");\n        var naturalOrFloat = either(attempt(lexemeDbl(fracfloat)).Map(Right<int, double>), \n                                    integer.Map(Left<int, double>)).label(\"number\");\n\n        var reservedOp = fun((string name) =>\n                                 lexemeUnit(\n                                     attempt(\n                                         from n in str(name)\n                                         from _ in notFollowedBy(def.OpLetter).label(\"end of \" + name)\n                                         select unit)));\n\n        var oper = (from c in def.OpStart\n                    from cs in many(def.OpLetter)\n                    select new string(c.Cons(cs).ToArray()))\n           .label(\"operator\");\n\n        var operator_ =\n            lexemeStr(\n                attempt(\n                    from name in oper\n                    from op in def.ReservedOpNames.Contains(name)\n                                   ? unexpected<string>(\"reserved operator \" + name)\n                                   : result(name)\n                    select op));\n\n        var theReservedNames =\n            def.CaseSensitive\n                ? def.ReservedNames\n                : def.ReservedNames.Map(x => x.ToLower()).ToLst();\n\n        var isReserved = fun((Lst<string> names, string name) =>\n                                 names.Contains(\n                                     def.CaseSensitive\n                                         ? name\n                                         : name.ToLower()));\n\n        isReservedName = fun((string name) =>\n                                 isReserved(theReservedNames, name));\n\n        var ident = (from c in def.IdentStart\n                     from cs in many(def.IdentLetter)\n                     select new string(c.Cons(cs).ToArray()))\n           .label(\"identifier\");\n\n        var identifier = lexemeStr(\n            attempt(\n                from name in ident\n                from r in isReservedName(name)\n                              ? unexpected<string>(\"reserved word \" + name)\n                              : result(name)\n                select r));\n\n        var caseString = fun((string name) => str(name));\n        //def.CaseSensitive\n        //    ? str(name)\n        //    : /* TODO - fully implement case insensitive version*/);\n\n        var reserved = fun((string name) =>\n                               lexemeStr(\n                                   attempt(\n                                       from x in caseString(name)\n                                       from _ in notFollowedBy(def.IdentLetter).label(\"end of \" + name)\n                                       select x)));\n\n        return new GenTokenParser(\n            identifier,\n            reserved,\n            operator_,\n            reservedOp,\n            charLiteral,\n            stringLiteral,\n            natural,\n            integer,\n            float_,\n            naturalOrFloat,\n            lexemeInt(dec),\n            lexemeInt(hexadecimal),\n            lexemeInt(octal),\n            symbol,\n            whiteSpace,\n            semi,\n            comma,\n            colon,\n            dot\n        );\n    }\n\n    static Func<Parser<T>, Parser<T>> lexemeDef<T>(Parser<Unit> whiteSpace)\n    {\n        var ws = whiteSpace;\n        return (Parser<T> p) =>\n                   from x in p\n                   from _ in ws\n                   select x;\n    }\n\n    static Parser<T> parseEsc<T>(char c, T code) =>\n        from _ in ch(c)\n        select code;\n\n    static readonly Seq<(char, char)> escMap =\n        toSeq(List.zip(\"abfnrtv\\\\\\\"\\'\", \"\\a\\b\\f\\n\\r\\t\\v\\\\\\\"\\'\").ToArray());\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Parsers/Token2.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Prim;\nusing static LanguageExt.Parsec.Char;\n\nnamespace LanguageExt.Parsec;\n\n/// <summary>\n/// A helper module to parse lexical elements (tokens)\n/// </summary>\npublic static class Token2\n{\n    /// <summary>\n    ///  Given a LanguageDef, create a token parser.\n    /// \n    ///  The expression makeTokenParser(language) creates a 'GenTokenParser'\n    ///  record that contains lexical parsers that are defined using the \n    ///  definitions in the language record.\n    /// \n    ///  The use of this function is quite stylised - one imports the\n    ///  appropriate language definition and selects the lexical parsers that\n    ///  are needed from the resulting 'GenTokenParser'.\n    /// \n    ///    // The parser\n    ///    ...\n    ///  \n    ///    var expr  =  either(\n    ///                     parens(expr),\n    ///                     identifier,\n    ///                     ...\n    ///                 )\n    ///  \n    ///    // The lexer\n    ///    var lexer       = makeTokenParser(langDef)\n    ///        \n    ///    var parens      = lexer.Parens(p);\n    ///    var braces      = lexer.Braces(p);\n    ///    var identifier  = lexer.Identifier;\n    ///    var reserved    = lexer.Reserved;\n    ///    ...        \n    /// </summary>\n    public static GenTokenParser2 makeTokenParser(GenLanguageDef def)\n    {\n        var simpleSpace = skipMany1(satisfy(System.Char.IsWhiteSpace));\n\n        Parser<Unit>       multiLineComment = null;\n        Parser<Unit>       inCommentMulti   = null;\n        Parser<Unit>       inCommentSingle  = null;\n        Func<string, bool> isReservedName   = null;\n\n        var startEnd = List.append(def.CommentEnd.ToArray(), def.CommentStart.ToArray()).Distinct().ToArray();\n\n        inCommentMulti =\n            choice(\n                    from x in attempt(str(def.CommentEnd))\n                    select unit,\n                    from x in lazyp(() => multiLineComment)\n                    from y in inCommentMulti\n                    select unit,\n                    from x in skipMany1(noneOf(startEnd))\n                    from y in inCommentMulti\n                    select unit,\n                    from x in oneOf(startEnd)\n                    from y in inCommentMulti\n                    select unit)\n               .label(\"end of comment\");\n\n        inCommentSingle =\n            choice(\n                    from x in attempt(str(def.CommentEnd))\n                    select unit,\n                    from x in skipMany1(noneOf(startEnd))\n                    from y in inCommentSingle\n                    select unit,\n                    from x in oneOf(startEnd)\n                    from y in inCommentSingle\n                    select unit)\n               .label(\"end of comment\");\n\n\n        var inComment = def.NestedComments\n                            ? inCommentMulti\n                            : inCommentSingle;\n\n        multiLineComment =\n            from x in attempt(str(def.CommentStart))\n            from _ in inComment\n            select unit;\n\n        var oneLineComment =\n            from x in attempt(str(def.CommentLine))\n            from _ in skipMany(satisfy(c => c != '\\n'))\n            select unit;\n\n        var whiteSpace =\n            def.CommentLine == null && def.CommentStart == null ? skipMany(simpleSpace.label(\"\"))\n            : def.CommentStart == null                          ? skipMany(either(simpleSpace, multiLineComment).label(\"\"))\n            : def.CommentLine  == null                          ? skipMany(either(simpleSpace, oneLineComment).label(\"\"))\n                                                                  : skipMany(choice(simpleSpace, oneLineComment, multiLineComment).label(\"\"));\n\n        var lexemeStr      = lexemeDef<string>(whiteSpace);\n        var lexemeCh       = lexemeDef<char>(whiteSpace);\n        var lexemeInt      = lexemeDef<int>(whiteSpace);\n        var lexemeDbl      = lexemeDef<double>(whiteSpace);\n        var lexemeUnit     = lexemeDef<Unit>(whiteSpace);\n        var lexemeFnIntInt = lexemeDef<Func<int, int>>(whiteSpace);\n        var lexemeEiIntDbl = lexemeDef<Either<int, double>>(whiteSpace);\n\n        var symbol = fun((string name) => lexemeStr(str(name)));\n\n        var semi  = symbol(\";\");\n        var comma = symbol(\",\");\n        var dot   = symbol(\".\");\n        var colon = symbol(\":\");\n\n        var dec = from x in many1(digit)\n                  let v = parseInt(new string(x.ToArray()))\n                  from n in v.Match(\n                      Some: result,\n                      None: () => failure<int>(\"Not a valid decimal value\"))\n                  select n;\n\n        var octal = (from _ in ch('o')\n                     from x in many1(octDigit)\n                     let v = parseInt(new string(x.ToArray()), 8)\n                     from n in v.Match(\n                         Some: result,\n                         None: () => failure<int>(\"Not a valid octal value\"))\n                     select n)\n           .label(\"octal number\");\n\n        var hexadecimal = (from _ in ch('x')\n                           from x in many1(hexDigit)\n                           let v = parseInt(new string(x.ToArray()), 16)\n                           from n in v.Match(\n                               Some: result,\n                               None: () => failure<int>(\"Not a valid hexadecimal value\"))\n                           select n)\n           .label(\"hexadecimal number\");\n\n        var zeroNumber = (from _ in ch('0')\n                          from r in choice(hexadecimal, octal, dec, result(0))\n                          select r)\n           .label(\"\");\n\n        var nat = either(zeroNumber, dec);\n\n        var int_ = from f in optional(oneOf(\"+-\"))\n                   from n in nat\n                   select f == '-' ? -n : n;\n\n        var charEsc = choice(escMap.Map(pair => parseEsc(pair.Item1, pair.Item2)));\n\n        var charNum = choice(dec, hexadecimal, octal)\n                     .Map(System.Char.ConvertFromUtf32)\n                     .Map(x => x[0]);\n\n        var charControl = from _ in ch('^')\n                          from c in upper\n                          select (char)(c - 64);\n\n        var escapeCode = choice(charEsc, charNum, charControl).label(\"escape code\");\n\n        var charEscape = from _ in ch('\\\\')\n                         from c in escapeCode\n                         select c;\n\n        var charLetter = satisfy(c => c != '\\'' && c != '\\\\' && c > 26);\n\n        var characterChar = either(charLetter, charEscape).label(\"literal character\");\n\n        var charLiteral =\n            lexemeCh(\n                    between(\n                        ch('\\''),\n                        ch('\\'').label(\"end of character\"),\n                        characterChar))\n               .label(\"character\");\n\n        var stringLetter = satisfy(c => c != '\"' && c != '\\\\' && c > 26);\n\n        var escapeGap = (from _ in many1(space)\n                         from c in ch('\\\\')\n                         select c)\n           .label(\"end of string gap\");\n\n        var escapeEmpty = ch('&');\n\n        var stringEscape = from _ in ch('\\\\')\n                           from esc in choice(\n                               from x in escapeGap\n                               select Option<char>.None,\n                               from x in escapeEmpty\n                               select Option<char>.None,\n                               from c in escapeCode\n                               select Some(c))\n                           select esc;\n\n\n        var stringChar =\n            either(from c in stringLetter\n                   select Some(c),\n                   stringEscape)\n               .label(\"string character\");\n\n\n        var stringLiteral =\n            lexemeStr(\n                    from s in between(\n                        ch('\"'),\n                        ch('\"'),\n                        many(stringChar)\n                    )\n                    select new string(s.Somes().ToArray()))\n               .label(\"literal string\");\n\n        // -1.05e+003 - optional fractional part\n        var floating = from si in optionOrElse(\"\", oneOf(\"+-\").Select(static x => x.ToString()))\n                       from nu in asString(many(digit))\n                       from frac in optionOrElse(\"\",\n                                                 from pt in dot\n                                                 from fr in asString(many(digit))\n                                                 from ex in optionOrElse(\"\",\n                                                                         from e in oneOf(\"eE\")\n                                                                         from s in oneOf(\"+-\")\n                                                                         from n in asString(many1(digit))\n                                                                         select $\"{e}{s}{n}\"\n                                                 )\n                                                 select $\"{pt}{fr}{ex}\")\n                       let all = $\"{si}{nu}{frac}\"\n                       let opt = parseDouble(all)\n                       from res in opt.Match(\n                           result,\n                           static () => failure<double>(\"Invalid floating point value\")\n                       )\n                       select res;\n\n        // -1.05e+003 - must have fractional part\n        var fracfloat = from si in optionOrElse(\"\", from x in oneOf(\"+-\") select x.ToString())\n                        from nu in asString(many(digit))\n                        from frac in from pt in dot\n                                     from fr in asString(many(digit))\n                                     from ex in optionOrElse(\"\",\n                                                             from e in oneOf(\"eE\")\n                                                             from s in oneOf(\"+-\")\n                                                             from n in asString(many1(digit))\n                                                             select $\"{e}{s}{n}\"\n                                     )\n                                     select $\"{pt}{fr}{ex}\"\n                        let all = $\"{si}{nu}{frac}\"\n                        let opt = parseDouble(all)\n                        from res in opt.Match(\n                            result,\n                            static () => failure<double>(\"Invalid floating point value\")\n                        )\n                        select res;\n            \n        var natural = lexemeInt(nat).label(\"natural\");\n        var integer = lexemeInt(int_).label(\"integer\");\n        var float_  = lexemeDbl(floating).label(\"float\");\n        var naturalOrFloat = either(\n            attempt(lexemeDbl(fracfloat)).Map(static x => (Right<int, double>(x.Value), x.BeginPos, x.EndPos, x.BeginIndex, x.EndIndex)),\n            integer.Map(static x => (Left<int, double>(x.Value), x.BeginPos, x.EndPos, x.BeginIndex, x.EndIndex))).label(\"number\");\n\n        var reservedOp = fun((string name) =>\n                                 lexemeUnit(\n                                     attempt(\n                                         from n in str(name)\n                                         from _ in notFollowedBy(def.OpLetter).label(\"end of \" + name)\n                                         select unit)));\n\n        var oper = (from c in def.OpStart\n                    from cs in many(def.OpLetter)\n                    select new string(c.Cons(cs).ToArray()))\n           .label(\"operator\");\n\n        var operator_ =\n            lexemeStr(\n                attempt(\n                    from name in oper\n                    from op in def.ReservedOpNames.Contains(name)\n                                   ? unexpected<string>(\"reserved operator \" + name)\n                                   : result(name)\n                    select op));\n\n        var theReservedNames =\n            def.CaseSensitive\n                ? def.ReservedNames\n                : def.ReservedNames.Map(x => x.ToLower()).ToLst();\n\n        var isReserved = fun((Lst<string> names, string name) =>\n                                 names.Contains(\n                                     def.CaseSensitive\n                                         ? name\n                                         : name.ToLower()));\n\n        isReservedName = fun((string name) =>\n                                 isReserved(theReservedNames, name));\n\n        var ident = (from c in def.IdentStart\n                     from cs in many(def.IdentLetter)\n                     select new string(c.Cons(cs).ToArray()))\n           .label(\"identifier\");\n\n        var identifier = lexemeStr(\n            attempt(\n                from name in ident\n                from r in isReservedName(name)\n                              ? unexpected<string>(\"reserved word \" + name)\n                              : result(name)\n                select r));\n\n        var caseString = fun((string name) => str(name));\n        //def.CaseSensitive\n        //    ? str(name)\n        //    : /* TODO - fully implement case insensitive version*/);\n\n        var reserved = fun((string name) =>\n                               lexemeStr(\n                                   attempt(\n                                       from x in caseString(name)\n                                       from _ in notFollowedBy(def.IdentLetter).label(\"end of \" + name)\n                                       select x)));\n\n        return new GenTokenParser2(\n            identifier,\n            reserved,\n            operator_,\n            reservedOp,\n            charLiteral,\n            stringLiteral,\n            natural,\n            integer,\n            float_,\n            naturalOrFloat,\n            lexemeInt(dec),\n            lexemeInt(hexadecimal),\n            lexemeInt(octal),\n            symbol,\n            whiteSpace,\n            semi,\n            comma,\n            colon,\n            dot\n        );\n    }\n\n    static Func<Parser<A>, Parser<A>> lexemeDef_OLD<A>(Parser<Unit> whiteSpace)\n    {\n        var ws = whiteSpace;\n        return (Parser<A> p) =>\n                   from x in p\n                   from _ in ws\n                   select x;\n    }\n        \n    internal static Func<Parser<A>, Parser<(A Value, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>> lexemeDef<A>(Parser<Unit> whiteSpace) =>\n        p =>\n            new Parser<(A T, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>(\n                inp =>\n                {\n                    var bi = inp.Index;\n                    var bp = inp.Pos;\n                    var xr = p(inp);\n                    if (xr.Reply.Tag == ReplyTag.OK)\n                    {\n                        var ei = xr.Reply.State.Index;\n                        var ep = xr.Reply.State.Pos;\n\n                        var wr = whiteSpace(xr.Reply.State);\n\n                        return (wr.Reply.Tag, wr.Tag) switch\n                               {\n                                   (ReplyTag.OK, ResultTag.Consumed)    => ParserResult.ConsumedOK((xr.Reply.Result, bp, ep, bi, ei), wr.Reply.State, xr.Reply.Error),\n                                   (ReplyTag.OK, ResultTag.Empty)       => ParserResult.ConsumedOK((xr.Reply.Result, bp, ep, bi, ei), wr.Reply.State, xr.Reply.Error),\n                                   (ReplyTag.Error, ResultTag.Consumed) => ParserResult.ConsumedError<(A T, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>(wr.Reply.Error),\n                                   (ReplyTag.Error, ResultTag.Empty)    => ParserResult.EmptyError<(A T, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>(wr.Reply.Error),\n                                   _                                    => throw new NotSupportedException()\n                               };\n                    }\n                    else\n                    {\n                        return xr.Tag switch\n                               {\n                                   ResultTag.Consumed => ParserResult.ConsumedError<(A T, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>(xr.Reply.Error),\n                                   ResultTag.Empty    => ParserResult.EmptyError<(A T, Pos BeginPos, Pos EndPos, int BeginIndex, int EndIndex)>(xr.Reply.Error),\n                                   _                  => throw new NotSupportedException()\n                               };\n                    }\n                });\n\n    static Parser<A> parseEsc<A>(char c, A code) =>\n        ch(c).Map(_ => code);\n\n    static readonly Seq<(char, char)> escMap =\n        toSeq(List.zip(\"abfnrtv\\\\\\\"\\'\", \"\\a\\b\\f\\n\\r\\t\\v\\\\\\\"\\'\").ToArray());\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Pipes.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Parsec;\nusing static LanguageExt.Prelude;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class ParsecPipes\n{\n    /// <summary>\n    /// Pipe a string to a PString\n    /// </summary>\n    public static PipeT<string, PString, M, Unit> toParserStringT<M>()\n        where M : MonadIO<M> =>\n        PipeT.map<M, string, PString>(x => PString.Zero.SetValue(x));\n\n    /// <summary>\n    /// Pipe tokens to a PString\n    /// </summary>\n    public static PipeT<A[], PString<A>, M, Unit> toTokenStringT<M, A>(Func<A, Pos>? tokenPos) \n        where M : MonadIO<M> =>\n        PipeT.map<M, A[], PString<A>>(xs => new PString<A>(xs, 0, xs.Length, None, tokenPos ?? (_ => Pos.Zero)));\n    \n    /// <summary>\n    /// Pipe a string to a PString\n    /// </summary>\n    public static Pipe<RT, string, PString, Unit> toParserString<RT>() =>\n        Pipe.map<RT, string, PString>(x => PString.Zero.SetValue(x));\n\n    /// <summary>\n    /// Pipe tokens to a PString\n    /// </summary>\n    public static Pipe<RT, A[], PString<A>, Unit> toTokenString<RT, A>(Func<A, Pos>? tokenPos) =>\n        Pipe.map<RT, A[], PString<A>>(xs => new PString<A>(xs, 0, xs.Length, None, tokenPos ?? (_ => Pos.Zero)));\n\n    /// <summary>\n    /// Convert a parser to a pipe that awaits a PString and yields the result of the parse operation\n    /// If the parser fails then the pipe fails\n    /// </summary>\n    public static PipeT<PString, OUT, M, Unit> ToPipeT<M, OUT>(this Parser<OUT> ma)\n        where M : MonadIO<M> =>\n        from t in PipeT.awaiting<M, PString, OUT>()\n        from r in ma.Parse(t).ToEither() switch\n                  {\n                      Either<string, OUT>.Right (var x) => IO.pure(x),\n                      Either<string, OUT>.Left (var e)  => IO.fail<OUT>(Errors.ParseError(e)),\n                      _                                 => throw new NotSupportedException()\n                  }\n        from _ in PipeT.yield<M, PString, OUT>(r)\n        select unit;\n\n    /// <summary>\n    /// Convert a parser to a pipe that awaits a string and yields the result of the parse operation\n    /// The value is only forwarded if the parsing succeeds\n    /// </summary>\n    public static PipeT<PString<IN>, OUT, M, Unit> ToPipeT<M, IN, OUT>(this Parser<IN, OUT> ma) \n        where M : MonadIO<M> =>\n        from t in PipeT.awaiting<M, PString<IN>, OUT>()\n        from _ in ma.Parse(t).ToEither() switch\n                  {\n                      Either<string, OUT>.Right (var x) => PipeT.yield<M, PString<IN>, OUT>(x),\n                      Either<string, OUT>.Left          => Pure<Unit>(default),\n                      _                                 => throw new NotSupportedException()\n                  }\n        select unit;\n    \n\n    /// <summary>\n    /// Convert a parser to a pipe that awaits a PString and yields the result of the parse operation\n    /// If the parser fails then the pipe fails\n    /// </summary>\n    public static Pipe<RT, PString, OUT, Unit> ToPipe<RT, OUT>(this Parser<OUT> ma) =>\n        from t in Pipe.awaiting<RT, PString, OUT>()\n        from r in ma.Parse(t).ToEither() switch\n                  {\n                      Either<string, OUT>.Right (var x) => IO.pure(x),\n                      Either<string, OUT>.Left (var e)  => IO.fail<OUT>(Errors.ParseError(e)),\n                      _                                 => throw new NotSupportedException()\n                  }\n        from _ in Pipe.yield<RT, PString, OUT>(r)\n        select unit;\n\n    /// <summary>\n    /// Convert a parser to a pipe that awaits a string and yields the result of the parse operation\n    /// The value is only forwarded if the parsing succeeds\n    /// </summary>\n    public static Pipe<RT, PString<IN>, OUT, Unit> ToPipe<RT, IN, OUT>(this Parser<IN, OUT> ma) =>\n        from t in Pipe.awaiting<RT, PString<IN>, OUT>()\n        from _ in ma.Parse(t).ToEither() switch\n                  {\n                      Either<string, OUT>.Right (var x) => Pipe.yield<RT, PString<IN>, OUT>(x),\n                      Either<string, OUT>.Left          => Pure<Unit>(default),\n                      _                                 => throw new NotSupportedException()\n                  }\n        select unit;    \n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Pos.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.Parsec\n{\n    /// <summary>\n    /// Represents a parser source position\n    /// </summary>\n    public class Pos : IEquatable<Pos>, IComparable<Pos>\n    {\n        public readonly int Line;\n        public readonly int Column;\n\n        public Pos(int line, int column)\n        {\n            Line = line;\n            Column = column;\n        }\n\n        public static readonly Pos Zero = new Pos(0, 0);\n\n        public bool Equals(Pos? other) =>\n            other is not null &&\n            Line == other.Line &&\n            Column == other.Column;\n\n        public override bool Equals(object? obj) =>\n            ((obj as Pos)?.Equals(this)).GetValueOrDefault();\n\n        public override int GetHashCode() =>\n            Tuple.Create(Line, Column).GetHashCode();\n\n        public override string ToString() =>\n            $\"(line {Line + 1}, column {Column + 1})\";\n\n        public int CompareTo(Pos? other) =>\n            other is null\n                ? 1\n                : Line < other.Line\n                    ? -1\n                    : Line > other.Line\n                        ? 1\n                        : Column.CompareTo(other.Column);\n\n        public static bool operator ==(Pos lhs, Pos rhs) =>\n            lhs.Equals(rhs);\n\n        public static bool operator !=(Pos lhs, Pos rhs) =>\n            !lhs.Equals(rhs);\n\n        public static bool operator < (Pos lhs, Pos rhs) =>\n            lhs.CompareTo(rhs) < 0;\n\n        public static bool operator >(Pos lhs, Pos rhs) =>\n            lhs.CompareTo(rhs) > 0;\n\n        public static bool operator <=(Pos lhs, Pos rhs) =>\n            lhs.CompareTo(rhs) <= 0;\n\n        public static bool operator >=(Pos lhs, Pos rhs) =>\n            lhs.CompareTo(rhs) >= 0;\n\n        public static R Compare<R>(\n            Pos lhs,\n            Pos rhs,\n            Func<R> EQ,\n            Func<R> GT,\n            Func<R> LT\n            )\n        {\n            var res = lhs.CompareTo(rhs);\n            if( res < 0)\n            {\n                return LT();\n            }\n            if (res > 0)\n            {\n                return GT();\n            }\n            return EQ();\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/README.nuget.md",
    "content": "# LanguageExt.Parsec\n\n`LanguageExt.Parsec` are the parser-combinators for the [language-ext functional programming framework](https://github.com/louthy/language-ext).\n\nThe framework uses and abuses the features of C# to provide a pure functional-programming \n'Base Class Library' that, if you squint, can look like extensions to the language itself. \nThe desire here is to make programming in C# much more robust by helping the engineer's \ninertia flow in the direction of declarative and pure functional code rather than imperative. \n\nUsing these techniques for large code-bases can bring tangible benefits to long-term maintenance \nby removing hidden complexity and by easing the engineer's cognitive load.\n\n## Features\n\n### [Functional effects and IO](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/index.html)\n\n| Location | Feature      | Description                                                                                                                                                                                              |\n|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `IO<A>`      | [A synchronous and asynchronous side-effect: an IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/IO/index.html)                                                                  |\n| `Core`   | `Eff<A>`     | [A synchronous and asynchronous side-effect with error handling](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20no%20runtime/index.html)                                       |\n| `Core`   | `Eff<RT, A>` | [Same as `Eff<A>` but with an injectable runtime for dependency-injection: a unit testable IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20with%20runtime/index.html) |\n| `Core`   | Pipes        | [A clean and powerful stream processing system that lets you build and connect reusable streaming components](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Pipes/index.html)           |\n| `Core`   | StreamT      | [less powerful (than Pipes), but easier to use streaming effects transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/StreamT/index.html)                                         |\n\n### [Atomic concurrency and collections](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/index.html)\n\n| Location | Feature                            | Description                                                                                                                                            |\n|----------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Atom<A>`                          | [A lock-free atomically mutable reference for working with shared state](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/Atom)      |\n| `Core`   | `Ref<A>`                           | [An atomic reference to be used in the transactional memory system](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/STM)            |\n| `Core`   | `AtomHashMap<K, V>`                | [An immutable `HashMap` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomHashMap) |\n| `Core`   | `AtomSeq<A>`                       | [An immutable `Seq` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomSeq)         |\n| `Core`   | `VectorClock<A>`                   | [Understand distributed causality](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VectorClock)                                     |\n| `Core`   | `VersionVector<A>`                 | [A vector clock with some versioned data](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionVector)                            |\n| `Core`   | `VersionHashMap <ConflictV, K, V>` | [Distrubuted atomic versioning of keys in a hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionHashMap)               |\n\n### [Immutable collections](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/index.html)\n\n| Location | Feature              | Description                                                                                                                                                                                                             |\n|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Arr<A>`             | [Immutable array](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Arr/index.html)                                                                                                        |\n| `Core`   | `Seq<A>`             | [Lazy immutable list, evaluate at-most-once](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Seq/index.html) - very, very fast!                                                          |\n| `Core`   | `Iterable<A>`        | [Wrapper around `IEnumerable` with support for traits](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Iterable/index.html) - enables the higher-kinded traits to work with enumerables. |\n| `Core`   | `Lst<A>`             | [Immutable list](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/List/index.html) - use `Seq` over `Lst` unless you need `InsertAt`                                                      |\n| `Core`   | `Map<K, V>`          | [Immutable map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                                                          |\n| `Core`   | `Map<OrdK, K, V>`    | [Immutable map with Ord constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                               |\n| `Core`   | `HashMap<K, V>`      | [Immutable hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                                                 |\n| `Core`   | `HashMap<EqK, K, V>` | [Immutable hash-map with Eq constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                       |\n| `Core`   | `Set<A>`             | [Immutable set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                                                          |\n| `Core`   | `Set<OrdA, A>`       | [Immutable set with Ord constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                               |\n| `Core`   | `HashSet<A>`         | [Immutable hash-set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                                                 |\n| `Core`   | `HashSet<EqA, A>`    | [Immutable hash-set with Eq constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                       |\n| `Core`   | `Que<A>`             | [Immutable queue](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Queue/index.html)                                                                                                      |\n| `Core`   | `Stck<A>`            | [Immutable stack](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Stack/index.html)                                                                                                      |\n\n### [Optional and alternative value monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/index.html)\n\n| Location | Feature                         | Description                                                                                                                                                                                              |\n|----------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Option<A>`                     | [Option monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Option/index.html)                                                                                     |\n| `Core`   | `OptionT<M, A>`                 | [Option monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/OptionT/index.html)                                                                        |\n| `Core`   | `Either<L,R>`                   | [Right/Left choice monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Either/index.html)                                                                          |\n| `Core`   | `EitherT<L, M, R>`              | [Right/Left choice monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/EitherT/index.html)                                                             |\n| `Core`   | `Fin<A>`                        | [`Error` handling monad, like `Either<Error, A>`](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Fin/index.html)                                                     |\n| `Core`   | `FinT<M, A>`                    | [`Error` handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/FinT/index.html)                                                                 |\n| `Core`   | `Try<A>`                        | [Exception handling monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Try/index.html)                                                                            |\n| `Core`   | `TryT<M, A>`                    | [Exception handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/TryT/index.html)                                                               |\n| `Core`   | `Validation<FAIL ,SUCCESS>`     | [Validation applicative and monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Validation/index.html) for collecting multiple errors before aborting an operation |\n| `Core`   | `ValidationT<FAIL, M, SUCCESS>` | [Validation applicative and monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/ValidationT/index.html)                                                |\n\n### [State managing monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/index.html)\n\n| Location | Feature            | Description                                                                                                                                                                             |\n|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Reader<E, A>`     | [Reader monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/Reader/index.html)                                               |\n| `Core`   | `ReaderT<E, M, A>` | [Reader monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/ReaderT/index.html)                                  |\n| `Core`   | `Writer<W, A>`     | [Writer monad that logs to a `W` constrained to be a Monoid](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/Writer/index.html) |\n| `Core`   | `WriterT<W, M, A>` | [Writer monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/WriterT/index.html)                                  |\n| `Core`   | `State<S, A>`      | [State monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/State/index.html)                                                  |\n| `Core`   | `StateT<S, M, A>`  | [State monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/StateT/index.html)                                     |\n\n### [Parser combinators](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)\n\n| Location | Feature        | Description                                                                                                                    |\n|----------|----------------|--------------------------------------------------------------------------------------------------------------------------------|\n| `Parsec` | `Parser<A>`    | [String parser monad and full parser combinators library](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html) |\n| `Parsec` | `Parser<I, O>` | [Parser monad that can work with any input stream type](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)   |\n\n### [Pretty](https://louthy.github.io/language-ext/LanguageExt.Core/Pretty/index.html)\n\n| Location | Feature  | Description                                      |\n|----------|----------|--------------------------------------------------|\n| `Core`   | `Doc<A>` | Produce nicely formatted text with smart layouts |\n\n### [Differencing](https://louthy.github.io/language-ext/LanguageExt.Core/DataTypes/Patch/index.html)\n\n| Location | Feature         | Description                                                                                                                                                                                                                          |\n|----------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Patch<EqA, A>` | Uses patch-theory to efficiently calculate the difference (`Patch.diff(list1, list2)`) between two collections of `A` and build a patch which can be applied (`Patch.apply(patch, list)`) to one to make the other (think git diff). |\n\n### [Traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/index.html)\n\nThe traits are major feature of `v5`+ language-ext that makes generic programming with higher-kinds a reality.  Check out Paul's [series on Higher Kinds](https://paullouth.com/higher-kinds-in-c-with-language-ext/) to get a deeper insight.\n\n| Location | Feature                                | Description                                                                                                                                                            |\n|----------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `MonoidK<F>`                       | [A monoid on applicative functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Alternative/index.html)                                               |\n| `Core`   | `Applicative<F>`                       | [Applicative functor](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Applicative/index.html)                                                            |\n| `Core`   | `Eq<A>`                                | [Ad-hoc equality trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Eq/index.html)                                                                   |\n| `Core`   | `Fallible<F>`                          | [Trait that describes types that can fail](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Fallible/index.html)                                          |\n| `Core`   | `Foldable<T>`                          | [Aggregation over a structure](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Foldable/index.html)                                                      |\n| `Core`   | `Functor<F>`                           | [Functor `Map`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Functor/index.html)                                                                      |\n| `Core`   | `Has<M, TRAIT>`                        | [Used in runtimes to enable DI-like capabilities](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Has/index.html)                                        |\n| `Core`   | `Hashable<A>`                          | [Ad-hoc has-a-hash-code trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Hashable/index.html)                                                      |\n| `Core`   | `Local<M, E>`                          | [Creates a local environment to run a computation ](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Local/index.html)                                    |\n| `Core`   | `Monad<M>`                             | [Monad trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/Monad/index.html)                                                                   |\n| `Core`   | `MonadT<M, N>`                         | [Monad transformer trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/MonadT/index.html)                                                      |\n| `Core`   | `Monoid<A>`                            | [A monoid is a type with an identity `Empty` and an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monoid/index.html) |\n| `Core`   | `MonoidK<M>`                           | [Equivalent of monoids for working on higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/MonoidK/index.html)                           |\n| `Core`   | `Mutates<M, OUTER_STATE, INNER_STATE>` | [Used in runtimes to enable stateful operations](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Mutates/index.html)                                     |\n| `Core`   | `Ord<A>`                               | [Ad-hoc ordering / comparisons](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Ord/index.html)                                                          |\n| `Core`   | `Range<SELF, NumOrdA, A>`              | [Abstraction of a range of values](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Range/index.html)                                                     |\n| `Core`   | `Readable<M, Env>`                     | [Generalised Reader monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Readable/index.html)                                              |\n| `Core`   | `SemigroupK<F>`                   | [A semigroup on functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                                                    |\n| `Core`   | `Semigroup<A>`                         | [Provides an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Semigroup/index.html)                                     |\n| `Core`   | `SemigroupK<M>`                        | [Equivalent of semigroups for working with higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                   |\n| `Core`   | `Stateful<M, S>`                       | [Generalised State monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Stateful/index.html)                                               |\n| `Core`   | `Traversable<T>`                       | [Traversable structures support element-wise sequencing of Applicative effects](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Traversable/index.html)  |\n| `Core`   | `Writable<M, W>`                       | [Generalised Writer monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Writable/index.html)                                              |\n\n### [Value traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Domain/index.html)\n\nThese work a little like `NewType` but they impart semantic meaning and some common operators for the underlying value.\n\n| Location | Feature                              | Description                                                                                                                                                                                                                                       |\n|----------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `DomainType<SELF, REPR>`             | Provides a mapping from `SELF` to an underlying representation: `REPR`                                                                                                                                                                            |\n| `Core`   | `Identifier <SELF>`                  | Identifiers (like IDs in databases: `PersonId` for example), they are equivalent to `DomaintType` with equality.                                                                                                                                  |\n| `Core`   | `VectorSpace<SELF, SCALAR>`          | Scalable values; can add and subtract self, but can only multiply and divide by a scalar. Can also negate.                                                                                                                                        |\n| `Core`   | `Amount <SELF, SCALAR>`              | Quantities, such as the amount of money in USD on a bank account or a file size in bytes. Derives `VectorSpace`, `IdentifierLike`, `DomainType`, and is orderable (comparable).                                                                   |\n| `Core`   | `LocusLike <SELF, SCALAR, DISTANCE>` | Works with space-like structures. Spaces have absolute and relative distances. Has an origin/zero point and derives `DomainType`, `IdentifierLike`, `AmountLike` and `VectorSpace`.  `DISTANCE` must also be an `AmountLike<SELF, REPR, SCALAR>`. |\n"
  },
  {
    "path": "LanguageExt.Parsec/Reply.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics;\n\nnamespace LanguageExt.Parsec\n{\n    public enum ReplyTag\n    {\n        OK,\n        Error\n    }\n\n    public static partial class Reply\n    {\n        public static Reply<T> OK<T>(T result, PString remaining, ParserError? error = null) =>\n            new Reply<T>(result, remaining, error);\n\n        public static Reply<T> Error<T>(ParserErrorTag tag, Pos pos, string message, Lst<string> expected) =>\n            new Reply<T>(new ParserError(tag, pos, message, expected));\n\n        public static Reply<T> Error<T>(ParserError error) =>\n            new Reply<T>(error);\n    }\n\n    public class Reply<T>\n    {\n        public readonly ReplyTag Tag;\n        public readonly T? Result;\n        public readonly PString? State;\n        public readonly ParserError? Error;\n\n        internal Reply(ParserError error)\n        {\n            Tag = ReplyTag.Error;\n            Error = error;\n            State = PString.Zero;\n        }\n\n        internal Reply(T result, PString state, ParserError? error = null)\n        {\n            Debug.Assert(notnull(result));\n\n            Tag = ReplyTag.OK;\n            State = state;\n            Result = result;\n            Error = error;\n        }\n\n        internal Reply(ReplyTag tag, T result, PString state, ParserError error)\n        {\n            Tag = tag;\n            Result = result;\n            State = state;\n            Error = error;\n        }\n\n        public Reply<U> Project<S, U>(S s, Func<S, T, U> project) =>\n            Tag == ReplyTag.Error\n                ? Reply.Error<U>(Error!)\n                : Reply.OK(project(s, Result!), State!, Error);\n\n        public Reply<U> Select<U>(Func<T, U> map) =>\n            Tag == ReplyTag.Error\n                ? Reply.Error<U>(Error!)\n                : Reply.OK(map(Result!), State!, Error);\n\n        internal Reply<T> SetEndIndex(int endIndex) =>\n            new Reply<T>(Tag, Result!, State!.SetEndIndex(endIndex), Error!);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/ReplyIO.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics;\n\nnamespace LanguageExt.Parsec\n{\n    public static partial class Reply\n    {\n        public static Reply<I, O> OK<I, O>(O result, PString<I> remaining, ParserError? error = null) =>\n            new Reply<I, O>(result, remaining, error);\n\n        public static Reply<I, O> Error<I, O>(ParserErrorTag tag, Pos pos, string message, Lst<string> expected, Func<I, Pos> tokenPos) =>\n            new Reply<I, O>(new ParserError(tag, pos, message, expected), tokenPos);\n\n        public static Reply<I, O> Error<I, O>(ParserError error, Func<I, Pos> tokenPos) =>\n            new Reply<I, O>(error, tokenPos);\n    }\n\n    public class Reply<I, O>\n    {\n        public readonly ReplyTag Tag;\n        public readonly O? Result;\n        public readonly PString<I> State;\n        public readonly ParserError? Error;\n\n        internal Reply(ParserError error, Func<I, Pos> tokenPos)\n        {\n            Tag = ReplyTag.Error;\n            Error = error;\n            State = PString<I>.Zero(tokenPos);\n        }\n\n        internal Reply(O result, PString<I> state, ParserError? error = null)\n        {\n            Debug.Assert(notnull(result));\n\n            Tag = ReplyTag.OK;\n            State = state;\n            Result = result;\n            Error = error;\n        }\n\n        internal Reply(ReplyTag tag, O result, PString<I> state, ParserError error)\n        {\n            Tag = tag;\n            Result = result;\n            State = state;\n            Error = error;\n        }\n\n        public Reply<I, U> Project<S, U>(S s, Func<S, O, U> project) =>\n            Tag == ReplyTag.Error\n                ? Reply.Error<I, U>(Error!, State.TokenPos)\n                : Reply.OK(project(s, Result!), State, Error);\n\n        public Reply<I, U> Select<U>(Func<O, U> map) =>\n            Tag == ReplyTag.Error\n                ? Reply.Error<I, U>(Error!, State.TokenPos)\n                : Reply.OK(map(Result!), State, Error);\n\n        internal Reply<I, O> SetEndIndex(int endIndex) =>\n            new Reply<I, O>(Tag, Result!, State.SetEndIndex(endIndex), Error!);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/Sidedness.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.Parsec\n{\n    public enum Sidedness\n    {\n        Onside,\n        Offside\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Parsec/StringAndCollectionExt.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt.Parsec\n{\n    public static class StringAndCollectionExtensions\n    {\n        public static PString ToPString(this string value) =>\n            PString.Zero.SetValue(value);\n\n        public static PString<T> ToPString<T>(this IEnumerable<T> value, Func<T, Pos> tokenPos) =>\n            PString<T>.Zero(tokenPos).SetValue(value.ToArray());\n\n        public static PString<T> ToPString<T>(this Seq<T> value, Func<T, Pos> tokenPos) =>\n            PString<T>.Zero(tokenPos).SetValue(value.ToArray());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Rx/Atom.Extensions.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Reactive.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class AtomExtensions\n{\n    /// <summary>\n    /// Observe changes to the `Atom`\n    /// </summary>\n    /// <param name=\"atom\">Atom to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable atom</returns>\n    [Pure]\n    public static IObservable<A> OnChange<A>(this Atom<A> atom) =>\n        Observable.FromEvent<A>(\n            add => atom.Change += new AtomChangedEvent<A>(add),\n            remove => atom.Change -= new AtomChangedEvent<A>(remove));\n\n    /// <summary>\n    /// Creates an observable that watches for changes to the `Atom`, but\n    /// also gets primed with the initial state on subscription, so there's\n    /// always at least one value that flows downstream.\n    /// </summary>\n    /// <param name=\"atom\">Atom to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable atom</returns>\n    [Pure]\n    public static IObservable<A> Latest<A>(this Atom<A> atom) =>\n        Observable.Return(atom.Value)\n                  .Merge(atom.OnChange());\n\n    /// <summary>\n    /// Observe changes to the `Atom`\n    /// </summary>\n    /// <param name=\"atom\">Atom to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable atom</returns>\n    [Pure]\n    public static IObservable<A> OnChange<M, A>(this Atom<M, A> atom) =>\n        Observable.FromEvent<A>(\n            add => atom.Change += new AtomChangedEvent<A>(add),\n            remove => atom.Change -= new AtomChangedEvent<A>(remove));\n\n    /// <summary>\n    /// Creates an observable that watches for changes to the `Atom`, but\n    /// also gets primed with the initial state on subscription, so there's\n    /// always at least one value that flows downstream.\n    /// </summary>\n    /// <param name=\"atom\">Atom to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable atom</returns>\n    [Pure]\n    public static IObservable<A> Latest<M, A>(this Atom<M, A> atom) =>\n        Observable.Return(atom.Value)\n                  .Merge(atom.OnChange());\n\n    /// <summary>\n    /// Observe changes to the `Ref`\n    /// </summary>\n    /// <param name=\"value\">Ref to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable ref</returns>\n    [Pure]\n    public static IObservable<A> OnChange<A>(this Ref<A> atom) =>\n        Observable.FromEvent<A>(\n            add => atom.Change += new AtomChangedEvent<A>(add),\n            remove => atom.Change -= new AtomChangedEvent<A>(remove));\n\n    /// <summary>\n    /// Creates an observable that watches for changes to the `Atom`, but\n    /// also gets primed with the initial state on subscription, so there's\n    /// always at least one value that flows downstream.\n    /// </summary>\n    /// <param name=\"atom\">Atom to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable atom</returns>\n    [Pure]\n    public static IObservable<A> Latest<A>(this Ref<A> atom) =>\n        Observable.Return(atom.Value)\n                  .Merge(atom.OnChange());\n\n    /// <summary>\n    /// Observe changes to the `AtomHashMap`\n    /// </summary>\n    /// <remarks>This publishes the full patch of a change, which may contain multiple\n    /// key updates (if done from within a transaction for-example).</remarks>\n    /// <param name=\"atom\">`AtomHashMap` to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable `AtomHashMap`</returns>\n    [Pure]\n    public static IObservable<HashMapPatch<K, V>> OnChange<K, V>(this AtomHashMap<K, V> atom) =>\n        Observable.FromEvent<HashMapPatch<K, V>>(\n            add    => atom.Change += new AtomHashMapChangeEvent<K, V>(add),\n            remove => atom.Change -= new AtomHashMapChangeEvent<K, V>(remove));\n\n    /// <summary>\n    /// Observe changes to the `AtomHashMap`\n    /// </summary>\n    /// <remarks>This publishes the full patch of a change, which may contain multiple\n    /// key updates (if done from within a transaction for-example).</remarks>\n    /// <param name=\"atom\">`AtomHashMap` to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable `AtomHashMap`</returns>\n    [Pure]\n    public static IObservable<HashMapPatch<EqK, K, V>> OnChange<EqK, K, V>(\n        this AtomHashMap<EqK, K, V> atom)\n        where EqK : Eq<K> =>\n        Observable.FromEvent<HashMapPatch<EqK, K, V>>(\n            add => atom.Change += new AtomHashMapChangeEvent<EqK, K, V>(add),\n            remove => atom.Change -= new AtomHashMapChangeEvent<EqK, K, V>(remove));\n\n    /// <summary>\n    /// Observe changes to the `AtomHashMap`\n    /// </summary>\n    /// <remarks>This publishes the changes to individual key-values within the `AtomHashMap`</remarks>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable `(K, Change〈V〉)`</returns>\n    [Pure]\n    public static IObservable<(K, Change<V>)> OnEntryChange<K, V>(this AtomHashMap<K, V> atom) =>\n        atom.OnChange()\n            .SelectMany(static p =>\n                            p.Changes\n                             .AsIterable()\n                             .Filter(static c => c.Value.HasChanged));\n\n    /// <summary>\n    /// Observe changes to the `AtomHashMap`\n    /// </summary>\n    /// <remarks>This publishes the changes to individual key-values within the `AtomHashMap`</remarks>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable `(K, Change〈V〉)`</returns>\n    [Pure]\n    public static IObservable<(K, Change<V>)> OnEntryChange<EqK, K, V>(this AtomHashMap<EqK, K, V> atom)\n        where EqK : Eq<K> =>\n        atom.OnChange()\n            .SelectMany(static p =>\n                            p.Changes\n                             .AsEnumerable()\n                             .Filter(static c => c.Value.HasChanged));\n\n    /// <summary>\n    /// Observe changes to the `AtomHashMap`\n    /// </summary>\n    /// <remarks>This publishes the latest state of an `AtomHashMap`</remarks>\n    /// <param name=\"atom\">`AtomHashMap` to observe</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Observable `HashMap`</returns>\n    [Pure]\n    public static IObservable<HashMap<EqK, K, V>> OnMapChange<EqK, K, V>(this AtomHashMap<EqK, K, V> atom)\n        where EqK : Eq<K> =>\n        atom.OnChange().Select(p => p.To);\n}\n"
  },
  {
    "path": "LanguageExt.Rx/Cast.cs",
    "content": "﻿\nnamespace LanguageExt\n{\n    internal static class CastExtensions\n    {\n        public static A Cast<A>(this Option<A> ma) => (A)ma;\n        public static L CastLeft<L, R>(this Either<L, R> ma) => (L)ma;\n        public static R CastRight<L, R>(this Either<L, R> ma) => (R)ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Rx/Check.cs",
    "content": "﻿namespace LanguageExt\n{\n    internal static class Check\n    {\n        internal static T NullReturn<T>(T value) =>\n            Prelude.isnull(value)\n                ? Prelude.raise<T>(new ResultIsNullException())\n                : value;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Rx/Eff.Extensions.cs",
    "content": "using System;\nusing System.Collections.Concurrent;\nusing System.Threading;\nusing LanguageExt.Common;\nusing LanguageExt.Effects;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class EffRxExtensions\n{\n    /// <summary>\n    /// Consume an observable stream\n    /// </summary>\n    /// <remarks>Each item is passed to the `next` function.  When the stream completes the Aff returns\n    /// which allows subsequent operations to be composed.</remarks>\n    /// <param name=\"ma\">Observable to consume</param>\n    /// <param name=\"next\">Next function to call</param>\n    /// <param name=\"token\">Cancellation token</param>\n    /// <typeparam name=\"A\">Bound type</typeparam>\n    /// <returns>Aff of unit</returns>\n    public static Eff<Unit> Consume<A>(\n        this IObservable<A> ma,\n        Func<A, Eff<Unit>> next) =>\n        from t in cancelTokenEff\n        from _ in Eff<Unit>.Lift(\n            () =>\n            {\n                using var  wait      = new AutoResetEvent(false);\n                var        items     = new ConcurrentQueue<A>();\n                var        done      = false;\n                Exception? exception = default;\n\n                using var disp = ma.Subscribe(\n                    onNext: x =>\n                            {\n                                items.Enqueue(x);\n                                wait.Set();\n                            },\n                    onError: e =>\n                             {\n                                 exception = e;\n                                 done = true;\n                                 wait.Set();\n                             },\n                    onCompleted: () =>\n                                 {\n                                     done = true;\n                                     wait.Set();\n                                 });\n\n                while (true)\n                {\n                    wait.WaitOne();\n                    if (done)\n                    {\n                        return unit;\n                    }\n\n                    if (t.IsCancellationRequested)\n                    {\n                        return Errors.Cancelled;\n                    }\n\n                    if (exception != null)\n                    {\n                        return Error.New(exception);\n                    }\n\n                    while (items.TryDequeue(out var item))\n                    {\n                        var res = next(item).Run();\n                        if (res.IsFail) return Fin.Fail<Unit>((Error)res);\n                    }\n                }\n            })\n        select unit;\n\n    /// <summary>\n    /// Fold an observable stream\n    /// </summary>\n    /// <remarks>Each item is passed to the `next` function, with a state value.  The state is aggregated over the\n    /// stream by passing the return value from `next` to the subsequent calls.  When the stream completes, the\n    /// aggregate state is returned.\n    /// </remarks>\n    /// <param name=\"ma\">Observable to fold</param>\n    /// <param name=\"next\">Next function to call</param>\n    /// <typeparam name=\"A\">Bound type</typeparam>\n    /// <param name=\"token\">Cancellation token</param>\n    /// <returns>Aff of S</returns>\n    public static Eff<S> Fold<S, A>(this IObservable<A> ma, S initialState, Func<S, A, Eff<S>> next)\n    {\n        var state = Atom(initialState);\n        return ma.Consume(a => next(state, a).Map(x => ignore(state.Swap(_ => x))))\n                 .Map(_ => state.Value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Rx/Either.Extensions.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Reactive.Linq;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class EitherRxExtensions\n{\n    public static IObservable<R> ToObservable<L, R>(this Either<L, R> ma) =>\n        ma.Match(_ => Observable.Empty<R>(), Observable.Return);\n\n    /// <summary>\n    /// Match the two states of the Either and return a stream of non-null R2s.\n    /// </summary>\n    [Pure]\n    public static IObservable<R2> MatchObservable<L, R, R2>(this Either<L, IObservable<R>> self, Func<R, R2> Right, Func<L, R2> Left) =>\n        self.IsRight\n            ? self.CastRight().Select(Right).Select(Check.NullReturn)\n            : Observable.Return(Check.NullReturn(Left(self.CastLeft())));\n\n    /// <summary>\n    /// Match the two states of the IObservable Either and return a stream of non-null R2s.\n    /// </summary>\n    [Pure]\n    public static IObservable<R2> MatchObservable<L, R, R2>(this IObservable<Either<L, R>> self, Func<R, R2> Right, Func<L, R2> Left) =>\n        self.Select(either => either.Match(Left, Right));\n\n\n    /// <summary>\n    /// Match the two states of the Either and return an observable stream of non-null R2s.\n    /// </summary>\n    [Pure]\n    public static IObservable<R2> MatchObservable<L, R, R2>(this Either<L, R> ma, Func<R, IObservable<R2>> Right, Func<L, R2> Left) =>\n        ma.Match(l => Observable.Return(Left(l)), Right);\n\n    /// <summary>\n    /// Match the two states of the Either and return an observable stream of non-null R2s.\n    /// </summary>\n    [Pure]\n    public static IObservable<R2> MatchObservable<L, R, R2>(this Either<L, R> ma, Func<R, IObservable<R2>> Right, Func<L, IObservable<R2>> Left) =>\n        ma.Match(Left, Right);\n}\n"
  },
  {
    "path": "LanguageExt.Rx/EitherUnsafe.Extensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Diagnostics;\n\nnamespace LanguageExt\n{\n    public class EitherUnsafeRxExtensions\n    {\n        public static IObservable<R> ToObservable<L, R>(this EitherUnsafe<L, R> ma) =>\n            ma.Match(Observable.Return, _ => Observable.Empty<R>());\n\n        /// <summary>\n        /// Match the two states of the Either and return a stream of non-null R2s.\n        /// </summary>\n        [Pure]\n        public static IObservable<R2> MatchObservable<L, R, R2>(this EitherUnsafe<L, IObservable<R>> self, Func<R, R2> Right, Func<L, R2> Left) =>\n            self.IsRight\n                ? self.CastRight().Select(Right).Select(Check.NullReturn)\n                : Observable.Return(Check.NullReturn(Left(self.CastLeft())));\n\n        /// <summary>\n        /// Match the two states of the IObservable Either and return a stream of non-null R2s.\n        /// </summary>\n        [Pure]\n        public static IObservable<R2> MatchObservable<L, R, R2>(this IObservable<EitherUnsafe<L, R>> self, Func<R, R2> Right, Func<L, R2> Left) =>\n            self.Select(either => matchUnsafe(either, Right, Left));\n\n        /// <summary>\n        /// Match the two states of the Either and return an observable stream of non-null R2s.\n        /// </summary>\n        [Pure]\n        public static IObservable<R2> MatchObservable<L, R, R2>(this EitherUnsafe<L, R> ma, Func<R, IObservable<R2>> Right, Func<L, R2> Left) =>\n            ma.Match(Right, l => Observable.Return(Left(l)));\n\n        /// <summary>\n        /// Match the two states of the Either and return an observable stream of non-null R2s.\n        /// </summary>\n        [Pure]\n        public static IObservable<R2> MatchObservable<L, R, R2>(this EitherUnsafe<L, R> ma, Func<R, IObservable<R2>> Right, Func<L, IObservable<R2>> Left) =>\n            ma.Match(Right, Left);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Rx/LanguageExt.Rx.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)'=='Debug'\">\n        <DefineConstants>TRACE;DEBUG</DefineConstants>\n    </PropertyGroup>\n    <PropertyGroup Label=\"Configuration\">\n        <NoWarn>1701;1702;1705;IDE1006;CS1591;CS1573;CS1712;CS1711;CS1572;CS1587</NoWarn>\n        <DefineConstants>CONTRACTS_FULL</DefineConstants>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <PackageVersion>5.0.0-beta-77</PackageVersion>\n        <PackageId>LanguageExt.Rx</PackageId>\n        <Title>LanguageExt.Rx</Title>\n        <Authors>Paul Louth</Authors>\n        <Summary>Functional language extensions for C#</Summary>\n        <Copyright>Copyright (c) Paul Louth. All rights reserved.</Copyright>\n        <PackageReadmeFile>README.nuget.md</PackageReadmeFile>\n        <Description>Support for Reactive Extensions overloads for various types in the LanguageExt functional framework</Description>\n        <PackageTags>C#, Functional, Language Extension, Monad, Option, Either, Reader, Writer, State, List, Set, Map, Queue, Memo, Memoization, Immutable, Lambda, Pattern Matching, Tuple</PackageTags>\n        <PackageIcon>lang-ext-small.png</PackageIcon>\n        <PackageProjectUrl>https://github.com/louthy/language-ext</PackageProjectUrl>\n        <PackageLicenseExpression>MIT</PackageLicenseExpression>\n        <EnableDefaultCompileItems>false</EnableDefaultCompileItems>\n        <DocumentationFile>bin\\$(Configuration)\\$(TargetFramework)\\$(AssemblyName).xml</DocumentationFile>\n        <OutputType>library</OutputType>\n        <AssemblyVersion>5.0.0.0</AssemblyVersion>\n        <FileVersion>5.0.0.0</FileVersion>\n        <LangVersion>default</LangVersion>\n    </PropertyGroup>\n    <ItemGroup>\n        <InternalsVisibleTo Include=\"LanguageExt.Tests\" />\n    </ItemGroup>\n    <ItemGroup>\n        <None Include=\"README.nuget.md\" Pack=\"true\" PackagePath=\"\\\"/>\n        <None Include=\"..\\Images\\lang-ext-small.png\" Pack=\"true\" PackagePath=\"\\\"/>\n    </ItemGroup>\n    <ItemGroup>\n        <Compile Include=\"**\\*.cs\" />\n        <EmbeddedResource Include=\"**\\*.resx\" />\n    </ItemGroup>\n    <ItemGroup>\n        <Compile Remove=\"obj\\**\" />\n        <EmbeddedResource Remove=\"obj\\**\" />\n        <None Remove=\"obj\\**\" />\n    </ItemGroup>\n    <ItemGroup>\n        <Compile Remove=\"EitherUnsafe.Extensions.cs\" />\n    </ItemGroup>\n    <ItemGroup>\n        <None Remove=\"Cast.cs\" />\n        <None Remove=\"Check.cs\" />\n        <None Remove=\"Either.Extensions.cs\" />\n        <None Remove=\"Nullable.Extensions.cs\" />\n        <None Remove=\"Option.Extensions.cs\" />\n        <None Remove=\"OptionUnsafe.Extensions.cs\" />\n        <None Remove=\"PreludeRx.cs\" />\n        <None Remove=\"Task.Try.Extensions.cs\" />\n        <None Remove=\"Try.Extensions.cs\" />\n        <None Remove=\"TryAsync.Extensions.cs\" />\n        <None Remove=\"TryOption.Extensions.cs\" />\n        <None Remove=\"TryOptionAsync.Extensions.cs\" />\n        <None Remove=\"Validation.Extensions.cs\" />\n        <None Remove=\"ValidationSeq.Extensions.cs\" />\n    </ItemGroup>\n    <ItemGroup>\n        <PackageReference Include=\"System.Reactive\" Version=\"5.0.0\" />\n    </ItemGroup>\n    <ItemGroup>\n        <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "LanguageExt.Rx/Option.Extensions.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Reactive.Linq;\n\nnamespace LanguageExt;\n\npublic static class OptionRxExtensions\n{\n    public static IObservable<B> Choose<A, B>(this IObservable<A> ma, Func<A, Option<B>> f) =>\n        ma.Select(f)\n          .Where(x => x.IsSome)\n          .Select(x => (B)x);\n        \n    public static IObservable<A> ToObservable<A>(this Option<A> ma) =>\n        ma.IsSome\n            ? Observable.Return(ma.Cast())\n            : Observable.Empty<A>();\n\n    /// <summary>\n    /// Match the two states of the Option and return an observable stream of non-null Rs.\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Some\">Some handler.  Must not return null.</param>\n    /// <param name=\"None\">None handler.  Must not return null.</param>\n    /// <returns>A stream of non-null Rs</returns>\n    [Pure]\n    public static IObservable<B> MatchObservable<A, B>(this Option<A> ma, Func<A, IObservable<B>> Some, Func<B> None) =>\n        ma.IsSome\n            ? Some(ma.Cast())\n            : Observable.Return(None());\n\n    /// <summary>\n    /// Match the two states of the Option and return an observable stream of non-null Rs.\n    /// </summary>\n    /// <typeparam name=\"B\">Return type</typeparam>\n    /// <param name=\"Some\">Some handler.  Must not return null.</param>\n    /// <param name=\"None\">None handler.  Must not return null.</param>\n    /// <returns>A stream of non-null Rs</returns>\n    [Pure]\n    public static IObservable<B> MatchObservable<A, B>(this Option<A> ma, Func<A, IObservable<B>> Some, Func<IObservable<B>> None) =>\n        ma.IsSome\n            ? Some(ma.Cast())\n            : None();\n}\n"
  },
  {
    "path": "LanguageExt.Rx/PreludeRx.cs",
    "content": "﻿using System;\nusing System.Reactive.Linq;\nusing System.Reactive.Threading.Tasks;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\npublic static class PreludeRx\n{\n    /// <summary>\n    /// Execute a function after a specified delay\n    /// </summary>\n    /// <param name=\"f\">Function to execute</param>\n    /// <param name=\"delayFor\">Time span to delay for</param>\n    /// <returns>IObservable T with the result</returns>\n    public static IObservable<T> delay<T>(Func<T> f, TimeSpan delayFor) =>\n        delayFor.TotalMilliseconds < 1\n            ? Observable.Return(f()).Take(1)\n            : Task.Delay(delayFor).ContinueWith(_ => f()).ToObservable().Take(1);\n\n    /// <summary>\n    /// Execute a function at a specific time\n    /// </summary>\n    /// <remarks>\n    /// This will fail to be accurate across a Daylight Saving Time boundary\n    /// </remarks>\n    /// <param name=\"f\">Function to execute</param>\n    /// <param name=\"delayUntil\">DateTime to wake up at.</param>\n    /// <returns>IObservable T with the result</returns>\n    public static IObservable<T> delay<T>(Func<T> f, DateTime delayUntil) =>\n        delay(f, delayUntil.ToUniversalTime() - DateTime.UtcNow);\n}\n"
  },
  {
    "path": "LanguageExt.Rx/README.nuget.md",
    "content": "# LanguageExt.Rx\n\n`LanguageExt.Rx` are the 'Reactive Extensions' extensions for the [language-ext functional programming framework](https://github.com/louthy/language-ext).\n\nThe framework uses and abuses the features of C# to provide a pure functional-programming \n'Base Class Library' that, if you squint, can look like extensions to the language itself. \nThe desire here is to make programming in C# much more robust by helping the engineer's \ninertia flow in the direction of declarative and pure functional code rather than imperative. \n\nUsing these techniques for large code-bases can bring tangible benefits to long-term maintenance \nby removing hidden complexity and by easing the engineer's cognitive load.\n\n## Features\n\n### [Functional effects and IO](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/index.html)\n\n| Location | Feature      | Description                                                                                                                                                                                              |\n|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `IO<A>`      | [A synchronous and asynchronous side-effect: an IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/IO/index.html)                                                                  |\n| `Core`   | `Eff<A>`     | [A synchronous and asynchronous side-effect with error handling](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20no%20runtime/index.html)                                       |\n| `Core`   | `Eff<RT, A>` | [Same as `Eff<A>` but with an injectable runtime for dependency-injection: a unit testable IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20with%20runtime/index.html) |\n| `Core`   | Pipes        | [A clean and powerful stream processing system that lets you build and connect reusable streaming components](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Pipes/index.html)           |\n| `Core`   | StreamT      | [less powerful (than Pipes), but easier to use streaming effects transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/StreamT/index.html)                                         |\n\n### [Atomic concurrency and collections](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/index.html)\n\n| Location | Feature                            | Description                                                                                                                                            |\n|----------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Atom<A>`                          | [A lock-free atomically mutable reference for working with shared state](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/Atom)      |\n| `Core`   | `Ref<A>`                           | [An atomic reference to be used in the transactional memory system](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/STM)            |\n| `Core`   | `AtomHashMap<K, V>`                | [An immutable `HashMap` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomHashMap) |\n| `Core`   | `AtomSeq<A>`                       | [An immutable `Seq` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomSeq)         |\n| `Core`   | `VectorClock<A>`                   | [Understand distributed causality](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VectorClock)                                     |\n| `Core`   | `VersionVector<A>`                 | [A vector clock with some versioned data](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionVector)                            |\n| `Core`   | `VersionHashMap <ConflictV, K, V>` | [Distrubuted atomic versioning of keys in a hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionHashMap)               |\n\n### [Immutable collections](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/index.html)\n\n| Location | Feature              | Description                                                                                                                                                                                                             |\n|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Arr<A>`             | [Immutable array](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Arr/index.html)                                                                                                        |\n| `Core`   | `Seq<A>`             | [Lazy immutable list, evaluate at-most-once](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Seq/index.html) - very, very fast!                                                          |\n| `Core`   | `Iterable<A>`        | [Wrapper around `IEnumerable` with support for traits](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Iterable/index.html) - enables the higher-kinded traits to work with enumerables. |\n| `Core`   | `Lst<A>`             | [Immutable list](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/List/index.html) - use `Seq` over `Lst` unless you need `InsertAt`                                                      |\n| `Core`   | `Map<K, V>`          | [Immutable map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                                                          |\n| `Core`   | `Map<OrdK, K, V>`    | [Immutable map with Ord constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                               |\n| `Core`   | `HashMap<K, V>`      | [Immutable hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                                                 |\n| `Core`   | `HashMap<EqK, K, V>` | [Immutable hash-map with Eq constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                       |\n| `Core`   | `Set<A>`             | [Immutable set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                                                          |\n| `Core`   | `Set<OrdA, A>`       | [Immutable set with Ord constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                               |\n| `Core`   | `HashSet<A>`         | [Immutable hash-set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                                                 |\n| `Core`   | `HashSet<EqA, A>`    | [Immutable hash-set with Eq constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                       |\n| `Core`   | `Que<A>`             | [Immutable queue](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Queue/index.html)                                                                                                      |\n| `Core`   | `Stck<A>`            | [Immutable stack](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Stack/index.html)                                                                                                      |\n\n### [Optional and alternative value monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/index.html)\n\n| Location | Feature                         | Description                                                                                                                                                                                              |\n|----------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Option<A>`                     | [Option monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Option/index.html)                                                                                     |\n| `Core`   | `OptionT<M, A>`                 | [Option monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/OptionT/index.html)                                                                        |\n| `Core`   | `Either<L,R>`                   | [Right/Left choice monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Either/index.html)                                                                          |\n| `Core`   | `EitherT<L, M, R>`              | [Right/Left choice monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/EitherT/index.html)                                                             |\n| `Core`   | `Fin<A>`                        | [`Error` handling monad, like `Either<Error, A>`](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Fin/index.html)                                                     |\n| `Core`   | `FinT<M, A>`                    | [`Error` handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/FinT/index.html)                                                                 |\n| `Core`   | `Try<A>`                        | [Exception handling monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Try/index.html)                                                                            |\n| `Core`   | `TryT<M, A>`                    | [Exception handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/TryT/index.html)                                                               |\n| `Core`   | `Validation<FAIL ,SUCCESS>`     | [Validation applicative and monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Validation/index.html) for collecting multiple errors before aborting an operation |\n| `Core`   | `ValidationT<FAIL, M, SUCCESS>` | [Validation applicative and monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/ValidationT/index.html)                                                |\n\n### [State managing monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/index.html)\n\n| Location | Feature            | Description                                                                                                                                                                             |\n|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Reader<E, A>`     | [Reader monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/Reader/index.html)                                               |\n| `Core`   | `ReaderT<E, M, A>` | [Reader monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/ReaderT/index.html)                                  |\n| `Core`   | `Writer<W, A>`     | [Writer monad that logs to a `W` constrained to be a Monoid](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/Writer/index.html) |\n| `Core`   | `WriterT<W, M, A>` | [Writer monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/WriterT/index.html)                                  |\n| `Core`   | `State<S, A>`      | [State monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/State/index.html)                                                  |\n| `Core`   | `StateT<S, M, A>`  | [State monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/StateT/index.html)                                     |\n\n### [Parser combinators](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)\n\n| Location | Feature        | Description                                                                                                                    |\n|----------|----------------|--------------------------------------------------------------------------------------------------------------------------------|\n| `Parsec` | `Parser<A>`    | [String parser monad and full parser combinators library](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html) |\n| `Parsec` | `Parser<I, O>` | [Parser monad that can work with any input stream type](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)   |\n\n### [Pretty](https://louthy.github.io/language-ext/LanguageExt.Core/Pretty/index.html)\n\n| Location | Feature  | Description                                      |\n|----------|----------|--------------------------------------------------|\n| `Core`   | `Doc<A>` | Produce nicely formatted text with smart layouts |\n\n### [Differencing](https://louthy.github.io/language-ext/LanguageExt.Core/DataTypes/Patch/index.html)\n\n| Location | Feature         | Description                                                                                                                                                                                                                          |\n|----------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Patch<EqA, A>` | Uses patch-theory to efficiently calculate the difference (`Patch.diff(list1, list2)`) between two collections of `A` and build a patch which can be applied (`Patch.apply(patch, list)`) to one to make the other (think git diff). |\n\n### [Traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/index.html)\n\nThe traits are major feature of `v5`+ language-ext that makes generic programming with higher-kinds a reality.  Check out Paul's [series on Higher Kinds](https://paullouth.com/higher-kinds-in-c-with-language-ext/) to get a deeper insight.\n\n| Location | Feature                                | Description                                                                                                                                                            |\n|----------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `MonoidK<F>`                       | [A monoid on applicative functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Alternative/index.html)                                               |\n| `Core`   | `Applicative<F>`                       | [Applicative functor](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Applicative/index.html)                                                            |\n| `Core`   | `Eq<A>`                                | [Ad-hoc equality trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Eq/index.html)                                                                   |\n| `Core`   | `Fallible<F>`                          | [Trait that describes types that can fail](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Fallible/index.html)                                          |\n| `Core`   | `Foldable<T>`                          | [Aggregation over a structure](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Foldable/index.html)                                                      |\n| `Core`   | `Functor<F>`                           | [Functor `Map`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Functor/index.html)                                                                      |\n| `Core`   | `Has<M, TRAIT>`                        | [Used in runtimes to enable DI-like capabilities](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Has/index.html)                                        |\n| `Core`   | `Hashable<A>`                          | [Ad-hoc has-a-hash-code trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Hashable/index.html)                                                      |\n| `Core`   | `Local<M, E>`                          | [Creates a local environment to run a computation ](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Local/index.html)                                    |\n| `Core`   | `Monad<M>`                             | [Monad trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/Monad/index.html)                                                                   |\n| `Core`   | `MonadT<M, N>`                         | [Monad transformer trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/MonadT/index.html)                                                      |\n| `Core`   | `Monoid<A>`                            | [A monoid is a type with an identity `Empty` and an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monoid/index.html) |\n| `Core`   | `MonoidK<M>`                           | [Equivalent of monoids for working on higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/MonoidK/index.html)                           |\n| `Core`   | `Mutates<M, OUTER_STATE, INNER_STATE>` | [Used in runtimes to enable stateful operations](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Mutates/index.html)                                     |\n| `Core`   | `Ord<A>`                               | [Ad-hoc ordering / comparisons](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Ord/index.html)                                                          |\n| `Core`   | `Range<SELF, NumOrdA, A>`              | [Abstraction of a range of values](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Range/index.html)                                                     |\n| `Core`   | `Readable<M, Env>`                     | [Generalised Reader monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Readable/index.html)                                              |\n| `Core`   | `SemigroupK<F>`                   | [A semigroup on functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                                                    |\n| `Core`   | `Semigroup<A>`                         | [Provides an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Semigroup/index.html)                                     |\n| `Core`   | `SemigroupK<M>`                        | [Equivalent of semigroups for working with higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                   |\n| `Core`   | `Stateful<M, S>`                       | [Generalised State monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Stateful/index.html)                                               |\n| `Core`   | `Traversable<T>`                       | [Traversable structures support element-wise sequencing of Applicative effects](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Traversable/index.html)  |\n| `Core`   | `Writable<M, W>`                       | [Generalised Writer monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Writable/index.html)                                              |\n\n### [Value traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Domain/index.html)\n\nThese work a little like `NewType` but they impart semantic meaning and some common operators for the underlying value.\n\n| Location | Feature                              | Description                                                                                                                                                                                                                                       |\n|----------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `DomainType<SELF, REPR>`             | Provides a mapping from `SELF` to an underlying representation: `REPR`                                                                                                                                                                            |\n| `Core`   | `Identifier <SELF>`                  | Identifiers (like IDs in databases: `PersonId` for example), they are equivalent to `DomaintType` with equality.                                                                                                                                  |\n| `Core`   | `VectorSpace<SELF, SCALAR>`          | Scalable values; can add and subtract self, but can only multiply and divide by a scalar. Can also negate.                                                                                                                                        |\n| `Core`   | `Amount <SELF, SCALAR>`              | Quantities, such as the amount of money in USD on a bank account or a file size in bytes. Derives `VectorSpace`, `IdentifierLike`, `DomainType`, and is orderable (comparable).                                                                   |\n| `Core`   | `LocusLike <SELF, SCALAR, DISTANCE>` | Works with space-like structures. Spaces have absolute and relative distances. Has an origin/zero point and derives `DomainType`, `IdentifierLike`, `AmountLike` and `VectorSpace`.  `DISTANCE` must also be an `AmountLike<SELF, REPR, SCALAR>`. |\n"
  },
  {
    "path": "LanguageExt.Rx/Validation.Extensions.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Contracts;\nusing System.Reactive.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class ValidationRxExtensions\n{\n    /// <summary>\n    /// Match the two states of the Validation and return an observable stream of non-null R2s.\n    /// </summary>\n    [Pure]\n    public static IObservable<R2> MatchObservable<F, A, R2>(\n        this Validation<F, A> ma, \n        Func<A, IObservable<R2>> Succ, \n        Func<F, R2> Fail) \n        where F : Monoid<F>, Eq<F> =>\n        ma.Match( Succ: Succ, Fail: x => Observable.Return(Fail(x)));\n\n    /// <summary>\n    /// Match the two states of the Validation and return an observable stream of non-null R2s.\n    /// </summary>\n    [Pure]\n    public static IObservable<R2> MatchObservable<F, A, R2>(\n        this Validation<F, A> ma, \n        Func<A, IObservable<R2>> Succ, \n        Func<F, IObservable<R2>> Fail) \n        where F : Monoid<F>, Eq<F> =>\n        ma.Match(Succ: Succ, Fail: Fail);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Buffer.cs",
    "content": "namespace LanguageExt;\n\n/// <summary>\n/// Settings for `Conduit` channels\n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record Buffer<A>\n{\n    static Buffer()\n    {\n        Unbounded = new UnboundedBuffer<A>();\n        Single = new SingleBuffer<A>();\n        New = new NewBuffer<A>();\n    }\n    \n    internal Buffer()\n    { }\n\n    /// <summary>\n    /// Store an unbounded number of messages in a FIFO queue\n    /// </summary>\n    public static readonly Buffer<A> Unbounded;\n    \n    /// <summary>\n    /// Bounded number of messages to `1`\n    /// </summary>\n    public static readonly Buffer<A> Single;\n    \n    /// <summary>\n    /// `Newest(1)`\n    /// </summary>\n    public static readonly Buffer<A> New;\n    \n    /// <summary>\n    /// Store a bounded number of messages, specified by the 'size' argument\n    /// </summary>\n    /// <param name=\"size\">Bounded size of the buffer</param>\n    public static Buffer<A> Bounded(uint size) => \n        size == 1\n            ? new SingleBuffer<A>()\n            : new BoundedBuffer<A>(size);\n    \n    /// <summary>\n    /// Only store the 'Latest' message, beginning with an initial value\n    /// </summary>\n    /// <remarks>\n    /// 'Latest' is never empty nor full.\n    /// </remarks>\n    public static Buffer<A> Latest(A value) => \n        new LatestBuffer<A>(value);\n    \n    /// <summary>\n    /// Like `Bounded`, but `Post` never fails (the buffer is never full).\n    /// Instead, old elements are discarded to make room for new elements\n    /// </summary>\n    /// <param name=\"size\">Size of the buffer</param>\n    public static Buffer<A> Newest(uint size) => \n        size == 1\n            ? new NewBuffer<A>()\n            : new NewestBuffer<A>(size);\n}\n\npublic sealed record UnboundedBuffer<A> : Buffer<A>;\npublic sealed record BoundedBuffer<A>(uint Size) : Buffer<A>;\npublic sealed record SingleBuffer<A> : Buffer<A>;\npublic sealed record LatestBuffer<A>(A Value) : Buffer<A>;\npublic sealed record NewestBuffer<A>(uint Size) : Buffer<A>;\npublic sealed record NewBuffer<A> : Buffer<A>;\n"
  },
  {
    "path": "LanguageExt.Streaming/Conduit/Conduit.Extensions.cs",
    "content": "using LanguageExt.Pipes;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class ConduitExtensions\n{\n    public static Conduit<A, B> As<A, B>(this K<Conduit<A>, B> ma) => \n        (Conduit<A, B>)ma;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Conduit/Conduit.Module.cs",
    "content": "using System;\nusing Ch = System.Threading.Channels;\nnamespace LanguageExt;\n\npublic static class Conduit\n{\n    /// <summary>\n    /// Create a new unbounded Conduit \n    /// </summary>\n    /// <param name=\"label\">Label for debugging purposes</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed Conduit with an `Sink` and an `Source`</returns>\n    public static Conduit<A, A> make<A>() =>\n        make(Buffer<A>.Unbounded);\n\n    /// <summary>\n    /// Create a new Conduit with the buffer settings provided \n    /// </summary>\n    /// <param name=\"buffer\">Buffer settings</param>\n    /// <param name=\"label\">Label for debugging purposes</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed Conduit with an `Sink` and an `Source`</returns>\n    /// <exception cref=\"NotSupportedException\">Thrown for invalid buffer settings</exception>\n    public static Conduit<A, A> make<A>(Buffer<A> buffer)\n    {\n        var channel = MakeChannel(buffer);\n        return new Conduit<A, A, A>(Transducer.identity<A>(), channel, Transducer.identity<A>());\n    }\n    \n    static Ch.Channel<A> MakeChannel<A>(Buffer<A> buffer)\n    {\n        Ch.Channel<A> channel;\n        switch (buffer)\n        {\n            case UnboundedBuffer<A>:\n                channel = Ch.Channel.CreateUnbounded<A>();\n                break;\n\n            case BoundedBuffer<A>(var size):\n            {\n                var opts = new Ch.BoundedChannelOptions((int)size) { FullMode = Ch.BoundedChannelFullMode.Wait };\n                channel = Ch.Channel.CreateBounded<A>(opts);\n                break;\n            }\n\n            case SingleBuffer<A>:\n            {\n                var opts = new Ch.BoundedChannelOptions(1) { FullMode = Ch.BoundedChannelFullMode.Wait };\n                channel = Ch.Channel.CreateBounded<A>(opts);\n                break;\n            }\n\n            case LatestBuffer<A>(var initial):\n            {\n                var opts = new Ch.BoundedChannelOptions(1) { FullMode = Ch.BoundedChannelFullMode.DropOldest };\n                channel = Ch.Channel.CreateBounded<A>(opts);\n                channel.Writer.TryWrite(initial);\n                break;\n            }\n\n            case NewestBuffer<A>(var size):\n            {\n                var opts = new Ch.BoundedChannelOptions((int)size) { FullMode = Ch.BoundedChannelFullMode.DropOldest };\n                channel = Ch.Channel.CreateBounded<A>(opts);\n                break;\n            }\n\n            case NewBuffer<A>:\n            {\n                var opts = new Ch.BoundedChannelOptions(1) { FullMode = Ch.BoundedChannelFullMode.DropOldest };\n                channel = Ch.Channel.CreateBounded<A>(opts);\n                break;\n            }\n\n            default:\n                throw new NotSupportedException();\n        }\n\n        return channel;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Conduit/Conduit.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class Conduit<A> : Cofunctor<Conduit<A>>, Functor<Conduit<A>>\n{\n    public static K<Conduit<A>, X> Comap<X, B>(Func<X, B> f, K<Conduit<A>, B> fb) => \n        fb.As().Comap(f);\n\n    public static K<Conduit<A>, C> Map<B, C>(Func<B, C> f, K<Conduit<A>, B> ma) =>\n        ma.As().Map(f);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Conduit/Conduit.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents a channel with an internal queue.  A channel has:\n///\n///   * A sink: an input transducer that manipulates values before being placed into the internal queue.\n///   * A buffer: `System.Threading.Channels.Channel`.\n///   * A source: an output transducer that manipulates values after being taken from the internal queue.\n///\n/// Both sides of the conduit can be manipulated:\n///\n/// The sink is a co-functor and can be mapped using `Comap` or `CoTransform`, these transform values _before_ they get\n/// to the conduit's buffer.\n/// \n/// The source is a functor, so you can `Map` or `Transform` in the usual way to map values on their way out of the\n/// buffer.  \n///\n/// Control of the internal buffer is provided by passing a `Buffer` value to `Conduit.make`.  This allows you to set\n/// various parameters for the internal queue, such as the maximum number of items to hold in the queue, and what\n/// strategy to use when the queue is full.  The default is `Buffer.Unbounded`.\n///\n/// `ToProducer` and `ToConsumer` enable the `Conduit` components to be used in composed pipe effects.\n/// </summary>\n/// <typeparam name=\"A\">Input value type</typeparam>\n/// <typeparam name=\"B\">Output value type</typeparam>\npublic abstract class Conduit<A, B> : K<Conduit<A>, B>\n{\n    /// <summary>\n    /// Access the underlying `Sink` for more direct manipulation.  \n    /// </summary>\n    /// <returns></returns>\n    public abstract Sink<A> Sink { get; }\n\n    /// <summary>\n    /// Access the underlying `Source` for more direct manipulation.  \n    /// </summary>\n    /// <returns></returns>\n    public abstract Source<B> Source  { get; }\n    \n    /// <summary>\n    /// Post a value to the `Sink`\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.SinkFull` if the `Sink` is full or closed.\n    /// </remarks>\n    /// <param name=\"value\">Value to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public abstract IO<Unit> Post(A value);\n    \n    /// <summary>\n    /// Complete and close the Sink\n    /// </summary>\n    public abstract IO<Unit> Complete();\n    \n    /// <summary>\n    /// Complete and close the Sink with an `Error`\n    /// </summary>\n    public abstract IO<Unit> Fail(Error Error);\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public abstract IO<S> Reduce<S>(S state, ReducerIO<B, S> reducer);\n    \n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public abstract K<M, S> Reduce<M, S>(S state, ReducerIO<B, S> reducer) \n        where M : MonadIO<M>;\n    \n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public abstract Conduit<A, C> Map<C>(Func<B, C> f);\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public Conduit<A, C> Select<C>(Func<B, C> f) =>\n        Map(f);\n    \n    /// <summary>\n    /// Transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <returns>Transformed source</returns>\n    public abstract Conduit<A, C> Transform<C>(Transducer<B, C> transducer);\n    \n    /// <summary>\n    /// Contravariant functor map\n    /// </summary>\n    public abstract Conduit<X, B> Comap<X>(Func<X, A> f);\n    \n    /// <summary>\n    /// Co-transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <returns>Transformed source</returns>\n    public abstract Conduit<X, B> CoTransform<X>(Transducer<X, A> transducer);\n\n    /// <summary>\n    /// Convert the `Sink` to a `ConsumerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ConsumerT`</returns>\n    public abstract ConsumerT<A, M, Unit> ToConsumerT<M>()\n        where M : MonadIO<M>;\n\n    /// <summary>\n    /// Convert the `Sink` to a `Consumer` pipe component\n    /// </summary>\n    /// <returns>`Consumer`</returns>\n    public abstract Consumer<RT, A, Unit> ToConsumer<RT>();\n\n    /// <summary>\n    /// Convert `Source` to a `ProducerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ProducerT`</returns>\n    public abstract ProducerT<B, M, Unit> ToProducerT<M>()\n        where M : MonadIO<M>;\n\n    /// <summary>\n    /// Convert `Source` to a `Producer` pipe component\n    /// </summary>\n    /// <returns>`Producer`</returns>\n    public abstract Producer<RT, B, Unit> ToProducer<RT>();\n\n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>SourceT where the only values yield are those that pass the predicate</returns>\n    public Conduit<A, B> Where(Func<B, bool> f) =>\n        Filter(f);\n    \n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>SourceT where the only values yield are those that pass the predicate</returns>\n    public abstract Conduit<A, B> Filter(Func<B, bool> f); \n\n    /// <summary>\n    /// Skip items in the source\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>Transformed source</returns>\n    public abstract Conduit<A, B> Skip(int amount); \n\n    /// <summary>\n    /// Limit the number of items processed \n    /// </summary>\n    /// <param name=\"amount\">Number to take</param>\n    /// <returns>Transformed source</returns>\n    public abstract Conduit<A, B> Take(int amount); \n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public abstract Conduit<A, S> FoldWhile<S>(Func<S, B, S> Fold, Func<S, B, bool> Pred, S Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public abstract Conduit<A, S> FoldUntil<S>(Func<S, B, S> Fold, Func<S, B, bool> Pred, S Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public abstract Conduit<A, S> FoldWhile<S>(\n        Schedule Time,\n        Func<S, B, S> Fold,\n        Func<S, B, bool> Pred,\n        S Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\"></typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public abstract Conduit<A, S> FoldUntil<S>(\n        Schedule Time,\n        Func<S, B, S> Fold,\n        Func<S, B, bool> Pred,\n        S Init);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Conduit/Internal/Conduit.ABC.cs",
    "content": "using System;\nusing System.Collections.Concurrent;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Represents a channel with an internal queue.  A channel has:\n///\n///   * A sink: an input transducer that manipulates values before being placed into the internal queue.\n///   * A buffer: `System.Threading.Channels.Channel`.\n///   * A source: an output transducer that manipulates values after being taken from the internal queue.\n///\n/// Both sides of the conduit can be manipulated:\n///\n/// The sink is a co-functor and can be mapped using `Comap` or `CoTransform`, these transform values _before_ they get\n/// to the conduit's buffer.\n/// \n/// The source is a functor, so you can `Map` or `Transform` in the usual way to map values on their way out of the\n/// buffer.  \n///\n/// Control of the internal buffer is provided by passing a `Buffer` value to `Conduit.make`.  This allows you to set\n/// various parameters for the internal queue, such as the maximum number of items to hold in the queue, and what\n/// strategy to use when the queue is full.  The default is `Buffer.Unbounded`.\n///\n/// `ToProducer` and `ToConsumer` enable the `Conduit` components to be used in composed pipe effects.\n/// </summary>\n/// <typeparam name=\"A\">Input value type</typeparam>\n/// <typeparam name=\"B\">Buffer value type</typeparam>\n/// <typeparam name=\"C\">Output value type</typeparam>\ninternal class Conduit<A, B, C> : Conduit<A, C>\n{\n    readonly Transducer<A, B> sink;\n    readonly Channel<B> channel;\n    readonly Transducer<B, C> source;\n\n    internal Conduit(Transducer<A, B> sink, Channel<B> channel, Transducer<B, C> source)\n    {\n        this.sink = sink;\n        this.channel = channel;\n        this.source = source;\n        Source = LanguageExt.Source.lift(channel).Transform(source);\n    }\n\n    /// <summary>\n    /// Post a value to the `Sink`\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.SinkFull` if the `Sink` is full or closed.\n    /// </remarks>\n    /// <param name=\"value\">Value to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public override IO<Unit> Post(A value) =>\n        sink.Reduce<Unit>(\n            (_, x) => \n                IO.liftVAsync(async e =>\n                          {\n                              if (await channel.Writer.WaitToWriteAsync(e.Token))\n                              {\n                                  await channel.Writer.WriteAsync(x);\n                                  return Reduced.Unit;\n                              }\n                              else\n                              {\n                                  throw Errors.SinkFull;\n                              }\n                          }))\n                    (unit, value)\n            .Map(r => r.Value);\n\n    /// <summary>\n    /// Complete and close the Sink\n    /// </summary>\n    public override IO<Unit> Complete() =>\n        IO.lift(_ => channel.Writer.TryComplete()).Map(unit);\n\n    /// <summary>\n    /// Complete and close the Sink with an `Error`\n    /// </summary>\n    public override IO<Unit> Fail(Error Error) =>\n        IO.lift(_ => channel.Writer.TryComplete(Error)).Map(unit);\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public override IO<S> Reduce<S>(S state, ReducerIO<C, S> reducer) =>\n        IO.liftVAsync(async e =>\n                      {\n                          while (await channel.Reader.WaitToReadAsync(e.Token))\n                          {\n                              var value = await channel.Reader.ReadAsync();\n                              switch (await source.Reduce(reducer)(state, value).RunAsync(e))\n                              {\n                                  case { Continue: true, Value: var nstate }:\n                                    state = nstate;\n                                    break;      \n                                  \n                                  case { Value: var nstate }:\n                                      return nstate;\n                              }\n                          }\n                          return state;\n                      });\n    \n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public override K<M, S> Reduce<M, S>(S state, ReducerIO<C, S> reducer) =>\n        M.LiftIOMaybe(IO.liftVAsync(async e =>\n                               {\n                                   while (await channel.Reader.WaitToReadAsync(e.Token))\n                                   {\n                                       var value = await channel.Reader.ReadAsync();\n                                       switch (await source.Reduce(reducer)(state, value).RunAsync(e))\n                                       {\n                                           case { Continue: true, Value: var nstate }:\n                                               state = nstate;\n                                               break;\n\n                                           case { Value: var nstate }:\n                                               return nstate;\n                                       }\n                                   }\n                                   return state;\n                               }));\n    \n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public override Conduit<A, D> Map<D>(Func<C, D> f) =>\n        With(source.Map(f));\n    \n    /// <summary>\n    /// Contravariant functor map\n    /// </summary>\n    public override Conduit<X, C> Comap<X>(Func<X, A> f) =>\n        With (sink.Comap(f));\n\n    /// <summary>\n    /// Access the underlying `Sink` for more direct manipulation.  \n    /// </summary>\n    /// <returns></returns>\n    public override Sink<A> Sink => \n        LanguageExt.Sink.lift(channel).Comap(sink);\n\n    /// <summary>\n    /// Access the underlying `Source` for more direct manipulation.  \n    /// </summary>\n    /// <returns></returns>\n    public override Source<C> Source { get; }\n\n    /// <summary>\n    /// Convert the `Sink` to a `ConsumerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ConsumerT`</returns>\n    public override ConsumerT<A, M, Unit> ToConsumerT<M>() =>\n        Sink.ToConsumerT<M>();\n\n    /// <summary>\n    /// Convert the `Sink` to a `Consumer` pipe component\n    /// </summary>\n    /// <returns>`Consumer`</returns>\n    public override Consumer<RT, A, Unit> ToConsumer<RT>() =>\n        Sink.ToConsumer<RT>();\n\n    /// <summary>\n    /// Convert `Source` to a `ProducerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ProducerT`</returns>\n    public override ProducerT<C, M, Unit> ToProducerT<M>() =>\n        Source.ToProducerT<M>();\n\n    /// <summary>\n    /// Convert `Source` to a `Producer` pipe component\n    /// </summary>\n    /// <returns>`Producer`</returns>\n    public override Producer<RT, C, Unit> ToProducer<RT>() =>\n        Source.ToProducer<RT>();\n        \n    /// <summary>\n    /// Transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <returns>Transformed source</returns>\n    public override Conduit<A, D> Transform<D>(Transducer<C, D> transducer) =>\n        With(source.Compose(transducer)); \n        \n    /// <summary>\n    /// Co-transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <returns>Transformed source</returns>\n    public override Conduit<X, C> CoTransform<X>(Transducer<X, A> transducer) =>\n        With(transducer.Compose(sink)); \n    \n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>SourceT where the only values yield are those that pass the predicate</returns>\n    public override Conduit<A, C> Filter(Func<C, bool> f) =>\n        With(source.Filter(f)); \n\n    /// <summary>\n    /// Skip items in the source\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>Transformed source</returns>\n    public override Conduit<A, C> Skip(int amount) =>\n        With(source.Skip(amount)); \n\n    /// <summary>\n    /// Limit the number of items processed \n    /// </summary>\n    /// <param name=\"amount\">Number to take</param>\n    /// <returns>Transformed source</returns>\n    public override Conduit<A, C> Take(int amount) =>\n        With(source.Take(amount)); \n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public override Conduit<A, S> FoldWhile<S>(Func<S, C, S> Fold, Func<S, C, bool> Pred, S Init) =>\n        With(source.FoldWhile(Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public override Conduit<A, S> FoldUntil<S>(Func<S, C, S> Fold, Func<S, C, bool> Pred, S Init) =>\n        With(source.FoldUntil(Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public override Conduit<A, S> FoldWhile<S>(\n        Schedule Time,\n        Func<S, C, S> Fold,\n        Func<S, C, bool> Pred,\n        S Init) =>\n        With(source.FoldWhile(Time, Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\"></typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public override Conduit<A, S> FoldUntil<S>(\n        Schedule Time,\n        Func<S, C, S> Fold,\n        Func<S, C, bool> Pred,\n        S Init) =>\n        With(source.FoldUntil(Time, Fold, Pred, Init));\n    \n\n    /// <summary>\n    /// New conduit with all the same properties except the Source, which is provided as the argument.\n    /// </summary>\n    /// <param name=\"src\">Source to use</param>\n    /// <typeparam name=\"Src\">Source bound-value type</typeparam>\n    /// <returns>Transformed conduit</returns>\n    internal Conduit<A, B, Src> With<Src>(Transducer<B, Src> src) =>\n        new (sink, channel, src);\n    \n    /// <summary>\n    /// New conduit with all the same properties except the Sink, which is provided as the argument.\n    /// </summary>\n    /// <param name=\"snk\">Sink to use</param>\n    /// <typeparam name=\"Src\">Source bound-value type</typeparam>\n    /// <returns>Transformed conduit</returns>\n    internal Conduit<Snk, B, C> With<Snk>(Transducer<Snk, B> snk) =>\n        new (snk, channel, source);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/ConduitT/ConduitT.Extensions.cs",
    "content": "using LanguageExt.Pipes;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class ConduitTExtensions\n{\n    public static ConduitT<M, A, B> As<M, A, B>(this K<ConduitT<M, A>, B> ma) \n        where M : MonadIO<M>, Monad<M>, Fallible<M> =>\n        (ConduitT<M, A, B>)ma;\n    \n    /// <summary>\n    /// Convert the conduit's `Sink` to a `Consumer` pipe component\n    /// </summary>\n    /// <returns>`Consumer`</returns>\n    public static Consumer<RT, A, Unit> ToConsumer<RT, A, B>(this ConduitT<Eff<RT>, A, B> conduit) =>\n        new (conduit.ToConsumerT().Proxy);\n\n    /// <summary>\n    /// Convert the conduit's `Source` to a `Producer` pipe component\n    /// </summary>\n    /// <returns>`Producer`</returns>\n    public static Producer<RT, B, Unit> ToProducer<RT, A, B>(this ConduitT<Eff<RT>, A, B> conduit) =>\n        new(conduit.ToProducerT().Proxy);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/ConduitT/ConduitT.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing Ch = System.Threading.Channels;\nnamespace LanguageExt;\n\npublic static class ConduitT\n{\n    /// <summary>\n    /// Create a new unbounded Conduit \n    /// </summary>\n    /// <param name=\"label\">Label for debugging purposes</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed Conduit with an `Sink` and an `Source`</returns>\n    public static ConduitT<M, A, A> make<M, A>() \n        where M : MonadIO<M>, Fallible<M> =>\n        make<M, A>(Buffer<A>.Unbounded);\n\n    /// <summary>\n    /// Create a new Conduit with the buffer settings provided \n    /// </summary>\n    /// <param name=\"buffer\">Buffer settings</param>\n    /// <param name=\"label\">Label for debugging purposes</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed Conduit with an `Sink` and an `Source`</returns>\n    /// <exception cref=\"NotSupportedException\">Thrown for invalid buffer settings</exception>\n    public static ConduitT<M, A, A> make<M, A>(Buffer<A> buffer)\n        where M : MonadIO<M>, Fallible<M> \n    {\n        var channel = MakeChannel<M, A>(buffer);\n        return new ConduitT<M, A, A, A>(TransducerM.identity<M, A>(), channel, TransducerM.identity<M, A>());\n    }\n    \n    /// <summary>\n    /// Create a new unbounded Conduit \n    /// </summary>\n    /// <param name=\"label\">Label for debugging purposes</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed Conduit with an `Sink` and an `Source`</returns>\n    public static K<M, ConduitT<M, A, A>> makeM<M, A>() \n        where M : MonadIO<M>, Fallible<M> =>\n        M.Pure(make<M, A>(Buffer<A>.Unbounded));\n\n    /// <summary>\n    /// Create a new Conduit with the buffer settings provided \n    /// </summary>\n    /// <param name=\"buffer\">Buffer settings</param>\n    /// <param name=\"label\">Label for debugging purposes</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Constructed Conduit with an `Sink` and an `Source`</returns>\n    /// <exception cref=\"NotSupportedException\">Thrown for invalid buffer settings</exception>\n    public static K<M, ConduitT<M, A, A>> makeM<M, A>(Buffer<A> buffer)\n        where M : MonadIO<M>, Fallible<M> =>\n        M.Pure(make<M, A>(Buffer<A>.Unbounded));\n    \n    static Ch.Channel<K<M, A>> MakeChannel<M, A>(Buffer<A> buffer)\n        where M : Maybe.MonadIO<M>, Monad<M>, Fallible<M> \n    {\n        Ch.Channel<K<M, A>> channel;\n        switch (buffer)\n        {\n            case UnboundedBuffer<A>:\n                channel = Ch.Channel.CreateUnbounded<K<M, A>>();\n                break;\n\n            case BoundedBuffer<A>(var size):\n            {\n                var opts = new Ch.BoundedChannelOptions((int)size) { FullMode = Ch.BoundedChannelFullMode.Wait };\n                channel = Ch.Channel.CreateBounded<K<M, A>>(opts);\n                break;\n            }\n\n            case SingleBuffer<A>:\n            {\n                var opts = new Ch.BoundedChannelOptions(1) { FullMode = Ch.BoundedChannelFullMode.Wait };\n                channel = Ch.Channel.CreateBounded<K<M, A>>(opts);\n                break;\n            }\n\n            case LatestBuffer<A>(var initial):\n            {\n                var opts = new Ch.BoundedChannelOptions(1) { FullMode = Ch.BoundedChannelFullMode.DropOldest };\n                channel = Ch.Channel.CreateBounded<K<M, A>>(opts);\n                channel.Writer.TryWrite(M.Pure(initial));\n                break;\n            }\n\n            case NewestBuffer<A>(var size):\n            {\n                var opts = new Ch.BoundedChannelOptions((int)size) { FullMode = Ch.BoundedChannelFullMode.DropOldest };\n                channel = Ch.Channel.CreateBounded<K<M, A>>(opts);\n                break;\n            }\n\n            case NewBuffer<A>:\n            {\n                var opts = new Ch.BoundedChannelOptions(1) { FullMode = Ch.BoundedChannelFullMode.DropOldest };\n                channel = Ch.Channel.CreateBounded<K<M, A>>(opts);\n                break;\n            }\n\n            default:\n                throw new NotSupportedException();\n        }\n\n        return channel;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/ConduitT/ConduitT.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class ConduitT<M, A> : Cofunctor<ConduitT<M, A>>, Functor<ConduitT<M, A>>\n    where M : MonadIO<M>, Monad<M>, Fallible<M>\n{\n    public static K<ConduitT<M, A>, X> Comap<X, B>(Func<X, B> f, K<ConduitT<M, A>, B> fb) => \n        fb.As().Comap(f);\n\n    public static K<ConduitT<M, A>, C> Map<B, C>(Func<B, C> f, K<ConduitT<M, A>, B> ma) =>\n        ma.As().Map(f);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/ConduitT/ConduitT.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// <para>\n/// Represents a channel with an internal queue.  A channel has:\n/// </para>\n/// <para>\n///   * A `Sink`: an input DSL that manipulates values before being placed into the internal queue.\n///   * An internal queue: usually a `System.Threading.Channels.Channel`.\n///   * A `Source`:  an output DSL that manipulates values after being taken from the internal queue.\n/// </para>\n/// <para>\n/// Both sides of the `ConduitT` can be manipulated:\n/// </para>\n/// <para>\n/// The `Sink` is a `Cofunctor` and can be mapped using `Comap`, this  transforms values _before_ they get to the\n/// channel.\n/// </para>\n/// <para>\n/// The `Source` is a monad-transformer, so you can `Map`, `Bind`, `Apply`, in the usual way to map values on their way\n/// out.  They manipulate values as they leave the channel through the `Source`.\n/// </para>\n/// <para>\n/// Control of the internal queue is provided by passing a `Buffer` value to `ConduitT.make`.  This allows you to set\n/// various parameters for the internal queue, such as the maximum number of items to hold in the queue, and what\n/// strategy to use when the queue is full.  The default is `Buffer.Unbounded`.\n/// </para>\n/// <para>\n/// `ToProducer` and `ToConsumer` enable the `ConduitT` components to be used in composed pipe effects.\n/// </para>\n/// </summary>\n/// <param name=\"Sink\">Sink</param>\n/// <param name=\"Source\">Source</param>\n/// <typeparam name=\"A\">Input value type</typeparam>\n/// <typeparam name=\"B\">Output value type</typeparam>\npublic abstract class ConduitT<M, A, B> : K<ConduitT<M, A>, B>\n    where M : MonadIO<M>, Monad<M>, Fallible<M>\n{\n    /// <summary>\n    /// Post a value to the Sink\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.SinkFull` if the Sink is full or closed.\n    /// </remarks>\n    /// <param name=\"value\">Value to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public abstract K<M, Unit> Post(A value);\n\n    /// <summary>\n    /// Post a value to the Sink\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.SinkFull` if the sink is full or closed.\n    /// </remarks>\n    /// <param name=\"ma\">Operation to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public abstract K<M, Unit> PostM(K<M, A> ma);\n\n    /// <summary>\n    /// Complete and close the sink\n    /// </summary>\n    public abstract K<M, Unit> Complete();\n\n    /// <summary>\n    /// Complete and close the sink with an `Error`\n    /// </summary>\n    public abstract K<M, Unit> Fail(Error Error);\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.  This is returned lifted. \n    /// </summary>\n    /// <remarks>Note, this is recursive, so `M` needs to be able to support recursion without\n    /// blowing the stack.  If you have the `IO` monad in your stack, then this will automatically\n    /// be the case.</remarks>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Lifted aggregate state</returns>\n    public abstract K<M, S> Reduce<S>(S state, ReducerM<M, B, S> reducer);\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public abstract ConduitT<M, A, C> Map<C>(Func<B, C> f);\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public ConduitT<M, A, C> Select<C>(Func<B, C> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Contravariant functor map\n    /// </summary>\n    public abstract ConduitT<M, X, B> Comap<X>(Func<X, A> f);\n\n    /// <summary>\n    /// Access the underlying `SinkT` for more direct manipulation.  \n    /// </summary>\n    /// <returns></returns>\n    public abstract SinkT<M, A> Sink { get; }\n\n    /// <summary>\n    /// Access the underlying `SourceT` for more direct manipulation.  \n    /// </summary>\n    /// <returns></returns>\n    public abstract SourceT<M, B> Source { get; }\n\n    /// <summary>\n    /// Convert the conduit's `Sink` to a `ConsumerT` pipe component\n    /// </summary>\n    /// <returns>`ConsumerT`</returns>\n    public abstract ConsumerT<A, M, Unit> ToConsumerT();\n\n    /// <summary>\n    /// Convert the conduit's `Source` to a `ProducerT` pipe component\n    /// </summary>\n    /// <returns>`ProducerT`</returns>\n    public abstract ProducerT<B, M, Unit> ToProducerT();\n\n    /// <summary>\n    /// Transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <returns>Transformed source</returns>\n    public abstract ConduitT<M, A, C> Transform<C>(TransducerM<M, B, C> transducer);\n\n    /// <summary>\n    /// Co-transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <returns>Transformed source</returns>\n    public abstract ConduitT<M, X, B> CoTransform<X>(TransducerM<M, X, A> transducer);\n\n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>SourceT where the only values yield are those that pass the predicate</returns>\n    public ConduitT<M, A, B> Where(Func<B, bool> f) =>\n        Filter(f);\n\n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>SourceT where the only values yield are those that pass the predicate</returns>\n    public abstract ConduitT<M, A, B> Filter(Func<B, bool> f);\n\n    /// <summary>\n    /// Skip items in the source\n    /// </summary>\n    /// <param name=\"amount\">Number to skip</param>\n    /// <returns>Transformed source</returns>\n    public abstract ConduitT<M, A, B> Skip(int amount);\n\n    /// <summary>\n    /// Limit the number of items processed \n    /// </summary>\n    /// <param name=\"amount\">Number to take</param>\n    /// <returns>Transformed source</returns>\n    public abstract ConduitT<M, A, B> Take(int amount);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public abstract ConduitT<M, A, S> FoldWhile<S>(Func<S, B, S> Fold, Func<S, B, bool> Pred, S Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public abstract ConduitT<M, A, S> FoldUntil<S>(Func<S, B, S> Fold, Func<S, B, bool> Pred, S Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public abstract ConduitT<M, A, S> FoldWhile<S>(\n        Schedule Time,\n        Func<S, B, S> Fold,\n        Func<S, B, bool> Pred,\n        S Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\"></typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public abstract ConduitT<M, A, S> FoldUntil<S>(\n        Schedule Time,\n        Func<S, B, S> Fold,\n        Func<S, B, bool> Pred,\n        S Init);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/ConduitT/Internal/ConduitT.ABC.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Channels;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nclass ConduitT<M, A, B, C> : ConduitT<M, A, C>\n    where M : MonadIO<M>, Monad<M>, Fallible<M>\n{\n    readonly TransducerM<M, A, B> sink;\n    readonly Channel<K<M, B>> channel;\n    readonly TransducerM<M, B, C> source;\n    \n    internal ConduitT(TransducerM<M, A, B> sink, Channel<K<M, B>> channel, TransducerM<M, B, C> source)\n    {\n        this.sink = sink;\n        this.channel = channel;\n        this.source = source;\n        Source = SourceT.liftM(channel).Transform(source);\n    }\n\n    /// <summary>\n    /// Post a value to the `Sink`\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.SinkFull` if the `Sink` is full or closed.\n    /// </remarks>\n    /// <param name=\"value\">Value to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public override K<M, Unit> Post(A value) =>\n        sink.Reduce<Unit>((_, b) => Write(M.Pure(b)).Map(Reduced.Continue))(unit, value)\n            .Map(r => r.Value);\n\n    /// <summary>\n    /// Post a value to the `Sink`\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.SinkFull` if the `Sink` is full or closed.\n    /// </remarks>\n    /// <param name=\"ma\">Value to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public override K<M, Unit> PostM(K<M, A> ma) =>\n        ma.Bind(Post);\n    \n    /// <summary>\n    /// Complete and close the Sink\n    /// </summary>\n    public override K<M, Unit> Complete() =>\n        M.LiftIOMaybe(IO.lift(_ => channel.Writer.TryComplete()).Map(unit));\n\n    /// <summary>\n    /// Complete and close the Sink with an `Error`\n    /// </summary>\n    public override K<M, Unit> Fail(Error Error) =>\n        M.LiftIOMaybe(IO.lift(_ => channel.Writer.TryComplete(Error)).Map(unit));\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public override K<M, S> Reduce<S>(S state, ReducerM<M, C, S> reducer)\n    {\n        return M.LiftIO(IO.lift(e => go(state, e.Token).Map(r => r.Value))).Flatten();\n        \n        K<M, Reduced<S>> go(S s0, CancellationToken token)\n        {\n            if(token.IsCancellationRequested) return M.Pure(Reduced.Done(s0));\n            if (channel.Reader.WaitToReadAsync(token).GetAwaiter().GetResult())\n            {\n                var mb = channel.Reader.ReadAsync(token).GetAwaiter().GetResult();\n                return mb.Bind(b => source.Reduce<S>((s1, c) => reducer(s1, c)\n                                                               .Bind(s2 => s2.Continue\n                                                                            ? go(s2.Value, token)\n                                                                            : M.Pure(s2))\n                                                               .Catch(M.Pure(Reduced.Done(s0))))(s0, b));       // TODO: Deal with errors?\n            }\n            else\n            {\n                return M.Pure(Reduced.Done(s0));\n            }\n        }\n    }\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public override ConduitT<M, A, D> Map<D>(Func<C, D> f) =>\n        With(source.Compose(TransducerM.map<M, C, D>(f)));\n    \n    /// <summary>\n    /// Contravariant functor map\n    /// </summary>\n    public override ConduitT<M, X, C> Comap<X>(Func<X, A> f) =>\n        With (TransducerM.map<M, X, A>(f).Compose(sink));\n\n    /// <summary>\n    /// Access the underlying `Sink` for more direct manipulation.  \n    /// </summary>\n    /// <returns></returns>\n    public override SinkT<M, A> Sink => \n        SinkT.lift(channel).Comap(sink);\n\n    /// <summary>\n    /// Access the underlying `Source` for more direct manipulation.  \n    /// </summary>\n    /// <returns></returns>\n    public override SourceT<M, C> Source { get; }\n\n    /// <summary>\n    /// Convert the `Sink` to a `ConsumerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ConsumerT`</returns>\n    public override ConsumerT<A, M, Unit> ToConsumerT() =>\n        Sink.ToConsumerT();\n\n    /// <summary>\n    /// Convert `Source` to a `ProducerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ProducerT`</returns>\n    public override ProducerT<C, M, Unit> ToProducerT() =>\n        Source.ToProducerT();\n        \n    /// <summary>\n    /// Transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <returns>Transformed source</returns>\n    public override ConduitT<M, A, D> Transform<D>(TransducerM<M, C, D> transducer) =>\n        With(source.Compose(transducer)); \n        \n    /// <summary>\n    /// Co-transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <returns>Transformed source</returns>\n    public override ConduitT<M, X, C> CoTransform<X>(TransducerM<M, X, A> transducer) =>\n        With(transducer.Compose(sink)); \n    \n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>SourceT where the only values yield are those that pass the predicate</returns>\n    public override ConduitT<M, A, C> Filter(Func<C, bool> f) =>\n        With(source.Filter(f)); \n\n    /// <summary>\n    /// Skip items in the source\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>Transformed source</returns>\n    public override ConduitT<M, A, C> Skip(int amount) =>\n        With(source.Skip(amount)); \n\n    /// <summary>\n    /// Limit the number of items processed \n    /// </summary>\n    /// <param name=\"amount\">Number to take</param>\n    /// <returns>Transformed source</returns>\n    public override ConduitT<M, A, C> Take(int amount) =>\n        With(source.Take(amount));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public override ConduitT<M, A, S> FoldWhile<S>(Func<S, C, S> Fold, Func<S, C, bool> Pred, S Init) =>\n        With(source.FoldWhile(Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public override ConduitT<M, A, S> FoldUntil<S>(Func<S, C, S> Fold, Func<S, C, bool> Pred, S Init) =>\n        With(source.FoldUntil(Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public override ConduitT<M, A, S> FoldWhile<S>(\n        Schedule Time,\n        Func<S, C, S> Fold,\n        Func<S, C, bool> Pred,\n        S Init) =>\n        With(source.FoldWhile(Time, Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\"></typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public override ConduitT<M, A, S> FoldUntil<S>(\n        Schedule Time,\n        Func<S, C, S> Fold,\n        Func<S, C, bool> Pred,\n        S Init) =>\n        With(source.FoldUntil(Time, Fold, Pred, Init));\n\n    /// <summary>\n    /// New conduit with all the same properties except the Source, which is provided as the argument.\n    /// </summary>\n    /// <param name=\"src\">Source to use</param>\n    /// <typeparam name=\"Src\">Source bound-value type</typeparam>\n    /// <returns>Transformed conduit</returns>\n    ConduitT<M, A, B, Src> With<Src>(TransducerM<M, B, Src> src) =>\n        new (sink, channel, src);\n    \n    /// <summary>\n    /// New conduit with all the same properties except the Sink, which is provided as the argument.\n    /// </summary>\n    /// <param name=\"sink\">Sink to use</param>\n    /// <typeparam name=\"Src\">Source bound-value type</typeparam>\n    /// <returns>Transformed conduit</returns>\n    ConduitT<M, Snk, B, C> With<Snk>(TransducerM<M, Snk, B> sink) =>\n        new (sink, channel, source);    \n\n    K<M, Unit> Write(K<M, B> value)\n    {\n        return M.LiftIOMaybe(IO.liftVAsync(e => go(e, value, channel)));\n        \n        static async ValueTask<Unit> go(EnvIO e, K<M, B> mb, Channel<K<M, B>> ch)\n        {\n            if (await ch.Writer.WaitToWriteAsync(e.Token))\n            {\n                await ch.Writer.WriteAsync(mb);\n                return unit;\n            }\n            else\n            {\n                throw Errors.SinkFull;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Event/Event.Module.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\npublic static class Event\n{\n    /// <summary>\n    /// Create an `Event` from an event delegate\n    /// </summary>\n    /// <param name=\"eventDelegate\">Delegate to which the event will listen for values</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Event that can be passed around in a first-class manner</returns>\n    public static Event<A> from<A>(ref Action<A> eventDelegate) =>\n        new (ref eventDelegate);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Event/Event.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Channels;\nusing LanguageExt.Traits;\nusing LanguageExt.UnsafeValueAccess;\nusing L = LanguageExt;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Adds itself to the `Action` event-delegate and then forwards anything posted by the event\n/// to any subscribers to this type.  We're trying to make events a bit more 'first class,\n/// rather than the 'runt of the litter' that they are now.\n///\n/// So, as long as you can find a way to make your event into a single argument action, you\n/// can then use it with the streaming functionality within this library.\n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic class Event<A> : IDisposable\n{\n    readonly AtomHashMap<Channel<A>, Subscription> subscribers = AtomHashMap<Channel<A>, Subscription>.Empty;\n    Action<A> @delegate;\n    int disposed;\n\n    /// <summary>\n    /// Construct an event from subscribing to the delegate\n    /// </summary>\n    /// <param name=\"delegate\">The delegate that this type will subscribe to</param>\n    public Event(ref Action<A> @delegate)\n    {\n        @delegate += Post;\n        this.@delegate = @delegate;\n    }\n\n    /// <summary>\n    /// Subscribe to this event\n    /// </summary>\n    public IO<Source<A>> Subscribe() =>\n        SubscribeInternal()\n           .Map(s => Source.lift(s.Channel));\n    \n    /// <summary>\n    /// Subscribe to this event\n    /// </summary>\n    public SourceT<M, A> Subscribe<M>()\n        where M : MonadIO<M>, Fallible<M> =>\n        from sub in SubscribeInternal()\n        from val in SourceT.lift<M, A>(sub.Channel)\n        select val;\n\n    /// <summary>\n    /// Subscribe a channel to this event\n    /// </summary>\n    /// <param name=\"channel\"></param>\n    /// <returns></returns>\n    IO<Subscription> SubscribeInternal() =>\n        IO.lift(e =>\n                {\n                    var channel = Channel.CreateUnbounded<A>();\n                    var sub     = new Subscription(this, channel);\n                    subscribers.AddOrUpdate(channel, sub);\n                    e.Resources.Acquire(sub);\n                    return sub;\n                });\n\n    public IO<Unit> Unsubscribe(Subscription sub) =>\n        IO.lift(e => subscribers.Swap(map =>\n                                      {\n                                          if (map.ContainsKey(sub.Channel))\n                                          {\n                                              sub.Channel.Writer.TryComplete();\n                                              map = map.Remove(sub.Channel);\n                                          }\n                                          return map;\n                                      }));\n\n    public IO<Unit> UnsubscribeAll() =>\n        IO.lift(e =>\n                {\n                    foreach (var sub in subscribers.Values)\n                    {\n                        sub.Channel.Writer.TryComplete();\n                    }\n                    return subscribers.Clear();\n                });\n\n    void Post(A value)\n    {\n        foreach (var sub in subscribers.Values)\n        {\n            sub.Channel.Writer.TryWrite(value);\n        }\n    }\n    \n    public void Dispose()\n    {\n        if (Interlocked.CompareExchange(ref disposed, 1, 0) == 0)\n        {\n            #pragma warning disable CS8601 // Possible null reference assignment.\n            @delegate -= Post;\n            UnsubscribeAll().Run();\n        }\n    }\n    \n    public class Subscription : IDisposable\n    {\n        internal Channel<A> Channel;\n        readonly Event<A> @event;\n        int disposed;\n\n        internal Subscription(Event<A> @event, Channel<A> channel)\n        {\n            this.@event = @event;\n            Channel = channel;\n        }\n\n        public void Dispose()\n        {\n            if (Interlocked.CompareExchange(ref disposed, 1, 0) == 0)\n            {\n                @event.Unsubscribe(this).Run();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/LanguageExt.Streaming.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)'=='Debug'\">\n        <DefineConstants>TRACE;DEBUG</DefineConstants>\n    </PropertyGroup>\n    <PropertyGroup Label=\"Configuration\">\n        <NoWarn>1701;1702;1705;IDE1006;CS1591;CS1573;CS1712;CS1711;CS1572;CS1587</NoWarn>\n        <DefineConstants>CONTRACTS_FULL</DefineConstants>\n        <TargetFramework>net10.0</TargetFramework>\n        <Nullable>enable</Nullable>\n        <RootNamespace>LanguageExt.Pipes</RootNamespace>\n    </PropertyGroup>\n    <PropertyGroup>\n        <PackageVersion>5.0.0-beta-77</PackageVersion>\n        <PackageId>LanguageExt.Streaming</PackageId>\n        <Title>LanguageExt.Streaming</Title>\n        <Authors>Paul Louth</Authors>\n        <Summary>Compositional pipelines for language-ext</Summary>\n        <PackageReadmeFile>README.nuget.md</PackageReadmeFile>\n        <Copyright>Copyright (c) Paul Louth. All rights reserved.</Copyright>\n        <Description>Streaming is a clean and powerful stream processing library that lets you build and connect reusable streaming components</Description>\n        <PackageTags>C#, Functional, Language Extension, Monad, Option, Either, Reader, Writer, State, List, Set, Map, Queue, Memo, Memoization, Immutable, Lambda, Pattern Matching, Tuple</PackageTags>\n        <PackageIcon>lang-ext-small.png</PackageIcon>\n        <PackageProjectUrl>https://github.com/louthy/language-ext</PackageProjectUrl>\n        <PackageLicenseExpression>MIT</PackageLicenseExpression>\n        <EnableDefaultCompileItems>false</EnableDefaultCompileItems>\n        <DocumentationFile>bin\\$(Configuration)\\$(TargetFramework)\\$(AssemblyName).xml</DocumentationFile>\n        <OutputType>library</OutputType>\n        <AssemblyVersion>5.0.0.0</AssemblyVersion>\n        <FileVersion>5.0.0.0</FileVersion>\n        <LangVersion>default</LangVersion>\n    </PropertyGroup>\n    <ItemGroup>\n        <InternalsVisibleTo Include=\"LanguageExt.Tests\" />\n    </ItemGroup>\n    <ItemGroup>\n        <None Include=\"..\\Images\\lang-ext-small.png\" Pack=\"true\" PackagePath=\"\\\"/>\n        <None Update=\"README.nuget.md\">\n          <Pack>true</Pack>\n          <PackagePath>/</PackagePath>\n        </None>\n    </ItemGroup>\n    <ItemGroup>\n        <Compile Include=\"**\\*.cs\" />\n        <EmbeddedResource Include=\"**\\*.resx\" />\n    </ItemGroup>\n    <ItemGroup>\n        <Compile Remove=\"obj\\**\" />\n        <EmbeddedResource Remove=\"obj\\**\" />\n        <None Remove=\"obj\\**\" />\n    </ItemGroup>\n    <ItemGroup>\n        <None Include=\"README.md\" />\n    </ItemGroup>\n    <ItemGroup>\n      <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Consumer/Consumer.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class ConsumerExtensions\n{\n    /// <summary>\n    /// Transformation from `PipeT` to `Consumer`.\n    /// </summary>\n    public static Consumer<RT, IN, A> ToConsumer<RT, IN, A>(this K<PipeT<IN, Void, Eff<RT>>, A> pipe) =>\n        new(pipe.As());\n    \n    /// <summary>\n    /// Transformation from `Pipe` to `Consumer`.\n    /// </summary>\n    public static Consumer<RT, IN, A> ToConsumer<RT, IN, A>(this K<Pipe<RT, IN, Void>, A> pipe) =>\n        new(pipe.As().Proxy);\n\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    public static Consumer<RT, IN, A> As<RT, IN, A>(this K<Consumer<RT, IN>, A> ma) =>\n        (Consumer<RT, IN, A>)ma;\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Consumer<RT, IN, C> SelectMany<RT, IN, A, B, C>(\n        this K<Eff<RT>, A> ma, \n        Func<A, Consumer<RT, IN, B>> f,\n        Func<A, B, C> g) =>\n        Consumer.liftM<RT, IN, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Consumer<RT, IN, C> SelectMany<RT, IN, A, B, C>(\n        this IO<A> ma, \n        Func<A, Consumer<RT, IN, B>> f,\n        Func<A, B, C> g) =>\n        Consumer.liftIO<RT, IN, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Consumer<RT, IN, C> SelectMany<RT, IN, A, B, C>(\n        this Pure<A> ma, \n        Func<A, Consumer<RT, IN, B>> f,\n        Func<A, B, C> g) =>\n        Consumer.pure<RT, IN, A>(ma.Value).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Consumer<RT, IN, C> SelectMany<RT, IN, A, B, C>(\n        this Lift<A> ff, \n        Func<A, Consumer<RT, IN, B>> f,\n        Func<A, B, C> g) =>\n        Consumer.lift<RT, IN, A>(ff.Function).SelectMany(f, g);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Consumer<RT, IN, B> Bind<RT, IN, A, B>(\n        this K<Eff<RT>, A> ma, \n        Func<A, Consumer<RT, IN, B>> f,\n        Func<A, B> g) =>\n        Consumer.liftM<RT, IN, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Consumer<RT, IN, B> Bind<RT, IN, A, B>(\n        this IO<A> ma, \n        Func<A, Consumer<RT, IN, B>> f,\n        Func<A, B> g) =>\n        Consumer.liftIO<RT, IN, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Consumer<RT, IN, B> Bind<RT, IN, A, B>(\n        this Pure<A> ma, \n        Func<A, Consumer<RT, IN, B>> f,\n        Func<A, B> g) =>\n        Consumer.pure<RT, IN, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Consumer<RT, IN, B> Bind<RT, IN, A, B>(\n        this Lift<A> ff, \n        Func<A, Consumer<RT, IN, B>> f,\n        Func<A, B> g) =>\n        Consumer.lift<RT, IN, A>(ff.Function).Bind(f);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static Consumer<RT, IN, C> SelectMany<RT, IN, A, C>(\n        this K<Consumer<RT, IN>, A> ma,\n        Func<A, Guard<Error, Unit>> bind,\n        Func<A, Unit, C> project) =>\n        ma.Bind(a => bind(a) switch\n                     {\n                         { Flag: true } => Consumer.pure<RT, IN, C>(project(a, default)),\n                         var guard      => Consumer.error<RT, IN, C>(guard.OnFalse())\n                     }).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static Consumer<RT, IN, C> SelectMany<RT, IN, B, C>(\n        this Guard<Error, Unit> ma,\n        Func<Unit, K<Consumer<RT, IN>, B>> bind,\n        Func<Unit, B, C> project) =>\n        ma switch\n        {\n            { Flag: true } => bind(default).Map(b => project(default, b)).As(),\n            var guard      => Consumer.error<RT, IN, C>(guard.OnFalse())\n        };    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Consumer/Consumer.Module.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `ConsumerT` streaming consumer monad-transformer\n/// </summary>\npublic static class Consumer\n{\n    /// <summary>\n    /// Await a value from upstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, IN> awaiting<RT, IN>() =>\n        PipeT.awaiting<Eff<RT>, IN, Void>().ToConsumer();\n\n    /// <summary>\n    /// Await a value from upstream and then ignore it\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, Unit> awaitIgnore<RT, IN>() =>\n        new PipeTAwait<IN, Void, Eff<RT>, Unit>(_ => PipeT.pure<IN, Void, Eff<RT>, Unit>(default)).ToConsumer();\n\n    /// <summary>\n    /// Create a consumer that simply returns a bound value without awaiting anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to await</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> pure<RT, IN, A>(A value) =>\n        PipeT.pure<IN, Void, Eff<RT>, A>(value).ToConsumer();\n\n    /// <summary>\n    /// Create a consumer that always fails\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to await</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> error<RT, IN, A>(Error value) =>\n        PipeT.fail<IN, Void, Error, Eff<RT>, A>(value).ToConsumer();\n\n    /// <summary>\n    /// Create a consumer that yields nothing at all\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> empty<RT, IN, A>() =>\n        PipeT.empty<IN, Void, Eff<RT>, A>().ToConsumer();\n\n    /// <summary>\n    /// Create a consumer that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> lift<RT, IN, A>(Func<A> f) =>\n        PipeT.lift<IN, Void, Eff<RT>, A>(f).ToConsumer();\n\n    /// <summary>\n    /// Create a lazy consumer \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> liftT<RT, IN, A>(Func<Consumer<RT, IN, A>> f) =>\n        PipeT.liftT(() => f().Proxy).ToConsumer();\n\n    /// <summary>\n    /// Create an asynchronous lazy consumer \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> liftT<RT, IN, A>(Func<ValueTask<Consumer<RT, IN, A>>> f) =>\n        PipeT.liftT(() => f().Map(x => x.Proxy)).ToConsumer();\n\n    /// <summary>\n    /// Create an asynchronous consumer \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> liftT<RT, IN, A>(ValueTask<Consumer<RT, IN, A>> f) =>\n        PipeT.liftT(f.Map(x => x.Proxy)).ToConsumer();\n\n    /// <summary>\n    /// Create a consumer that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> liftM<RT, IN, A>(K<Eff<RT>, A> ma) =>\n        PipeT.liftM<IN, Void, Eff<RT>, A>(ma).ToConsumer();\n\n    /// <summary>\n    /// Create a consumer that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> liftIO<RT, IN, A>(IO<A> ma) =>\n        PipeT.liftIO<IN, Void, Eff<RT>, A>(ma).ToConsumer();\n\n    /// <summary>\n    /// Continually repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> repeat<RT, IN, A>(Consumer<RT, IN, A> ma) =>\n        PipeT.repeat(ma.Proxy).ToConsumer();\n    \n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> repeat<RT, IN, A>(Schedule schedule, Consumer<RT, IN, A> ma) =>\n        PipeT.repeat(schedule, ma.Proxy).ToConsumer();\n\n    /// <summary>\n    /// Continually lift and repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> repeatM<RT, IN, A>(K<Eff<RT>, A> ma) =>\n        PipeT.repeatM<IN, Void, Eff<RT>, A>(ma).ToConsumer();\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Consumer<RT, IN, A> repeatM<RT, IN, A>(Schedule schedule, K<Eff<RT>, A> ma) =>\n        PipeT.repeatM<IN, Void, Eff<RT>, A>(schedule, ma).ToConsumer();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Consumer/Consumer.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic class Consumer<RT, IN> : \n    MonadUnliftIO<Consumer<RT, IN>>,\n    MonadT<Consumer<RT, IN>, Eff<RT>>\n{\n    static K<Consumer<RT, IN>, B> Monad<Consumer<RT, IN>>.Bind<A, B>(\n        K<Consumer<RT, IN>, A> ma, \n        Func<A, K<Consumer<RT, IN>, B>> f) => \n        ma.As().Bind(x => f(x).As());\n\n    static K<Consumer<RT, IN>, B> Monad<Consumer<RT, IN>>.Recur<A, B>(A value, Func<A, K<Consumer<RT, IN>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<Consumer<RT, IN>, B> Functor<Consumer<RT, IN>>.Map<A, B>(\n        Func<A, B> f, \n        K<Consumer<RT, IN>, A> ma) => \n        ma.As().Map(f);\n\n    static K<Consumer<RT, IN>, A> Applicative<Consumer<RT, IN>>.Pure<A>(A value) => \n        Consumer.pure<RT, IN, A>(value);\n\n    static K<Consumer<RT, IN>, B> Applicative<Consumer<RT, IN>>.Apply<A, B>(\n        K<Consumer<RT, IN>, Func<A, B>> mf,\n        K<Consumer<RT, IN>, A> ma) =>\n        ma.As().ApplyBack(mf.As());\n\n    static K<Consumer<RT, IN>, B> Applicative<Consumer<RT, IN>>.Apply<A, B>(\n        K<Consumer<RT, IN>, Func<A, B>> mf,\n        Memo<Consumer<RT, IN>, A> mma) =>\n        new PipeTMemo<IN, Void, Eff<RT>, A>(mma.Lower().Map(ma => ma.As().Proxy.Kind()).Lift())\n           .ApplyBack(mf.As().Proxy)\n           .ToConsumer();\n\n    static K<Consumer<RT, IN>, A> MonadT<Consumer<RT, IN>, Eff<RT>>.Lift<A>(K<Eff<RT>, A> ma) =>\n        Consumer.liftM<RT, IN, A>(ma);\n\n    static K<Consumer<RT, IN>, A> MonadIO<Consumer<RT, IN>>.LiftIO<A>(IO<A> ma) => \n        Consumer.liftIO<RT, IN, A>(ma); \n\n    static K<Consumer<RT, IN>, B> MonadUnliftIO<Consumer<RT, IN>>.MapIO<A, B>(K<Consumer<RT, IN>, A> ma, Func<IO<A>, IO<B>> f) => \n        ma.As().MapIO(f);\n\n    static K<Consumer<RT, IN>, IO<A>> MonadUnliftIO<Consumer<RT, IN>>.ToIO<A>(K<Consumer<RT, IN>, A> ma) => \n        ma.As().MapIO(IO.pure);\n\n    static K<Consumer<RT, IN>, B> Applicative<Consumer<RT, IN>>.Action<A, B>(\n        K<Consumer<RT, IN>, A> ma, \n        K<Consumer<RT, IN>, B> mb) =>\n        Consumer.liftM<RT, IN, B>(ma.As().Run().Action(mb.As().Run()));\n\n    static K<Consumer<RT, IN>, A> Applicative<Consumer<RT, IN>>.Actions<A>(\n        IterableNE<K<Consumer<RT, IN>, A>> fas) =>\n        fas.Select(fa => fa.As().Proxy.Kind())\n           .Actions()\n           .ToConsumer();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Consumer/Consumer.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class ConsumerExtensions\n{\n    extension<RT, IN, A>(K<Consumer<RT, IN>, A>)\n    {\n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static Consumer<RT, IN, A> operator +(K<Consumer<RT, IN>, A> ma) =>\n           (Consumer<RT, IN, A>) ma;\n        \n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static Consumer<RT, IN, A> operator >>(K<Consumer<RT, IN>, A> ma, Lower lower) =>\n           +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Consumer/Consumer.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `Consumer` streaming consumer monad-transformer instance\n/// </summary>\n/// <remarks>\n/// Unlike the general purpose `ConsumerT`, which will lift any monad, this type only lifts the `Eff` monad.\n/// </remarks>\npublic readonly record struct Consumer<RT, IN, A>(PipeT<IN, Void, Eff<RT>, A> Proxy) : K<Consumer<RT, IN>, A>\n{\n    [Pure]\n    public Consumer<RT, IN, B> Map<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n\n    [Pure]\n    public Consumer<RT, IN, B> MapM<B>(Func<Eff<RT, A>, Eff<RT, B>> f) =>\n        Proxy.MapM(ma => f(ma.As()));\n\n    [Pure]\n    public Consumer<RT, IN, B> MapIO<B>(Func<IO<A>, IO<B>> f) =>\n        Proxy.MapIO(f);\n\n    [Pure]\n    public Consumer<RT, IN, B> ApplyBack<B>(Consumer<RT, IN, Func<A, B>> ff) =>\n        Proxy.ApplyBack(ff.Proxy);\n    \n    [Pure]\n    public Consumer<RT, IN, B> Action<B>(Consumer<RT, IN, B> fb) =>\n        Proxy.Action(fb.Proxy);\n    \n    [Pure]\n    public Consumer<RT, IN, B> Bind<B>(Func<A, Consumer<RT, IN, B>> f) =>\n        Proxy.Bind(x => f(x).Proxy);\n    \n    [Pure]\n    public Consumer<RT, IN, B> Bind<B>(Func<A, IO<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    public Consumer<RT, IN, B> Bind<B>(Func<A, Eff<RT, B>> f) =>\n        Proxy.Bind(f).ToConsumer();\n   \n    [Pure]\n    public Consumer<RT, IN, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Proxy.Bind(f);\n   \n    [Pure]\n    public Consumer<RT, IN, B> Bind<B>(Func<A, Lift<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    internal Eff<RT, A> Run() =>\n        Proxy.Run().As();\n    \n    [Pure]\n    public Consumer<RT, IN, B> Select<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n   \n    [Pure]\n    public Consumer<RT, IN, C> SelectMany<B, C>(Func<A, Consumer<RT, IN, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(x => f(x).Proxy, g);\n   \n    [Pure]\n    public Consumer<RT, IN, C> SelectMany<B, C>(Func<A, Eff<RT, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Consumer<RT, IN, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Consumer<RT, IN, C> SelectMany<B, C>(Func<A, Pure<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Consumer<RT, IN, C> SelectMany<B, C>(Func<A, Lift<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n\n    [Pure]\n    public static implicit operator Consumer<RT, IN, A>(ConsumerT<IN, Eff<RT>, A> consumer) =>\n        consumer.Proxy;\n\n    [Pure]\n    public static implicit operator Consumer<RT, IN, A>(PipeT<IN, Void, Eff<RT>, A> pipe) =>\n        pipe.ToConsumer();\n\n    [Pure]\n    public static implicit operator Consumer<RT, IN, A>(Pipe<RT, IN, Void, A> pipe) =>\n        pipe.ToConsumer();\n\n    [Pure]\n    public static implicit operator Consumer<RT, IN, A>(Pure<A> rhs) =>\n        Consumer.pure<RT, IN, A>(rhs.Value);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ConsumerT/ConsumerT.Extensions.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class ConsumerTExtensions\n{\n    /// <summary>\n    /// Transformation from `PipeT` to `ConsumerT`.\n    /// </summary>\n    public static ConsumerT<IN, M, A> ToConsumer<IN, M, A>(this K<PipeT<IN, Void, M>, A> pipe)\n        where M : MonadIO<M> =>\n        new(pipe.As());\n\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    public static ConsumerT<IN, M, A> As<IN, M, A>(this K<ConsumerT<IN, M>, A> ma)\n        where M : MonadIO<M> =>\n        (ConsumerT<IN, M, A>)ma;\n    \n    /// <summary>\n    /// Convert to the `Eff` version of `Consumer`\n    /// </summary>\n    public static Consumer<RT, IN, A> ToEff<RT, IN, A>(this K<ConsumerT<IN, Eff<RT>>, A> ma) =>\n        ma.As();\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static ConsumerT<IN, M, C> SelectMany<IN, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, ConsumerT<IN, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        ConsumerT.liftM<IN, M, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static ConsumerT<IN, M, C> SelectMany<IN, M, A, B, C>(\n        this IO<A> ma, \n        Func<A, ConsumerT<IN, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        ConsumerT.liftIO<IN, M, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static ConsumerT<IN, M, C> SelectMany<IN, M, A, B, C>(\n        this Pure<A> ma, \n        Func<A, ConsumerT<IN, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        ConsumerT.pure<IN, M, A>(ma.Value).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static ConsumerT<IN, M, C> SelectMany<IN, M, A, B, C>(\n        this Lift<A> ff, \n        Func<A, ConsumerT<IN, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        ConsumerT.lift<IN, M, A>(ff.Function).SelectMany(f, g);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static ConsumerT<IN, M, B> Bind<IN, M, A, B>(\n        this K<M, A> ma, \n        Func<A, ConsumerT<IN, M, B>> f,\n        Func<A, B> g)\n        where M : MonadIO<M> =>\n        ConsumerT.liftM<IN, M, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static ConsumerT<IN, M, B> Bind<IN, M, A, B>(\n        this IO<A> ma, \n        Func<A, ConsumerT<IN, M, B>> f,\n        Func<A, B> g)\n        where M : MonadIO<M> =>\n        ConsumerT.liftIO<IN, M, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static ConsumerT<IN, M, B> Bind<IN, M, A, B>(\n        this Pure<A> ma, \n        Func<A, ConsumerT<IN, M, B>> f,\n        Func<A, B> g)\n        where M : MonadIO<M> =>\n        ConsumerT.pure<IN, M, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static ConsumerT<IN, M, B> Bind<IN, M, A, B>(\n        this Lift<A> ff, \n        Func<A, ConsumerT<IN, M, B>> f,\n        Func<A, B> g)\n        where M : MonadIO<M> =>\n        ConsumerT.lift<IN, M, A>(ff.Function).Bind(f);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static ConsumerT<IN, M, C> SelectMany<IN, E, M, A, C>(\n        this K<ConsumerT<IN, M>, A> ma,\n        Func<A, Guard<E, Unit>> bind,\n        Func<A, Unit, C> project)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        ma.Bind(a => bind(a) switch\n                     {\n                         { Flag: true } => ConsumerT.pure<IN, M, C>(project(a, default)),\n                         var guard      => ConsumerT.fail<IN, E, M, C>(guard.OnFalse())\n                     }).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static ConsumerT<IN, M, C> SelectMany<IN, E, M, B, C>(\n        this Guard<E, Unit> ma,\n        Func<Unit, K<ConsumerT<IN, M>, B>> bind,\n        Func<Unit, B, C> project)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        ma switch\n        {\n            { Flag: true } => bind(default).Map(b => project(default, b)).As(),\n            var guard      => ConsumerT.fail<IN, E, M, C>(guard.OnFalse())\n        };     \n\n    [Pure]\n    public static ConsumerT<IN, M, B> MapIO<IN, M, A, B>(this ConsumerT<IN, M, A> ma, Func<IO<A>, IO<B>> f) \n        where M : MonadUnliftIO<M> =>\n        ma.Proxy.MapIO(f);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ConsumerT/ConsumerT.Module.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `ConsumerT` streaming consumer monad-transformer\n/// </summary>\npublic static class ConsumerT\n{\n    /// <summary>\n    /// Await a value from upstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, IN> awaiting<M, IN>()\n        where M : MonadIO<M> =>\n        PipeT.awaiting<M, IN, Void>();\n\n    /// <summary>\n    /// Await a value from upstream and then ignore it\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, Unit> awaitIgnore<M, IN>()\n        where M : MonadIO<M> =>\n        new PipeTAwait<IN, Void, M, Unit>(_ => PipeT.pure<IN, Void, M, Unit>(default));\n\n    /// <summary>\n    /// Create a consumer that simply returns a bound value without awaiting anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to await</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> pure<IN, M, A>(A value)\n        where M : MonadIO<M> =>\n        PipeT.pure<IN, Void, M, A>(value);\n\n    /// <summary>\n    /// Create a consumer that always fails\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to await</typeparam>\n    /// <typeparam name=\"E\">Failure type</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> fail<IN, E, M, A>(E value)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        PipeT.fail<IN, Void, E, M, A>(value);\n\n    /// <summary>\n    /// Create a consumer that always fails\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to await</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> error<IN, M, A>(Error value)\n        where M : MonadIO<M>, Fallible<M> =>\n        PipeT.fail<IN, Void, Error, M, A>(value);\n\n    /// <summary>\n    /// Create a consumer that yields nothing at all\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> empty<IN, M, A>()\n        where M : MonadIO<M>, MonoidK<M> =>\n        PipeT.empty<IN, Void, M, A>();\n\n    /// <summary>\n    /// Create a consumer that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> lift<IN, M, A>(Func<A> f)\n        where M : MonadIO<M> =>\n        PipeT.lift<IN, Void, M, A>(f);\n\n    /// <summary>\n    /// Create a lazy consumer \n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> liftT<IN, M, A>(Func<ConsumerT<IN, M, A>> f)\n        where M : MonadIO<M> =>\n        PipeT.liftT(() => f().Proxy);\n\n    /// <summary>\n    /// Create an asynchronous lazy consumer \n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> liftT<IN, M, A>(Func<ValueTask<ConsumerT<IN, M, A>>> f)\n        where M : MonadIO<M> =>\n        PipeT.liftT(() => f().Map(x => x.Proxy));\n\n    /// <summary>\n    /// Create an asynchronous consumer \n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> liftT<IN, M, A>(ValueTask<ConsumerT<IN, M, A>> f)\n        where M : MonadIO<M> =>\n        PipeT.liftT(f.Map(x => x.Proxy));\n\n    /// <summary>\n    /// Create a consumer that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> liftM<IN, M, A>(K<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.liftM<IN, Void, M, A>(ma);\n\n    /// <summary>\n    /// Create a consumer that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> liftIO<IN, M, A>(IO<A> ma)\n        where M : MonadIO<M> =>\n        PipeT.liftIO<IN, Void, M, A>(ma);\n\n    /// <summary>\n    /// Continually repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> repeat<IN, M, A>(ConsumerT<IN, M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeat(ma.Proxy).ToConsumer();\n    \n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> repeat<IN, M, A>(Schedule schedule, ConsumerT<IN, M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeat(schedule, ma.Proxy).ToConsumer();\n\n    /// <summary>\n    /// Continually lift and repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> repeatM<IN, M, A>(K<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeatM<IN, Void, M, A>(ma).ToConsumer();\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ConsumerT<IN, M, A> repeatM<IN, M, A>(Schedule schedule, K<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeatM<IN, Void, M, A>(schedule, ma).ToConsumer();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ConsumerT/ConsumerT.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic class ConsumerT<IN, M> : \n    MonadT<ConsumerT<IN, M>, M>,\n    MonadUnliftIO<ConsumerT<IN, M>>\n    where M : MonadIO<M>\n{\n    static K<ConsumerT<IN, M>, B> Monad<ConsumerT<IN, M>>.Bind<A, B>(\n        K<ConsumerT<IN, M>, A> ma, \n        Func<A, K<ConsumerT<IN, M>, B>> f) => \n        ma.As().Bind(x => f(x).As());\n\n    static K<ConsumerT<IN, M>, B> Monad<ConsumerT<IN, M>>.Recur<A, B>(A value, Func<A, K<ConsumerT<IN, M>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<ConsumerT<IN, M>, B> Functor<ConsumerT<IN, M>>.Map<A, B>(\n        Func<A, B> f, \n        K<ConsumerT<IN, M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<ConsumerT<IN, M>, A> Applicative<ConsumerT<IN, M>>.Pure<A>(A value) => \n        ConsumerT.pure<IN, M, A>(value);\n\n    static K<ConsumerT<IN, M>, B> Applicative<ConsumerT<IN, M>>.Apply<A, B>(\n        K<ConsumerT<IN, M>, Func<A, B>> mf,\n        K<ConsumerT<IN, M>, A> ma) =>\n        ma.As().ApplyBack(mf.As());\n\n    static K<ConsumerT<IN, M>, B> Applicative<ConsumerT<IN, M>>.Apply<A, B>(\n        K<ConsumerT<IN, M>, Func<A, B>> mf,\n        Memo<ConsumerT<IN, M>, A> ma) =>\n        new PipeTMemo<IN, Void, M, A>(ma.Lower().Map(ma => ma.As().Proxy.Kind()).Lift())\n           .ApplyBack(mf.As().Proxy)\n           .ToConsumer();\n\n    static K<ConsumerT<IN, M>, A> MonadT<ConsumerT<IN, M>, M>.Lift<A>(K<M, A> ma) =>\n        ConsumerT.liftM<IN, M, A>(ma);\n\n    static K<ConsumerT<IN, M>, A> MonadIO<ConsumerT<IN, M>>.LiftIO<A>(IO<A> ma) => \n        ConsumerT.liftIO<IN, M, A>(ma); \n\n    static K<ConsumerT<IN, M>, B> MonadUnliftIO<ConsumerT<IN, M>>.MapIO<A, B>(K<ConsumerT<IN, M>, A> ma, Func<IO<A>, IO<B>> f) => \n        ma.As().MapM(m => M.MapIOMaybe(m, f));\n\n    static K<ConsumerT<IN, M>, IO<A>> MonadUnliftIO<ConsumerT<IN, M>>.ToIO<A>(K<ConsumerT<IN, M>, A> ma) => \n        ma.As().MapM(M.ToIOMaybe);\n\n    static K<ConsumerT<IN, M>, B> Applicative<ConsumerT<IN, M>>.Action<A, B>(\n        K<ConsumerT<IN, M>, A> ma, \n        K<ConsumerT<IN, M>, B> mb) =>\n        ConsumerT.liftM<IN, M, B>(ma.As().Run().Action(mb.As().Run()));\n\n    static K<ConsumerT<IN, M>, A> Applicative<ConsumerT<IN, M>>.Actions<A>(\n        IterableNE<K<ConsumerT<IN, M>, A>> fas) =>\n        fas.Select(fa => fa.As().Proxy.Kind())\n           .Actions()\n           .ToConsumer();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ConsumerT/ConsumerT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class ConsumerTExtensions\n{\n    extension<IN, M, A>(K<ConsumerT<IN, M>, A>)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static ConsumerT<IN, M, A> operator +(K<ConsumerT<IN, M>, A> ma) =>\n           (ConsumerT<IN, M, A>) ma;\n        \n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static ConsumerT<IN, M, A> operator >>(K<ConsumerT<IN, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ConsumerT/ConsumerT.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `ConsumerT` streaming consumer monad-transformer instance\n/// </summary>\npublic readonly record struct ConsumerT<IN, M, A>(PipeT<IN, Void, M, A> Proxy) : K<ConsumerT<IN, M>, A>\n    where M : MonadIO<M>\n{\n    [Pure]\n    public ConsumerT<IN, M, B> Map<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n    \n    [Pure]\n    public ConsumerT<IN, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        Proxy.MapM(f);\n\n    [Pure]\n    public ConsumerT<IN, M, B> ApplyBack<B>(ConsumerT<IN, M, Func<A, B>> ff) =>\n        Proxy.ApplyBack(ff.Proxy);\n    \n    [Pure]\n    public ConsumerT<IN, M, B> Action<B>(ConsumerT<IN, M, B> fb) =>\n        Proxy.Action(fb.Proxy);\n    \n    [Pure]\n    public ConsumerT<IN, M, B> Bind<B>(Func<A, ConsumerT<IN, M, B>> f) =>\n        Proxy.Bind(x => f(x).Proxy);\n    \n    [Pure]\n    public ConsumerT<IN, M, B> Bind<B>(Func<A, IO<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    public ConsumerT<IN, M, B> Bind<B>(Func<A, K<M, B>> f) =>\n        Proxy.Bind(f);\n   \n    [Pure]\n    public ConsumerT<IN, M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Proxy.Bind(f);\n   \n    [Pure]\n    public ConsumerT<IN, M, B> Bind<B>(Func<A, Lift<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    internal K<M, A> Run() =>\n        Proxy.Run();\n    \n    [Pure]\n    public ConsumerT<IN, M, B> Select<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n   \n    [Pure]\n    public ConsumerT<IN, M, C> SelectMany<B, C>(Func<A, ConsumerT<IN, M, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(x => f(x).Proxy, g);\n   \n    [Pure]\n    public ConsumerT<IN, M, C> SelectMany<B, C>(Func<A, K<M, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public ConsumerT<IN, M, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public ConsumerT<IN, M, C> SelectMany<B, C>(Func<A, Pure<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public ConsumerT<IN, M, C> SelectMany<B, C>(Func<A, Lift<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n\n    [Pure]\n    public static implicit operator ConsumerT<IN, M, A>(PipeT<IN, Void, M, A> pipe) =>\n        pipe.ToConsumer();\n    \n    [Pure]\n    public static implicit operator ConsumerT<IN, M, A>(Pure<A> rhs) =>\n        ConsumerT.pure<IN, M, A>(rhs.Value);\n    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Effect/Effect.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class EffectExtensions\n{\n    /// <summary>\n    /// Transformation from `PipeT` to `EffectT`.\n    /// </summary>\n    public static Effect<RT, A> ToEffect<RT, A>(this K<PipeT<Unit, Void, Eff<RT>>, A> pipe) =>\n        new(pipe.As());\n\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    public static Effect<RT, A> As<RT, A>(this K<Effect<RT>, A> ma) =>\n        (Effect<RT, A>)ma;\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Effect<RT, C> SelectMany<RT, A, B, C>(\n        this K<Eff<RT>, A> ma, \n        Func<A, Effect<RT, B>> f,\n        Func<A, B, C> g) =>\n        Effect.liftM(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Effect<RT, C> SelectMany<RT, A, B, C>(\n        this IO<A> ma, \n        Func<A, Effect<RT, B>> f,\n        Func<A, B, C> g) =>\n        Effect.liftIO<RT, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Effect<RT, C> SelectMany<RT, A, B, C>(\n        this Pure<A> ma, \n        Func<A, Effect<RT, B>> f,\n        Func<A, B, C> g) =>\n        Effect.pure<RT, A>(ma.Value).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Effect<RT, C> SelectMany<RT, A, B, C>(\n        this Lift<A> ff, \n        Func<A, Effect<RT, B>> f,\n        Func<A, B, C> g) =>\n        Effect.lift<RT, A>(ff.Function).SelectMany(f, g);    \n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Effect<RT, B> Bind<RT, A, B>(\n        this K<Eff<RT>, A> ma, \n        Func<A, Effect<RT, B>> f) =>\n        Effect.liftM(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Effect<RT, B> Bind<RT, A, B>(\n        this IO<A> ma, \n        Func<A, Effect<RT, B>> f) =>\n        Effect.liftIO<RT, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Effect<RT, B> Bind<RT, A, B>(\n        this Pure<A> ma, \n        Func<A, Effect<RT, B>> f) =>\n        Effect.pure<RT, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Effect<RT, B> Bind<RT, A, B>(\n        this Lift<A> ff, \n        Func<A, Effect<RT, B>> f) =>\n        Effect.lift<RT, A>(ff.Function).Bind(f);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static Effect<RT, C> SelectMany<RT, A, C>(\n        this K<Effect<RT>, A> ma,\n        Func<A, Guard<Error, Unit>> bind,\n        Func<A, Unit, C> project) =>\n        ma.Bind(a => bind(a) switch\n                     {\n                         { Flag: true } => Effect.pure<RT, C>(project(a, default)),\n                         var guard      => Effect.error<RT, C>(guard.OnFalse())\n                     }).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static Effect<RT, C> SelectMany<RT, B, C>(\n        this Guard<Error, Unit> ma,\n        Func<Unit, K<Effect<RT>, B>> bind,\n        Func<Unit, B, C> project) =>\n        ma switch\n        {\n            { Flag: true } => bind(default).Map(b => project(default, b)).As(),\n            var guard      => Effect.error<RT, C>(guard.OnFalse())\n        };    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Effect/Effect.Module.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `Effect` streaming effect monad-transformer\n/// </summary>\npublic static class Effect\n{\n    /// <summary>\n    /// Create an effect that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> pure<RT, A>(A value) =>\n        PipeT.pure<Unit, Void, Eff<RT>, A>(value);\n    \n    /// <summary>\n    /// Create an effect that always fails\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> error<RT, A>(Error value) =>\n        PipeT.error<Unit, Void, Eff<RT>, A>(value);\n    \n    /// <summary>\n    /// Create an effect that yields nothing at all\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> empty<RT, A>() =>\n        PipeT.empty<Unit, Void, Eff<RT>, A>();\n    \n    /// <summary>\n    /// Create an effect that lazily returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> lift<RT, A>(Func<A> f) =>\n        PipeT.lift<Unit, Void, Eff<RT>, A>(f);\n    \n    /// <summary>\n    /// Create an effect that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> liftM<RT, A>(K<Eff<RT>, A> ma) =>\n        PipeT.liftM<Unit, Void, Eff<RT>, A>(ma);\n    \n    /// <summary>\n    /// Create an effect that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> liftIO<RT, A>(IO<A> ma) =>\n        PipeT.liftIO<Unit, Void, Eff<RT>, A>(ma);\n        \n    /// <summary>\n    /// Create a lazy proxy \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> liftT<RT, A>(Func<Effect<RT, A>> f) =>\n        PipeT.liftT(() => f().Proxy);\n    \n    /// <summary>\n    /// Create an asynchronous lazy proxy \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> liftT<RT, A>(Func<ValueTask<Effect<RT, A>>> f) =>\n        PipeT.liftT(() => f().Map(p => p.Proxy));\n    \n    /// <summary>\n    /// Create an asynchronous proxy \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> liftT<RT, A>(ValueTask<Effect<RT, A>> f) =>\n        PipeT.liftT(f.Map(p => p.Proxy));\n\n    /// <summary>\n    /// Continually repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> repeat<RT, A>(Effect<RT, A> ma) =>\n        PipeT.repeat(ma.Proxy).ToEffect();\n    \n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> repeat<RT, A>(Schedule schedule, Effect<RT, A> ma) =>\n        PipeT.repeat(schedule, ma.Proxy).ToEffect();\n\n    /// <summary>\n    /// Continually lift and repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> repeatM<RT, A>(K<Eff<RT>, A> ma) =>\n        PipeT.repeatM<Unit, Void, Eff<RT>, A>(ma).ToEffect();\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Effect<RT, A> repeatM<RT, A>(Schedule schedule, K<Eff<RT>, A> ma) =>\n        PipeT.repeatM<Unit, Void, Eff<RT>, A>(schedule, ma).ToEffect();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Effect/Effect.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Async.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic class Effect<RT> : \n    MonadT<Effect<RT>, Eff<RT>>,\n    MonadUnliftIO<Effect<RT>>\n{\n    static K<Effect<RT>, B> Monad<Effect<RT>>.Bind<A, B>(K<Effect<RT>, A> ma, Func<A, K<Effect<RT>, B>> f) => \n        ma.As().Bind(x => f(x).As());\n\n    static K<Effect<RT>, B> Monad<Effect<RT>>.Recur<A, B>(A value, Func<A, K<Effect<RT>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<Effect<RT>, B> Functor<Effect<RT>>.Map<A, B>(Func<A, B> f, K<Effect<RT>, A> ma) => \n        ma.As().Map(f);\n\n    static K<Effect<RT>, A> Applicative<Effect<RT>>.Pure<A>(A value) => \n        Effect.pure<RT, A>(value);\n\n    static K<Effect<RT>, B> Applicative<Effect<RT>>.Apply<A, B>(K<Effect<RT>, Func<A, B>> mf, K<Effect<RT>, A> ma) => \n        ma.As().ApplyBack(mf.As());\n\n    static K<Effect<RT>, B> Applicative<Effect<RT>>.Apply<A, B>(K<Effect<RT>, Func<A, B>> mf, Memo<Effect<RT>, A> ma) => \n        new PipeTMemo<Unit, Void, Eff<RT>, A>(ma.Lower().Map(ma => ma.As().Proxy.Kind()).Lift())\n            .ApplyBack(mf.As().Proxy)\n            .ToEffect();\n\n    static K<Effect<RT>, A> MonadT<Effect<RT>, Eff<RT>>.Lift<A>(K<Eff<RT>, A> ma) =>\n        Effect.liftM(ma);\n\n    static K<Effect<RT>, A> MonadIO<Effect<RT>>.LiftIO<A>(IO<A> ma) => \n        Effect.liftIO<RT, A>(ma);\n\n    static K<Effect<RT>, B> MonadUnliftIO<Effect<RT>>.MapIO<A, B>(K<Effect<RT>, A> ma, Func<IO<A>, IO<B>> f) => \n        ma.As().MapIO(f);\n\n    static K<Effect<RT>, IO<A>> MonadUnliftIO<Effect<RT>>.ToIO<A>(K<Effect<RT>, A> ma) =>\n        ma.MapIO(IO.pure);\n\n    static K<Effect<RT>, ForkIO<A>> MonadUnliftIO<Effect<RT>>.ForkIO<A>(\n        K<Effect<RT>, A> ma,\n        Option<TimeSpan> timeout) =>\n        Effect.liftM(ma.As().Run().ForkIO(timeout));\n    \n    static K<Effect<RT>, B> Applicative<Effect<RT>>.Action<A, B>(\n        K<Effect<RT>, A> ma, \n        K<Effect<RT>, B> mb) =>\n        Effect.liftM(ma.As().Run().Action(mb.As().Run()));\n\n    static K<Effect<RT>, A> Applicative<Effect<RT>>.Actions<A>(\n        IterableNE<K<Effect<RT>, A>> fas) =>\n        fas.Select(fa => fa.As().Proxy.Kind())\n           .Actions()\n           .ToEffect();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Effect/Effect.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class EffectExtensions\n{\n    extension<RT, A>(K<Effect<RT>, A>)\n    {\n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static Effect<RT, A> operator +(K<Effect<RT>, A> ma) =>\n           (Effect<RT, A>) ma;\n        \n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static Effect<RT, A> operator >>(K<Effect<RT>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Effect/Effect.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic readonly record struct Effect<RT, A>(PipeT<Unit, Void, Eff<RT>, A> Proxy) : K<Effect<RT>, A>\n{\n    [Pure]\n    public Effect<RT, B> Map<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n\n    [Pure]\n    public Effect<RT, B> MapM<B>(Func<Eff<RT, A>, Eff<RT, B>> f) =>\n        Proxy.MapM(mx => f(mx.As())).ToEffect();\n\n    [Pure]\n    public Effect<RT, B> MapIO<B>(Func<IO<A>, IO<B>> f) =>\n        Proxy.MapIO(f);\n    \n    [Pure]\n    public Effect<RT, B> ApplyBack<B>(Effect<RT, Func<A, B>> ff) =>\n        Proxy.ApplyBack(ff.Proxy);\n    \n    [Pure]\n    public Effect<RT, B> Action<B>(Effect<RT, B> fb) =>\n        Proxy.Action(fb.Proxy);\n    \n    [Pure]\n    public Effect<RT, B> Bind<B>(Func<A, Effect<RT, B>> f) =>\n        Proxy.Bind(x => f(x).Proxy);\n    \n    [Pure]\n    public Effect<RT, B> Bind<B>(Func<A, K<Eff<RT>, B>> f) => \n        Proxy.Bind(f);\n    \n    [Pure]\n    public Effect<RT, B> Bind<B>(Func<A, IO<B>> f) => \n        Proxy.Bind(f);\n       \n    [Pure]\n    public Effect<RT, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Proxy.Bind(f);\n   \n    [Pure]\n    public Effect<RT, B> Bind<B>(Func<A, Lift<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    public Effect<RT, B> Select<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n   \n    [Pure]\n    public Effect<RT, C> SelectMany<B, C>(Func<A, Effect<RT, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(x => f(x).Proxy, g);\n\n    [Pure]\n    public Effect<RT, C> SelectMany<B, C>(Func<A, K<Eff<RT>, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n\n    [Pure]\n    public Effect<RT, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Effect<RT, C> SelectMany<B, C>(Func<A, Pure<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Effect<RT, C> SelectMany<B, C>(Func<A, Lift<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n\n    [Pure]\n    public Eff<RT, A> Run() =>\n        Proxy.Run().As();\n    \n    [Pure]\n    public static implicit operator Effect<RT, A>(PipeT<Unit, Void, Eff<RT>, A> pipe) =>\n        pipe.ToEffect();\n    \n    [Pure]\n    public static implicit operator Effect<RT, A>(EffectT<Eff<RT>, A> pipe) =>\n        pipe.Proxy;\n    \n    [Pure]\n    public static implicit operator Effect<RT, A>(Pure<A> rhs) =>\n        Effect.pure<RT, A>(rhs.Value);\n    \n    [Pure]\n    public static Effect<RT, A> operator |(Schedule lhs, Effect<RT, A> rhs) =>\n        ReferenceEquals(lhs, Schedule.Forever)\n            ? Effect.repeat(rhs)\n            : Effect.repeat(lhs, rhs);\n    \n    [Pure]\n    public static Effect<RT, A> operator |(Effect<RT, A> lhs, Schedule rhs) =>\n        ReferenceEquals(rhs, Schedule.Forever)\n            ? Effect.repeat(lhs)\n            : Effect.repeat(rhs, lhs);      \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/EffectT/EffectT.Extensions.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class EffectTExtensions\n{\n    /// <summary>\n    /// Transformation from `PipeT` to `EffectT`.\n    /// </summary>\n    [Pure]\n    public static EffectT<M, A> ToEffect<M, A>(this K<PipeT<Unit, Void, M>, A> pipe)\n        where M : MonadIO<M> =>\n        new(pipe.As());\n\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    [Pure]\n    public static EffectT<M, A> As<M, A>(this K<EffectT<M>, A> ma)\n        where M : MonadIO<M> =>\n        (EffectT<M, A>)ma;\n    \n    /// <summary>\n    /// Convert to the `Eff` version of `Effect`\n    /// </summary>\n    [Pure]\n    public static Effect<RT, A> ToEff<RT, A>(this K<EffectT<Eff<RT>>, A> ma) =>\n        ma.As();\n\n    /// <summary>\n    /// Convert to the `Eff` version of `Effect`\n    /// </summary>\n    [Pure]\n    public static EffectT<Eff<RT>, A> FromEff<RT, A>(this K<Effect<RT>, A> ma) =>\n        new(ma.As().Proxy);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static EffectT<M, C> SelectMany<M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, EffectT<M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        EffectT.liftM(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static EffectT<M, C> SelectMany<M, A, B, C>(\n        this IO<A> ma, \n        Func<A, EffectT<M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        EffectT.liftIO<M, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static EffectT<M, C> SelectMany<M, A, B, C>(\n        this Pure<A> ma, \n        Func<A, EffectT<M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        EffectT.pure<M, A>(ma.Value).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static EffectT<M, C> SelectMany<M, A, B, C>(\n        this Lift<A> ff, \n        Func<A, EffectT<M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        EffectT.lift<M, A>(ff.Function).SelectMany(f, g);    \n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static EffectT<M, B> Bind<M, A, B>(\n        this K<M, A> ma, \n        Func<A, EffectT<M, B>> f)\n        where M : MonadIO<M> =>\n        EffectT.liftM(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static EffectT<M, B> Bind<M, A, B>(\n        this IO<A> ma, \n        Func<A, EffectT<M, B>> f)\n        where M : MonadIO<M> =>\n        EffectT.liftIO<M, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static EffectT<M, B> Bind<M, A, B>(\n        this Pure<A> ma, \n        Func<A, EffectT<M, B>> f)\n        where M : MonadIO<M> =>\n        EffectT.pure<M, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static EffectT<M, B> Bind<M, A, B>(\n        this Lift<A> ff, \n        Func<A, EffectT<M, B>> f)\n        where M : MonadIO<M> =>\n        EffectT.lift<M, A>(ff.Function).Bind(f);\n    \n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    public static EffectT<M, C> SelectMany<E, M, A, C>(\n        this K<EffectT<M>, A> ma,\n        Func<A, Guard<E, Unit>> bind,\n        Func<A, Unit, C> project)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        ma.Bind(a => bind(a) switch\n                     {\n                         { Flag: true } => EffectT.pure<M, C>(project(a, default)),\n                         var guard      => EffectT.fail<E, M, C>(guard.OnFalse())\n                     }).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    public static EffectT<M, C> SelectMany<E, M, B, C>(\n        this Guard<E, Unit> ma,\n        Func<Unit, K<EffectT<M>, B>> bind,\n        Func<Unit, B, C> project)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        ma switch\n        {\n            { Flag: true } => bind(default).Map(b => project(default, b)).As(),\n            var guard      => EffectT.fail<E, M, C>(guard.OnFalse())\n        };\n\n    [Pure]\n    public static EffectT<M, B> MapIO<M, A, B>(this K<EffectT<M>, A> ma, Func<IO<A>, IO<B>> f)\n        where M : MonadUnliftIO<M> =>\n        ma.As().MapM(m => M.MapIOMaybe(m, f));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/EffectT/EffectT.Module.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `EffectT` streaming effect monad-transformer\n/// </summary>\npublic static class EffectT\n{\n    /// <summary>\n    /// Create an effect that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> pure<M, A>(A value)\n        where M : MonadIO<M> =>\n        PipeT.pure<Unit, Void, M, A>(value);\n    \n    /// <summary>\n    /// Create an effect that always fails\n    /// </summary>\n    /// <typeparam name=\"E\">Failure type</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> fail<E, M, A>(E value) \n        where M : MonadIO<M>, Fallible<E, M> =>\n        PipeT.fail<Unit, Void, E, M, A>(value);\n    \n    /// <summary>\n    /// Create an effect that always fails\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> error<M, A>(Error value) \n        where M : MonadIO<M>, Fallible<M> =>\n        PipeT.error<Unit, Void, M, A>(value);\n    \n    /// <summary>\n    /// Create an effect that yields nothing at all\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> empty<M, A>() \n        where M : MonadIO<M>, MonoidK<M> =>\n        PipeT.empty<Unit, Void, M, A>();\n    \n    /// <summary>\n    /// Create an effect that lazily returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> lift<M, A>(Func<A> f) \n        where M : MonadIO<M> =>\n        PipeT.lift<Unit, Void, M, A>(f);\n    \n    /// <summary>\n    /// Create an effect that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> liftM<M, A>(K<M, A> ma) \n        where M : MonadIO<M> =>\n        PipeT.liftM<Unit, Void, M, A>(ma);\n    \n    /// <summary>\n    /// Create an effect that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> liftIO<M, A>(IO<A> ma) \n        where M : MonadIO<M> =>\n        PipeT.liftIO<Unit, Void, M, A>(ma);\n        \n    /// <summary>\n    /// Create a lazy proxy \n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> liftT<M, A>(Func<EffectT<M, A>> f) \n        where M : MonadIO<M> =>\n        PipeT.liftT(() => f().Proxy);\n    \n    /// <summary>\n    /// Create an asynchronous lazy proxy \n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> liftT<M, A>(Func<ValueTask<EffectT<M, A>>> f) \n        where M : MonadIO<M> =>\n        PipeT.liftT(() => f().Map(p => p.Proxy));\n    \n    /// <summary>\n    /// Create an asynchronous proxy \n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> liftT<M, A>(ValueTask<EffectT<M, A>> f) \n        where M : MonadIO<M> =>\n        PipeT.liftT(f.Map(p => p.Proxy));\n\n    /// <summary>\n    /// Continually repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> repeat<M, A>(EffectT<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeat(ma.Proxy).ToEffect();\n    \n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> repeat<M, A>(Schedule schedule, EffectT<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeat(schedule, ma.Proxy).ToEffect();\n\n    /// <summary>\n    /// Continually lift and repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> repeatM<M, A>(K<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeatM<Unit, Void, M, A>(ma).ToEffect();\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static EffectT<M, A> repeatM<M, A>(Schedule schedule, K<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeatM<Unit, Void, M, A>(schedule, ma).ToEffect();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/EffectT/EffectT.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Async.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic class EffectT<M> :\n    MonadT<EffectT<M>, M>,\n    MonadUnliftIO<EffectT<M>>\n    where M : MonadIO<M>\n{\n    static K<EffectT<M>, B> Monad<EffectT<M>>.Bind<A, B>(K<EffectT<M>, A> ma, Func<A, K<EffectT<M>, B>> f) =>\n        ma.As().Bind(x => f(x).As());\n\n    static K<EffectT<M>, B> Monad<EffectT<M>>.Recur<A, B>(A value, Func<A, K<EffectT<M>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<EffectT<M>, B> Functor<EffectT<M>>.Map<A, B>(Func<A, B> f, K<EffectT<M>, A> ma) =>\n        ma.As().Map(f);\n\n    static K<EffectT<M>, A> Applicative<EffectT<M>>.Pure<A>(A value) =>\n        EffectT.pure<M, A>(value);\n\n    static K<EffectT<M>, B> Applicative<EffectT<M>>.Apply<A, B>(K<EffectT<M>, Func<A, B>> mf, K<EffectT<M>, A> ma) =>\n        ma.As().ApplyBack(mf.As());\n\n    static K<EffectT<M>, B> Applicative<EffectT<M>>.Apply<A, B>(K<EffectT<M>, Func<A, B>> mf, Memo<EffectT<M>, A> ma) =>\n        new PipeTMemo<Unit, Void, M, A>(ma.Lower().Map(ma => ma.As().Proxy.Kind()).Lift())\n           .ApplyBack(mf.As().Proxy)\n           .ToEffect();\n    \n    static K<EffectT<M>, A> MonadT<EffectT<M>, M>.Lift<A>(K<M, A> ma) =>\n        EffectT.liftM(ma);\n\n    static K<EffectT<M>, A> MonadIO<EffectT<M>>.LiftIO<A>(IO<A> ma) =>\n        EffectT.liftIO<M, A>(ma);\n\n    static K<EffectT<M>, B> MonadUnliftIO<EffectT<M>>.MapIO<A, B>(K<EffectT<M>, A> ma, Func<IO<A>, IO<B>> f) =>\n        ma.As().MapM(m => M.MapIOMaybe(m, f));\n\n    static K<EffectT<M>, IO<A>> MonadUnliftIO<EffectT<M>>.ToIO<A>(K<EffectT<M>, A> ma) =>\n        ma.As().MapM(M.ToIOMaybe);\n\n    static K<EffectT<M>, ForkIO<A>> MonadUnliftIO<EffectT<M>>.ForkIO<A>(\n        K<EffectT<M>, A> ma,\n        Option<TimeSpan> timeout) =>\n        MonadT.lift<EffectT<M>, M, ForkIO<A>>(ma.As().Run().ForkIOMaybe(timeout));\n    \n    static K<EffectT<M>, B> Applicative<EffectT<M>>.Action<A, B>(\n        K<EffectT<M>, A> ma,\n        K<EffectT<M>, B> mb) =>\n        EffectT.liftM(ma.As().Run().Action(mb.As().Run()));\n\n    static K<EffectT<M>, A> Applicative<EffectT<M>>.Actions<A>(\n        IterableNE<K<EffectT<M>, A>> fas) =>\n        fas.Select(fa => fa.As().Proxy.Kind())\n           .Actions()\n           .ToEffect();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/EffectT/EffectT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class EffectTExtensions\n{\n    extension<M, A>(K<EffectT<M>, A>)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static EffectT<M, A> operator +(K<EffectT<M>, A> ma) =>\n           (EffectT<M, A>) ma;\n        \n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static EffectT<M, A> operator >>(K<EffectT<M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/EffectT/EffectT.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic readonly record struct EffectT<M, A>(PipeT<Unit, Void, M, A> Proxy) : K<EffectT<M>, A>\n    where M : MonadIO<M>\n{\n    [Pure]\n    public EffectT<M, B> Map<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n\n    [Pure]\n    public EffectT<M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        Proxy.MapM(f);\n    \n    [Pure]\n    public EffectT<M, B> ApplyBack<B>(EffectT<M, Func<A, B>> ff) =>\n        Proxy.ApplyBack(ff.Proxy);\n    \n    [Pure]\n    public EffectT<M, B> Action<B>(EffectT<M, B> fb) =>\n        Proxy.Action(fb.Proxy);\n    \n    [Pure]\n    public EffectT<M, B> Bind<B>(Func<A, EffectT<M, B>> f) =>\n        Proxy.Bind(x => f(x).Proxy);\n    \n    [Pure]\n    public EffectT<M, B> Bind<B>(Func<A, K<M, B>> f) => \n        Proxy.Bind(f);\n    \n    [Pure]\n    public EffectT<M, B> Bind<B>(Func<A, IO<B>> f) => \n        Proxy.Bind(f);\n       \n    [Pure]\n    public EffectT<M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Proxy.Bind(f);\n   \n    [Pure]\n    public EffectT<M, B> Bind<B>(Func<A, Lift<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    public EffectT<M, B> Select<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n   \n    [Pure]\n    public EffectT<M, C> SelectMany<B, C>(Func<A, EffectT<M, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(x => f(x).Proxy, g);\n\n    [Pure]\n    public EffectT<M, C> SelectMany<B, C>(Func<A, K<M, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n\n    [Pure]\n    public EffectT<M, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public EffectT<M, C> SelectMany<B, C>(Func<A, Pure<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public EffectT<M, C> SelectMany<B, C>(Func<A, Lift<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n\n    [Pure]\n    public K<M, A> Run() =>\n        Proxy.Run();\n    \n    [Pure]\n    public static implicit operator EffectT<M, A>(PipeT<Unit, Void, M, A> pipe) =>\n        pipe.ToEffect();\n    \n    [Pure]\n    public static implicit operator EffectT<M, A>(Pure<A> rhs) =>\n        EffectT.pure<M, A>(rhs.Value);\n    \n    [Pure]\n    public static EffectT<M, A> operator |(Schedule lhs, EffectT<M, A> rhs) =>\n        ReferenceEquals(lhs, Schedule.Forever)\n            ? EffectT.repeat(rhs)\n            : EffectT.repeat(lhs, rhs);\n    \n    [Pure]\n    public static EffectT<M, A> operator |(EffectT<M, A> lhs, Schedule rhs) =>\n        ReferenceEquals(rhs, Schedule.Forever)\n            ? EffectT.repeat(lhs)\n            : EffectT.repeat(rhs, lhs);    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Pipe/Pipe.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class PipeExtensions\n{\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    public static Pipe<RT, IN, OUT, A> As<RT, IN, OUT, A>(this K<Pipe<RT, IN, OUT>, A> ma) =>\n        (Pipe<RT, IN, OUT, A>)ma;\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Pipe<RT, IN, OUT, C> SelectMany<RT, IN, OUT, A, B, C>(\n        this K<Eff<RT>, A> ma, \n        Func<A, Pipe<RT, IN, OUT, B>> f,\n        Func<A, B, C> g) =>\n        Pipe.liftM<RT, IN, OUT, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Pipe<RT, IN, OUT, C> SelectMany<RT, IN, OUT, A, B, C>(\n        this IO<A> ma, \n        Func<A, Pipe<RT, IN, OUT, B>> f,\n        Func<A, B, C> g) =>\n        Pipe.liftIO<RT, IN, OUT, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Pipe<RT, IN, OUT, C> SelectMany<RT, IN, OUT, A, B, C>(\n        this Pure<A> ma, \n        Func<A, Pipe<RT, IN, OUT, B>> f,\n        Func<A, B, C> g) =>\n        Pipe.pure<RT, IN, OUT, A>(ma.Value).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Pipe<RT, IN, OUT, C> SelectMany<RT, IN, OUT, A, B, C>(\n        this Lift<A> ff, \n        Func<A, Pipe<RT, IN, OUT, B>> f,\n        Func<A, B, C> g) =>\n        Pipe.lift<RT, IN, OUT, A>(ff.Function).SelectMany(f, g);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Pipe<RT, IN, OUT, B> Bind<RT, IN, OUT, A, B>(\n        this K<Eff<RT>, A> ma, \n        Func<A, Pipe<RT, IN, OUT, B>> f) =>\n        Pipe.liftM<RT, IN, OUT, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Pipe<RT, IN, OUT, B> Bind<RT, IN, OUT, A, B>(\n        this IO<A> ma, \n        Func<A, Pipe<RT, IN, OUT, B>> f) =>\n        Pipe.liftIO<RT, IN, OUT, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Pipe<RT, IN, OUT, B> Bind<RT, IN, OUT, A, B>(\n        this Pure<A> ma, \n        Func<A, Pipe<RT, IN, OUT, B>> f) =>\n        Pipe.pure<RT, IN, OUT, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Pipe<RT, IN, OUT, B> Bind<RT, IN, OUT, A, B>(\n        this Lift<A> ff, \n        Func<A, Pipe<RT, IN, OUT, B>> f) =>\n        Pipe.lift<RT, IN, OUT, A>(ff.Function).Bind(f);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static Pipe<RT, IN, OUT, C> SelectMany<RT, IN, OUT, A, C>(\n        this K<Pipe<RT, IN, OUT>, A> ma,\n        Func<A, Guard<Error, Unit>> bind,\n        Func<A, Unit, C> project) =>\n        ma.Bind(a => bind(a) switch\n                     {\n                         { Flag: true } => Pipe.pure<RT, IN, OUT, C>(project(a, default)),\n                         var guard      => Pipe.error<RT, IN, OUT, C>(guard.OnFalse())\n                     }).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static Pipe<RT, IN, OUT, C> SelectMany<RT, IN, OUT, B, C>(\n        this Guard<Error, Unit> ma,\n        Func<Unit, K<Pipe<RT, IN, OUT>, B>> bind,\n        Func<Unit, B, C> project) =>\n        ma switch\n        {\n            { Flag: true } => bind(default).Map(b => project(default, b)).As(),\n            var guard      => Pipe.error<RT, IN, OUT, C>(guard.OnFalse())\n        };     \n}\n    \n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Pipe/Pipe.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `Pipe` streaming producer monad-transformer\n/// </summary>\npublic static class Pipe\n{\n    /// <summary>\n    /// Yield a value downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> yield<RT, IN, OUT>(OUT value) =>\n        PipeT.yield<Eff<RT>, IN, OUT>(value);\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> yieldAll<RT, IN, OUT>(IEnumerable<OUT> values) =>\n        PipeT.yieldAll<Eff<RT>, IN, OUT>(values);\n    \n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> yieldAll<RT, IN, OUT>(IAsyncEnumerable<OUT> values) =>\n        PipeT.yieldAll<Eff<RT>, IN, OUT>(values);\n    \n    /// <summary>\n    /// Evaluate the `M` monad repeatedly, yielding its bound values downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> yieldRepeat<RT, IN, OUT>(K<Eff<RT>, OUT> ma) =>\n        PipeT.yieldRepeat<Eff<RT>, IN, OUT>(ma);\n\n    /// <summary>\n    /// Evaluate the `IO` monad repeatedly, yielding its bound values downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> yieldRepeatIO<RT, IN, OUT>(IO<OUT> ma) =>\n        PipeT.yieldRepeatIO<Eff<RT>, IN, OUT>(ma);\n    \n    /// <summary>\n    /// Await a value from upstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns>Pipe</returns>\n    public static Pipe<RT, IN, OUT, IN> awaiting<RT, IN, OUT>() =>\n        PipeT.awaiting<Eff<RT>, IN, OUT>();\n\n    /// <summary>\n    /// Create a pipe that filters out values that return `false` when applied to a predicate function\n    /// </summary>\n    /// <param name=\"f\">Predicate function</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"A\">Stream value to consume and produce</typeparam>\n    /// <returns>Pipe</returns>\n    public static Pipe<RT, A, A, Unit> filter<RT, A>(Func<A, bool> f) =>\n        PipeT.filter<Eff<RT>, A>(f);\n\n    /// <summary>\n    /// Create a pipe from a mapping function\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns>Pipe</returns>\n    public static Pipe<RT, IN, OUT, Unit> map<RT, IN, OUT>(Func<IN, OUT> f) =>\n        PipeT.map<Eff<RT>, IN, OUT>(f);\n\n    /// <summary>\n    /// Create a pipe from a mapping function\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns>Pipe</returns>\n    public static Pipe<RT, IN, OUT, Unit> mapM<RT, IN, OUT>(Func<IN, K<Eff<RT>, OUT>> f) =>\n        PipeT.mapM(f);\n    \n    /// <summary>\n    /// Create a pipe that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> pure<RT, IN, OUT, A>(A value) =>\n        PipeT.pure<IN, OUT, Eff<RT>, A>(value);\n    \n    /// <summary>\n    /// Create a pipe that always fails\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> error<RT, IN, OUT, A>(Error value) =>\n        PipeT.error<IN, OUT, Eff<RT>, A>(value);\n    \n    /// <summary>\n    /// Create a pipe that yields nothing at all\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> empty<RT, IN, OUT, A>() => \n        PipeT.empty<IN, OUT, Eff<RT>, A>();\n    \n    /// <summary>\n    /// Create a pipe that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> lift<RT, IN, OUT, A>(Func<A> f) => \n        PipeT.lift<IN, OUT, Eff<RT>, A>(f);\n    \n    /// <summary>\n    /// Create a lazy pipe \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> liftT<RT, IN, OUT, A>(Func<Pipe<RT, IN, OUT, A>> f) =>\n        PipeT.liftT(() => f().Proxy);\n\n    /// <summary>\n    /// Create an asynchronous lazy pipe \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> liftT<RT, IN, OUT, A>(Func<ValueTask<Pipe<RT, IN, OUT, A>>> f) =>\n        PipeT.liftT(async () => (await f()).Proxy);\n\n    /// <summary>\n    /// Create an asynchronous pipe \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> liftT<RT, IN, OUT, A>(ValueTask<Pipe<RT, IN, OUT, A>> task) =>\n        PipeT.liftT(task.Map(t => t.Proxy));\n\n    /// <summary>\n    /// Create a pipe that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> liftM<RT, IN, OUT, A>(K<Eff<RT>, A> ma) =>\n        PipeT.liftM<IN, OUT, Eff<RT>, A>(ma);\n\n    /// <summary>\n    /// Create a pipe that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> liftM<RT, IN, OUT, A>(ValueTask<K<Eff<RT>, A>> ma) =>\n        PipeT.liftM<IN, OUT, Eff<RT>, A>(ma);\n    \n    /// <summary>\n    /// Create a pipe that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> liftIO<RT, IN, OUT, A>(IO<A> ma) => \n        PipeT.liftIO<IN, OUT, Eff<RT>, A>(ma);\n\n    /// <summary>\n    /// Continually repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> repeat<RT, IN, OUT, A>(Pipe<RT, IN, OUT, A> ma) =>\n        PipeT.repeat(ma.Proxy);\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> repeat<RT, IN, OUT, A>(Schedule schedule, Pipe<RT, IN, OUT, A> ma) =>\n        PipeT.repeat(schedule, ma.Proxy);\n\n    /// <summary>\n    /// Continually lift and repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> repeatM<RT, IN, OUT, A>(K<Eff<RT>, A> ma) =>\n        PipeT.repeatM<IN, OUT, Eff<RT>, A>(ma);\n    \n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, A> repeatM<RT, IN, OUT, A>(Schedule schedule, K<Eff<RT>, A> ma) =>\n        PipeT.repeatM<IN, OUT, Eff<RT>, A>(schedule, ma);\n            \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> fold<RT, IN, OUT, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        OUT Init, \n        Pipe<RT, IN, OUT, A> Item) =>\n        Item.Proxy.Fold(Time, Fold, Init);\n    \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> foldUntil<RT, IN, OUT, A>(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init, \n        Pipe<RT, IN, OUT, A> Item) =>\n        Item.Proxy.FoldUntil(Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> foldUntil<RT, IN, OUT, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold,\n        Func<(OUT State, A Value), bool> Pred,\n        OUT Init,\n        Pipe<RT, IN, OUT, A> Item) =>\n        Item.Proxy.FoldUntil(Time, Fold, Pred, Init);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> foldWhile<RT, IN, OUT, A>(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init, \n        Pipe<RT, IN, OUT, A> Item) =>\n        Item.Proxy.FoldWhile(Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> foldWhile<RT, IN, OUT, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold,\n        Func<(OUT State, A Value), bool> Pred,\n        OUT Init,\n        Pipe<RT, IN, OUT, A> Item) =>\n        Item.Proxy.FoldWhile(Time, Fold, Pred, Init);\n    \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> fold<RT, IN, OUT>(\n        Schedule Time,\n        Func<OUT, IN, OUT> Fold, \n        OUT Init) =>\n        PipeT.awaiting<Eff<RT>, IN, OUT>().Fold(Time, Fold, Init);\n    \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> foldUntil<RT, IN, OUT>(\n        Func<OUT, IN, OUT> Fold, \n        Func<(OUT State, IN Value), bool> Pred, \n        OUT Init)  =>\n        PipeT.awaiting<Eff<RT>, IN, OUT>().FoldUntil(Fold, Pred, Init);\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> foldUntil<RT, IN, OUT>(\n        Schedule Time,\n        Func<OUT, IN, OUT> Fold, \n        Func<(OUT State, IN Value), bool> Pred, \n        OUT Init) =>\n        PipeT.awaiting<Eff<RT>, IN, OUT>().FoldUntil(Time, Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> foldWhile<RT, IN, OUT>(\n        Func<OUT, IN, OUT> Fold,\n        Func<(OUT State, IN Value), bool> Pred,\n        OUT Init) =>\n        PipeT.awaiting<Eff<RT>, IN, OUT>().FoldWhile(Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Pipe<RT, IN, OUT, Unit> foldWhile<RT, IN, OUT>(\n        Schedule Time,\n        Func<OUT, IN, OUT> Fold, \n        Func<(OUT State, IN Value), bool> Pred, \n        OUT Init) =>\n        PipeT.awaiting<Eff<RT>, IN, OUT>().FoldWhile(Time, Fold, Pred, Init);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Pipe/Pipe.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Async.Linq;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic class Pipe<RT, IN, OUT> : \n    MonadT<Pipe<RT, IN, OUT>, Eff<RT>>,\n    MonadUnliftIO<Pipe<RT, IN, OUT>>\n{\n    static K<Pipe<RT, IN, OUT>, B> Monad<Pipe<RT, IN, OUT>>.Bind<A, B>(\n        K<Pipe<RT, IN, OUT>, A> ma, \n        Func<A, K<Pipe<RT, IN, OUT>, B>> f) => \n        ma.As().Bind(x => f(x).As());\n\n    static K<Pipe<RT, IN, OUT>, B> Monad<Pipe<RT, IN, OUT>>.Recur<A, B>(A value, Func<A, K<Pipe<RT, IN, OUT>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<Pipe<RT, IN, OUT>, B> Functor<Pipe<RT, IN, OUT>>.Map<A, B>(\n        Func<A, B> f, \n        K<Pipe<RT, IN, OUT>, A> ma) => \n        ma.As().Map(f);\n\n    static K<Pipe<RT, IN, OUT>, A> Applicative<Pipe<RT, IN, OUT>>.Pure<A>(A value) => \n        Pipe.pure<RT, IN, OUT, A>(value);\n\n    static K<Pipe<RT, IN, OUT>, B> Applicative<Pipe<RT, IN, OUT>>.Apply<A, B>(\n        K<Pipe<RT, IN, OUT>, Func<A, B>> mf,\n        K<Pipe<RT, IN, OUT>, A> ma) =>\n        ma.As().ApplyBack(mf.As());\n\n    static K<Pipe<RT, IN, OUT>, B> Applicative<Pipe<RT, IN, OUT>>.Apply<A, B>(\n        K<Pipe<RT, IN, OUT>, Func<A, B>> mf,\n        Memo<Pipe<RT, IN, OUT>, A> ma) =>\n        new Pipe<RT, IN, OUT, B>(\n            new PipeTMemo<IN, OUT, Eff<RT>, A>(ma.Lower().Map(ma => ma.As().Proxy.Kind()).Lift())\n               .ApplyBack(mf.As().Proxy));\n    \n    static K<Pipe<RT, IN, OUT>, B> Applicative<Pipe<RT, IN, OUT>>.Action<A, B>(\n        K<Pipe<RT, IN, OUT>, A> ma, \n        K<Pipe<RT, IN, OUT>, B> mb) =>\n        Pipe.liftM<RT, IN, OUT, B>(ma.As().Run().Action(mb.As().Run()));\n\n    static K<Pipe<RT, IN, OUT>, A> Applicative<Pipe<RT, IN, OUT>>.Actions<A>(IterableNE<K<Pipe<RT, IN, OUT>, A>> fas) =>\n        Pipe.liftM<RT, IN, OUT, A>(fas.Select(fa => fa.As().Run().Kind()).Actions());\n\n    static K<Pipe<RT, IN, OUT>, A> MonadT<Pipe<RT, IN, OUT>, Eff<RT>>.Lift<A>(K<Eff<RT>, A> ma) => \n        Pipe.liftM<RT, IN, OUT, A>(ma);\n\n    static K<Pipe<RT, IN, OUT>, A> MonadIO<Pipe<RT, IN, OUT>>.LiftIO<A>(IO<A> ma) => \n        Pipe.liftIO<RT, IN, OUT, A>(ma);\n\n    static K<Pipe<RT, IN, OUT>, B> MonadUnliftIO<Pipe<RT, IN, OUT>>.MapIO<A, B>(K<Pipe<RT, IN, OUT>, A> ma, Func<IO<A>, IO<B>> f) => \n        ma.As().MapIO(f);\n\n    static K<Pipe<RT, IN, OUT>, IO<A>> MonadUnliftIO<Pipe<RT, IN, OUT>>.ToIO<A>(K<Pipe<RT, IN, OUT>, A> ma) => \n        ma.MapIO(IO.pure);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Pipe/Pipe.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class PipeExtensions\n{\n    extension<RT, IN, OUT, A>(K<Pipe<RT, IN, OUT>, A>)\n    {\n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static Pipe<RT, IN, OUT, A> operator +(K<Pipe<RT, IN, OUT>, A> ma) =>\n           (Pipe<RT, IN, OUT, A>) ma;\n        \n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static Pipe<RT, IN, OUT, A> operator >>(K<Pipe<RT, IN, OUT>, A> ma, Lower lower) =>\n           +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Pipe/Pipe.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `Pipe` monad-transformer base-type for `Eff`-based streaming components:\n///\n///   * `Producer` is a `Pipe` with the `IN` 'closed off' with `Unit`\n///   * `Consumer` is a `Pipe` with the `OUT` 'closed off' with `Void`\n///   * `Effect` is a `Pipe` with the `IN` and `OUT` 'closed off' with `Unit` upstream and `Void` downstream\n/// \n/// </summary>\n/// <remarks>\n/// Unlike the general purpose `PipeT`, which will lift any monad, this type only lifts the `Eff` monad.\n/// </remarks>\n/// <typeparam name=\"IN\">Type of values to be consumed</typeparam>\n/// <typeparam name=\"OUT\">Type of values to be produced</typeparam>\n/// <typeparam name=\"M\">Lifted monad type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic record Pipe<RT, IN, OUT, A>(PipeT<IN, OUT, Eff<RT>, A> Proxy) : K<Pipe<RT, IN, OUT>, A>\n{\n    [Pure]\n    public Pipe<RT, IN, OUT1, A> Compose<OUT1>(Pipe<RT, OUT, OUT1, A> rhs) =>\n        Proxy.Compose(rhs.Proxy);\n    [Pure]\n    public Pipe<RT, IN, OUT1, A> Compose<OUT1>(PipeT<OUT, OUT1, Eff<RT>, A> rhs) =>\n        Proxy.Compose(rhs);\n\n    [Pure]\n    public Consumer<RT, IN, A> Compose(Consumer<RT, OUT, A> rhs) =>\n        Proxy.Compose(rhs.Proxy);\n\n    [Pure]\n    public Consumer<RT, IN, A> Compose(ConsumerT<OUT, Eff<RT>, A> rhs) =>\n        Proxy.Compose(rhs.Proxy);\n    \n    [Pure]\n    public static Pipe<RT, IN, OUT, A> operator | (Pipe<RT, IN, OUT, A> lhs, Pipe<RT, OUT, OUT, A> rhs) =>\n        lhs.Compose(rhs);\n\n    [Pure]\n    public static Pipe<RT, IN, OUT, A> operator | (Pipe<RT, IN, OUT, A> lhs, PipeT<OUT, OUT, Eff<RT>, A> rhs) =>\n        lhs.Compose(rhs);\n\n    [Pure]\n    public static Producer<RT, OUT, A> operator | (Producer<RT, IN, A> lhs, Pipe<RT, IN, OUT, A> rhs) =>\n        lhs.Compose(rhs);\n\n    [Pure]\n    public static Producer<RT, OUT, A> operator | (ProducerT<IN, Eff<RT>, A> lhs, Pipe<RT, IN, OUT, A> rhs) =>\n        lhs.Compose(rhs.Proxy).Proxy;\n\n    [Pure]\n    public static Consumer<RT, IN, A> operator | (Pipe<RT, IN, OUT, A> lhs, Consumer<RT, OUT, A> rhs) =>\n        lhs.Compose(rhs);\n\n    [Pure]\n    public static Consumer<RT, IN, A> operator | (Pipe<RT, IN, OUT, A> lhs, ConsumerT<OUT, Eff<RT>, A> rhs) =>\n        lhs.Compose(rhs);\n    \n    [Pure]\n    public static implicit operator Pipe<RT, IN, OUT, A>(Pure<A> rhs) =>\n        Pipe.pure<RT, IN, OUT, A>(rhs.Value);\n\n    [Pure]\n    public static implicit operator Pipe<RT, IN, OUT, A>(PipeT<IN, OUT, Eff<RT>, A> rhs) =>\n        new(rhs);\n\n    [Pure]\n    public Pipe<RT, IN, OUT, B> Map<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n\n    [Pure]\n    public Pipe<RT, IN, OUT, B> MapM<B>(Func<Eff<RT, A>, Eff<RT, B>> f) =>\n        Proxy.MapM(mx => f(mx.As()));\n    \n    [Pure]\n    public Pipe<RT, IN, OUT, B> ApplyBack<B>(Pipe<RT, IN, OUT, Func<A, B>> ff) =>\n        Proxy.ApplyBack(ff.Proxy);\n    \n    [Pure]\n    public Pipe<RT, IN, OUT, B> Action<B>(Pipe<RT, IN, OUT, B> fb) =>\n        Proxy.Action(fb.Proxy);\n    \n    [Pure]\n    public Pipe<RT, IN, OUT, B> Bind<B>(Func<A, Pipe<RT, IN, OUT, B>> f) =>\n        Proxy.Bind(x => f(x).Proxy);\n    \n    [Pure]\n    public Pipe<RT, IN, OUT, B> Bind<B>(Func<A, IO<B>> f) =>\n        Proxy.Bind(f);\n    \n    [Pure]\n    public Pipe<RT, IN, OUT, B> Bind<B>(Func<A, K<Eff<RT>, B>> f) =>\n        Proxy.Bind(f);\n    \n    [Pure]\n    public Pipe<RT, IN, OUT, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    public Pipe<RT, IN, OUT, B> Bind<B>(Func<A, Lift<B>> f) =>\n        Proxy.Bind(f);\n    \n    [Pure]\n    public Pipe<RT, IN, OUT, B> BindAsync<B>(Func<A, ValueTask<Pipe<RT, IN, OUT, B>>> f) =>\n        Proxy.BindAsync(async x => (await f(x)).Proxy);\n    \n    [Pure]\n    public Pipe<RT, IN, OUT, B> MapIO<B>(Func<IO<A>, IO<B>> f) =>\n        Proxy.MapIO(f);\n\n    [Pure]\n    public Pipe<RT, IN, OUT, B> Select<B>(Func<A, B> f) =>\n        Map(f);\n   \n    [Pure]\n    public Pipe<RT, IN, OUT, C> SelectMany<B, C>(Func<A, Pipe<RT, IN, OUT, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(x => f(x).Proxy, g);\n   \n    [Pure]\n    public Pipe<RT, IN, OUT, C> SelectMany<B, C>(Func<A, K<Eff<RT>, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Pipe<RT, IN, OUT, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Pipe<RT, IN, OUT, C> SelectMany<B, C>(Func<A, Pure<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Pipe<RT, IN, OUT, C> SelectMany<B, C>(Func<A, Lift<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n                \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Pipe<RT, IN, OUT, Unit> Fold(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        OUT Init) =>\n        Proxy.Fold(Time, Fold, Init);\n\n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Pipe<RT, IN, OUT, Unit> FoldUntil(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        Proxy.FoldUntil(Fold, Pred, Init);\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Pipe<RT, IN, OUT, Unit> FoldUntil(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        Proxy.FoldUntil(Time, Fold, Pred, Init);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Pipe<RT, IN, OUT, Unit> FoldWhile(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        Proxy.FoldWhile(Fold, Pred, Init);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Pipe<RT, IN, OUT, Unit> FoldWhile(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        Proxy.FoldWhile(Time, Fold, Pred, Init);\n    \n    [Pure]\n    internal virtual Eff<RT, A> Run() =>\n        Proxy.Run().As();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/PipeT/PipeT.Cached.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\nclass PipeTCached<IN, OUT, M>\n    where M : MonadIO<M>\n{\n    public static readonly PipeT<IN, OUT, M, Unit> unitP = \n        PipeT.pure<IN, OUT, M, Unit>(default);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/PipeT/PipeT.DSL.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pipes;\n\nrecord PipeTEmpty<IN, OUT, M, A> : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>, MonoidK<M>\n{\n    public static readonly PipeT<IN, OUT, M, A> Default = new PipeTEmpty<IN, OUT, M, A>();\n    \n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) =>\n        PipeTEmpty<IN, OUT, M, B>.Default;\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        PipeTEmpty<IN, OUT, M, B>.Default;\n    \n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) =>\n        PipeTEmpty<IN, OUT, M, B>.Default;\n    \n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) =>\n        PipeTEmpty<IN, OUT, M, B>.Default;\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) =>\n        PipeTEmpty<IN, OUT, M, B>.Default;\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) => \n        PipeT.empty<IN1, OUT, M, A>();\n\n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) => \n        PipeT.empty<IN, OUT1, M, A>();\n    \n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) => \n        PipeT.empty<IN1, OUT, M, A>();\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        PipeT.empty<IN, OUT1, M, A>();\n    \n    internal override K<M, A> Run() =>\n        M.Empty<A>();\n}\n\nrecord PipeTPure<IN, OUT, M, A>(A Value) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) =>\n        PipeT.pure<IN, OUT, M, B>(f(Value));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        PipeT.liftM<IN, OUT, M, B>(f(M.Pure(Value)));\n    \n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) =>\n        ff.Map(f => f(Value));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) =>\n        fb; \n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) =>\n        f(Value);\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) => \n        PipeT.pure<IN1, OUT, M, A>(Value);\n\n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) => \n        PipeT.pure<IN, OUT1, M, A>(Value);\n\n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) =>\n        producer(default).PairEachYieldWithAwait(_ => PipeT.pure<IN, OUT, M, A>(Value));\n    \n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        PipeT.pure<IN, OUT1, M, A>(Value);\n\n    internal override K<M, A> Run() =>\n        M.Pure(Value);\n}\n\nrecord PipeTFail<IN, OUT, E, M, A>(E Value) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>, Fallible<E, M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) =>\n        PipeT.fail<IN, OUT, E, M, B>(Value);\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        PipeT.fail<IN, OUT, E, M, B>(Value);\n    \n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) =>\n        PipeT.fail<IN, OUT, E, M, B>(Value);\n    \n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) =>\n        PipeT.fail<IN, OUT, E, M, B>(Value);\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) =>\n        PipeT.fail<IN, OUT, E, M, B>(Value);\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) => \n        PipeT.fail<IN1, OUT, E, M, A>(Value);\n\n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) => \n        PipeT.fail<IN, OUT1, E, M, A>(Value);\n    \n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) => \n        PipeT.fail<IN1, OUT, E, M, A>(Value);\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        PipeT.fail<IN, OUT1, E, M, A>(Value);\n\n    internal override K<M, A> Run() =>\n        M.Fail<A>(Value);\n}\n\nrecord PipeTMemo<IN, OUT, M, A>(Memo<PipeT<IN, OUT, M>, A> Acquire) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire.Map(f).As());\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire.Value.As().MapM(f));\n    \n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire.Value.As().ApplyBack(ff));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire.Value.As().Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire.Value.As().Bind(f));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) => \n        new PipeTLazy<IN1, OUT, M, A>(() => Acquire.Value.As().ReplaceAwait(producer));\n\n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) => \n        new PipeTLazy<IN, OUT1, M, A>(() => Acquire.Value.As().ReplaceYield(consumer));\n    \n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) => \n        new PipeTLazy<IN1, OUT, M, A>(() => Acquire.Value.As().PairEachAwaitWithYield(producer));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        new PipeTLazy<IN, OUT1, M, A>(() => Acquire.Value.As().PairEachYieldWithAwait(consumer));\n\n    internal override K<M, A> Run() =>\n        Acquire.Value.As().Run();\n}\n\nrecord PipeTLazy<IN, OUT, M, A>(Func<PipeT<IN, OUT, M, A>> Acquire) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire().Map(f));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire().MapM(f));\n    \n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire().ApplyBack(ff));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire().Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) =>\n        new PipeTLazy<IN, OUT, M, B>(() => Acquire().Bind(f));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) => \n        new PipeTLazy<IN1, OUT, M, A>(() => Acquire().ReplaceAwait(producer));\n\n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) => \n        new PipeTLazy<IN, OUT1, M, A>(() => Acquire().ReplaceYield(consumer));\n    \n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) => \n        new PipeTLazy<IN1, OUT, M, A>(() => Acquire().PairEachAwaitWithYield(producer));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        new PipeTLazy<IN, OUT1, M, A>(() => Acquire().PairEachYieldWithAwait(consumer));\n\n    internal override K<M, A> Run() =>\n        Acquire().Run();\n}\n\nrecord PipeTLazyAsync<IN, OUT, M, A>(Func<ValueTask<PipeT<IN, OUT, M, A>>> Acquire) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) =>\n        new PipeTLazyAsync<IN, OUT, M, B>(() => Acquire().Map(t => t.Map(f)));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new PipeTLazyAsync<IN, OUT, M, B>(() => Acquire().Map(t => t.MapM(f)));\n    \n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) =>\n        new PipeTLazyAsync<IN, OUT, M, B>(() => Acquire().Map(t => t.ApplyBack(ff)));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) =>\n        new PipeTLazyAsync<IN, OUT, M, B>(() => Acquire().Map(t => t.Action(fb)));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) =>\n        new PipeTLazyAsync<IN, OUT, M, B>(() => Acquire().Map(t => t.Bind(f)));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) => \n        new PipeTLazyAsync<IN1, OUT, M, A>(() => Acquire().Map(t => t.ReplaceAwait(producer)));\n\n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) => \n        new PipeTLazyAsync<IN, OUT1, M, A>(() => Acquire().Map(t => t.ReplaceYield(consumer)));\n    \n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) => \n        new PipeTLazyAsync<IN1, OUT, M, A>(() => Acquire().Map(t => t.PairEachAwaitWithYield(producer)));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        new PipeTLazyAsync<IN, OUT1, M, A>(() => Acquire().Map(t => t.PairEachYieldWithAwait(consumer)));\n\n    internal override K<M, A> Run() =>\n        IO.liftVAsync(Acquire) >> (p => p.Run());\n}\n\nrecord PipeTLiftM<IN, OUT, M, A>(K<M, PipeT<IN, OUT, M, A>> Value) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) =>\n        new PipeTLiftM<IN, OUT, M, B>(Value.Map(px => px.Map(f)));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        new PipeTLiftM<IN, OUT, M, B>(Value.Map(px => px.MapM(f)));\n    \n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) =>\n        new PipeTLiftM<IN, OUT, M, B>(Value.Map(px => px.ApplyBack(ff)));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) =>\n        new PipeTLiftM<IN, OUT, M, B>(Value.Map(px => px.Action(fb)));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) =>\n        new PipeTLiftM<IN, OUT, M, B>(Value.Map(px => px.Bind(f)));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) => \n        new PipeTLiftM<IN1, OUT, M, A>(Value.Map(px => px.ReplaceAwait(producer)));\n\n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) => \n        new PipeTLiftM<IN, OUT1, M, A>(Value.Map(px => px.ReplaceYield(consumer)));\n    \n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) => \n        new PipeTLiftM<IN1, OUT, M, A>(Value.Map(px => px.PairEachAwaitWithYield(producer)));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        new PipeTLiftM<IN, OUT1, M, A>(Value.Map(px => px.PairEachYieldWithAwait(consumer)));\n\n    internal override K<M, A> Run() =>\n        Value.Bind(p => p.Run());\n}\n\nrecord PipeTYield<IN, OUT, M, A>(OUT Value, Func<Unit, PipeT<IN, OUT, M, A>> Next) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) => \n        new PipeTYield<IN, OUT, M, B>(Value, _ => Next(default).Map(f));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) => \n        new PipeTYield<IN, OUT, M, B>(Value, _ => Next(default).MapM(f));\n\n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) => \n        new PipeTYield<IN, OUT, M, B>(Value, _ => Next(default).ApplyBack(ff));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) => \n        new PipeTYield<IN, OUT, M, B>(Value, _ => Next(default).Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) => \n        new PipeTYield<IN, OUT, M, B>(Value, _ => Next(default).Bind(f));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) =>\n        new PipeTYield<IN1, OUT, M, A>(Value, _ => Next(default).ReplaceAwait(producer));\n    \n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) =>\n        consumer(Value).Bind(_ => Next(default).ReplaceYield(consumer));\n\n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) =>\n        new PipeTYield<IN1, OUT, M, A>(Value, _ => Next(default).PairEachAwaitWithYield(producer));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        consumer(Value).PairEachAwaitWithYield(_ => Next(default));\n\n    internal override K<M, A> Run() => \n        throw new InvalidOperationException(\"closed\");\n}\n\nrecord PipeTAwait<IN, OUT, M, A>(Func<IN, PipeT<IN, OUT, M, A>> Await) : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).Map(f));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).MapM(f));\n\n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).ApplyBack(ff));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) => \n        new PipeTAwait<IN, OUT, M, B>(x => Await(x).Bind(f));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) =>\n        producer().Bind(x => Await(x).ReplaceAwait(producer));\n        \n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) =>\n        new PipeTAwait<IN, OUT1, M, A>(x => Await(x).ReplaceYield(consumer));\n\n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) => \n        producer(default).PairEachYieldWithAwait(Await);\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        new PipeTAwait<IN, OUT1, M, A>(x => Await(x).PairEachYieldWithAwait(consumer));\n\n    internal override K<M, A> Run() => \n        throw new InvalidOperationException(\"closed\");\n}\n\nrecord PipeTYieldAll<IN, OUT, M, A>(IterableNE<PipeT<IN, OUT, M, Unit>> Yields, Func<Unit, PipeT<IN, OUT, M, A>> Next) \n    : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) => \n        new PipeTYieldAll<IN, OUT, M, B>(Yields, x => Next(x).Map(f));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) => \n        new PipeTYieldAll<IN, OUT, M, B>(Yields, x => Next(x).MapM(f));\n\n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) => \n        new PipeTYieldAll<IN, OUT, M, B>(Yields, x => Next(x).ApplyBack(ff));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) => \n        new PipeTYieldAll<IN, OUT, M, B>(Yields, x => Next(x).Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) => \n        new PipeTYieldAll<IN, OUT, M, B>(Yields, x => Next(x).Bind(f));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) =>\n        new PipeTYieldAll<IN1, OUT, M, A>(Yields.Select(x => x.ReplaceAwait(producer)), x => Next(x).ReplaceAwait(producer));\n    \n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) =>\n        new PipeTYieldAll<IN, OUT1, M, A>(Yields.Select(x => x.ReplaceYield(consumer)), x => Next(x).ReplaceYield(consumer));\n\n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) =>\n        new PipeTYieldAll<IN1, OUT, M, A>(\n            Yields.Select(x => x.PairEachAwaitWithYield(_ => producer(default).Map(_ => Unit.Default))),\n            x => Next(x).PairEachAwaitWithYield(producer));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        new PipeTYieldAll<IN, OUT1, M, A>(\n            Yields.Select(x => x.PairEachYieldWithAwait(o => consumer(o).Map(_ => Unit.Default))), \n            x => Next(x).PairEachYieldWithAwait(consumer));\n\n    internal override K<M, A> Run() =>\n        Yields.Map(y => y.Kind())\n              .Actions()\n              .Bind(_ => Next(default))\n              .As()\n              .Run();\n}\n\nrecord PipeTYieldAllSource<IN, OUT, M, X, A>(Source<X> Yields, Func<X, PipeT<IN, OUT, M, Unit>> F, Func<Unit, PipeT<IN, OUT, M, A>> Next) \n    : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) => \n        new PipeTYieldAllSource<IN, OUT, M, X, B>(Yields, F, x => Next(x).Map(f));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) => \n        new PipeTYieldAllSource<IN, OUT, M, X, B>(Yields, F, x => Next(x).MapM(f));\n\n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) => \n        new PipeTYieldAllSource<IN, OUT, M, X, B>(Yields, F, x => Next(x).ApplyBack(ff));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) => \n        new PipeTYieldAllSource<IN, OUT, M, X, B>(Yields, F, x => Next(x).Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) => \n        new PipeTYieldAllSource<IN, OUT, M, X, B>(Yields, F, x => Next(x).Bind(f));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) =>\n        new PipeTYieldAllSource<IN1, OUT, M, X, A>(Yields, x => F(x).ReplaceAwait(producer), x => Next(x).ReplaceAwait(producer));\n    \n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) =>\n        new PipeTYieldAllSource<IN, OUT1, M, X, A>(Yields, x => F(x).ReplaceYield(consumer), x => Next(x).ReplaceYield(consumer));\n\n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) =>\n        new PipeTYieldAllSource<IN1, OUT, M, X, A>(\n            Yields,\n            x => F(x).PairEachAwaitWithYield(_ => producer(default).Map(_ => Unit.Default)),\n            x => Next(x).PairEachAwaitWithYield(producer));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        new PipeTYieldAllSource<IN, OUT1, M, X, A>(\n            Yields,\n            x => F(x).PairEachYieldWithAwait(o => consumer(o).Map(_ => Unit.Default)), \n            x => Next(x).PairEachYieldWithAwait(consumer));\n\n    internal override K<M, A> Run()\n    {\n        var comp = Yields.ReduceIO(\n                              PipeT.pure<IN, OUT, M, Unit>(unit),\n                              (ms, x) => Reduced.ContinueIO(ms.Bind(_ => F(x))));\n\n        var next = comp >> Next(unit) >> lower;\n        return next.Run();\n    }\n}\n\nrecord PipeTYieldAllSourceT<IN, OUT, M, X, A>(SourceT<M, X> Yields, Func<X, PipeT<IN, OUT, M, Unit>> F, Func<Unit, PipeT<IN, OUT, M, A>> Next) \n    : PipeT<IN, OUT, M, A>\n    where M : MonadIO<M>\n{\n    public override PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f) => \n        new PipeTYieldAllSourceT<IN, OUT, M, X, B>(Yields, F, x => Next(x).Map(f));\n\n    public override PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) => \n        new PipeTYieldAllSourceT<IN, OUT, M, X, B>(Yields, F, x => Next(x).MapM(f));\n\n    public override PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff) => \n        new PipeTYieldAllSourceT<IN, OUT, M, X, B>(Yields, F, x => Next(x).ApplyBack(ff));\n\n    public override PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb) => \n        new PipeTYieldAllSourceT<IN, OUT, M, X, B>(Yields, F, x => Next(x).Action(fb));\n\n    public override PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f) => \n        new PipeTYieldAllSourceT<IN, OUT, M, X, B>(Yields, F, x => Next(x).Bind(f));\n\n    internal override PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer) =>\n        new PipeTYieldAllSourceT<IN1, OUT, M, X, A>(Yields, x => F(x).ReplaceAwait(producer), x => Next(x).ReplaceAwait(producer));\n    \n    internal override PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer) =>\n        new PipeTYieldAllSourceT<IN, OUT1, M, X, A>(Yields, x => F(x).ReplaceYield(consumer), x => Next(x).ReplaceYield(consumer));\n\n    internal override PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer) =>\n        new PipeTYieldAllSourceT<IN1, OUT, M, X, A>(\n            Yields,\n            x => F(x).PairEachAwaitWithYield(_ => producer(default).Map(_ => Unit.Default)),\n            x => Next(x).PairEachAwaitWithYield(producer));\n\n    internal override PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer) =>\n        new PipeTYieldAllSourceT<IN, OUT1, M, X, A>(\n            Yields,\n            x => F(x).PairEachYieldWithAwait(o => consumer(o).Map(_ => Unit.Default)), \n            x => Next(x).PairEachYieldWithAwait(consumer));\n\n    internal override K<M, A> Run()\n    {\n        var comp = Yields.ReduceM(PipeT.pure<IN, OUT, M, Unit>(unit),\n                                  (ms, x) => M.Pure(Reduced.Continue(ms.Bind(_ => F(x)))))\n                         .Bind(pipe => pipe.Bind(x => Next(x)));\n\n        return comp.Run();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/PipeT/PipeT.Extensions.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class PipeTExtensions\n{\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, A> As<IN, OUT, M, A>(this K<PipeT<IN, OUT, M>, A> ma)\n        where M : MonadIO<M> =>\n        (PipeT<IN, OUT, M, A>)ma;\n    \n    /// <summary>\n    /// Convert to the `Eff` version of `Pipe`\n    /// </summary>\n    [Pure]\n    public static Pipe<RT, IN, OUT, A> ToEff<RT, IN, OUT, A>(this K<PipeT<IN, OUT, Eff<RT>>, A> ma) =>\n        ma.As();\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, C> SelectMany<IN, OUT, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, PipeT<IN, OUT, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        PipeT.liftM<IN, OUT, M, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, C> SelectMany<IN, OUT, M, A, B, C>(\n        this IO<A> ma, \n        Func<A, PipeT<IN, OUT, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        PipeT.liftIO<IN, OUT, M, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, C> SelectMany<IN, OUT, M, A, B, C>(\n        this Pure<A> ma, \n        Func<A, PipeT<IN, OUT, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        PipeT.pure<IN, OUT, M, A>(ma.Value).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, C> SelectMany<IN, OUT, M, A, B, C>(\n        this Lift<A> ff, \n        Func<A, PipeT<IN, OUT, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        PipeT.lift<IN, OUT, M, A>(ff.Function).SelectMany(f, g);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, B> Bind<IN, OUT, M, A, B>(\n        this K<M, A> ma, \n        Func<A, PipeT<IN, OUT, M, B>> f)\n        where M : MonadIO<M> =>\n        PipeT.liftM<IN, OUT, M, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, B> Bind<IN, OUT, M, A, B>(\n        this IO<A> ma, \n        Func<A, PipeT<IN, OUT, M, B>> f)\n        where M : MonadIO<M> =>\n        PipeT.liftIO<IN, OUT, M, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, B> Bind<IN, OUT, M, A, B>(\n        this Pure<A> ma, \n        Func<A, PipeT<IN, OUT, M, B>> f)\n        where M : MonadIO<M> =>\n        PipeT.pure<IN, OUT, M, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, B> Bind<IN, OUT, M, A, B>(\n        this Lift<A> ff, \n        Func<A, PipeT<IN, OUT, M, B>> f)\n        where M : MonadIO<M> =>\n        PipeT.lift<IN, OUT, M, A>(ff.Function).Bind(f);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, C> SelectMany<IN, OUT, E, M, A, C>(\n        this K<PipeT<IN, OUT, M>, A> ma,\n        Func<A, Guard<E, Unit>> bind,\n        Func<A, Unit, C> project)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        ma.Bind(a => bind(a) switch\n                     {\n                         { Flag: true } => PipeT.pure<IN, OUT, M, C>(project(a, default)),\n                         var guard      => PipeT.fail<IN, OUT, E, M, C>(guard.OnFalse())\n                     }).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    public static PipeT<IN, OUT, M, C> SelectMany<IN, OUT, E, M, B, C>(\n        this Guard<E, Unit> ma,\n        Func<Unit, K<PipeT<IN, OUT, M>, B>> bind,\n        Func<Unit, B, C> project)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        ma switch\n        {\n            { Flag: true } => bind(default).Map(b => project(default, b)).As(),\n            var guard      => PipeT.fail<IN, OUT, E, M, C>(guard.OnFalse())\n        };    \n        \n    [Pure]\n    public static PipeT<IN, OUT, M, B> MapIO<IN, OUT, M, A, B>(\n        this K<PipeT<IN, OUT, M>, A> ma,\n        Func<IO<A>, IO<B>> f) \n        where M : MonadUnliftIO<M> =>\n        ma.As().MapM(ma => M.MapIOMaybe(ma, f));\n}\n    \n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/PipeT/PipeT.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `PipeT` streaming producer monad-transformer\n/// </summary>\npublic static class PipeT\n{\n    /// <summary>\n    /// Yield a value downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yield<M, IN, OUT>(OUT value) \n        where M : MonadIO<M> =>\n        new PipeTYield<IN, OUT, M, Unit>(value, _ => pure<IN, OUT, M, Unit>(default));\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yieldAll<M, IN, OUT>(IterableNE<OUT> values)\n        where M : MonadIO<M> =>\n        new PipeTYieldAll<IN, OUT, M, Unit>(values.Select(yield<M, IN, OUT>), pure<IN, OUT, M, Unit>);\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yieldAll<M, IN, OUT>(Iterable<OUT> values)\n        where M : MonadIO<M> =>\n        liftIO<IN, OUT, M, Option<IterableNE<OUT>>>(IterableNE.createRange(values).Map(Some)) >> \n            (opt => opt switch\n                {\n                    { IsSome: true, Case: IterableNE<OUT> xs } => yieldAll<M, IN, OUT>(xs),\n                    _                                          => pure<IN, OUT, M, Unit>(unit)\n                }) >> lower;\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yieldAll<M, IN, OUT>(IEnumerable<OUT> values)\n        where M : MonadIO<M> =>\n        IterableNE.createRange(values) switch\n        {\n            { IsSome: true, Case: IterableNE<OUT> xs } => yieldAll<M, IN, OUT>(xs),\n            _                                          => pure<IN, OUT, M, Unit>(unit)\n        };\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yieldAll<M, IN, OUT>(IAsyncEnumerable<OUT> values)\n        where M : MonadIO<M> =>\n        from opt in liftIO<IN, OUT, M, Option<IterableNE<OUT>>>(IterableNE.createRange(values).Map(Some))\n        from res in opt switch\n                    {\n                        { IsSome: true, Case: IterableNE<OUT> xs } => yieldAll<M, IN, OUT>(xs),\n                        _                                          => pure<IN, OUT, M, Unit>(unit)\n                    }\n        select res;\n    \n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yieldAll<M, IN, OUT>(Source<OUT> values) \n        where M : MonadIO<M> =>\n        new PipeTYieldAllSource<IN, OUT, M, OUT, Unit>(values, yield<M, IN, OUT>, pure<IN, OUT, M, Unit>);\n    \n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yieldAll<M, IN, OUT>(SourceT<M, OUT> values) \n        where M : MonadIO<M> =>\n        new PipeTYieldAllSourceT<IN, OUT, M, OUT, Unit>(values, yield<M, IN, OUT>, pure<IN, OUT, M, Unit>);\n\n    /// <summary>\n    /// Evaluate the `M` monad repeatedly, yielding its bound values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yieldRepeat<M, IN, OUT>(K<M, OUT> ma)\n        where M : MonadIO<M> =>\n        new PipeTYieldAll<IN, OUT, M, Unit>(Units.Select(_ => ma.Bind(yield<M, IN, OUT>)), pure<IN, OUT, M, Unit>);\n\n    /// <summary>\n    /// Evaluate the `IO` monad repeatedly, yielding its bound values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> yieldRepeatIO<M, IN, OUT>(IO<OUT> ma)\n        where M : MonadIO<M> =>\n        new PipeTYieldAll<IN, OUT, M, Unit>(Units.Select(_ => ma.Bind(yield<M, IN, OUT>).As()), pure<IN, OUT, M, Unit>);\n    \n    /// <summary>\n    /// Await a value from upstream\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns>Pipe</returns>\n    public static PipeT<IN, OUT, M, IN> awaiting<M, IN, OUT>() \n        where M : MonadIO<M> =>\n        new PipeTAwait<IN, OUT, M, IN>(pure<IN, OUT, M, IN>);\n\n    /// <summary>\n    /// Create a pipe that filters out values that return `false` when applied to a predicate function\n    /// </summary>\n    /// <param name=\"f\">Predicate function</param>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Stream value to consume and produce</typeparam>\n    /// <returns>Pipe</returns>\n    public static PipeT<A, A, M, Unit> filter<M, A>(Func<A, bool> f)\n        where M : MonadIO<M> =>\n        awaiting<M, A, A>().Bind(x => f(x) ? yield<M, A, A>(x) : pure<A, A, M, Unit>(default));\n\n    /// <summary>\n    /// Create a pipe from a mapping function\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns>Pipe</returns>\n    public static PipeT<IN, OUT, M, Unit> map<M, IN, OUT>(Func<IN, OUT> f)\n        where M : MonadIO<M> =>\n        awaiting<M, IN, OUT>().Bind(x => yield<M, IN, OUT>(f(x)));\n\n    /// <summary>\n    /// Create a pipe from a mapping function\n    /// </summary>\n    /// <param name=\"f\">Mapping function</param>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns>Pipe</returns>\n    public static PipeT<IN, OUT, M, Unit> mapM<M, IN, OUT>(Func<IN, K<M, OUT>> f)\n        where M : MonadIO<M> =>\n        awaiting<M, IN, OUT>().Bind(x => liftM<IN, OUT, M, OUT>(f(x)).Bind(yield<M, IN, OUT>));\n    \n    /// <summary>\n    /// Create a pipe that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> pure<IN, OUT, M, A>(A value) \n        where M : MonadIO<M> =>\n        new PipeTPure<IN, OUT, M, A>(value);\n    \n    /// <summary>\n    /// Create a pipe that always fails\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"E\">Failure type</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> fail<IN, OUT, E, M, A>(E value) \n        where M : MonadIO<M>, Fallible<E, M> =>\n        new PipeTFail<IN, OUT, E, M, A>(value);\n    \n    /// <summary>\n    /// Create a pipe that always fails\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> error<IN, OUT, M, A>(Error value) \n        where M : MonadIO<M>, Fallible<M> =>\n        new PipeTFail<IN, OUT, Error, M, A>(value);\n    \n    /// <summary>\n    /// Create a pipe that yields nothing at all\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> empty<IN, OUT, M, A>() \n        where M : MonadIO<M>, MonoidK<M> =>\n        PipeTEmpty<IN, OUT, M, A>.Default;\n    \n    /// <summary>\n    /// Create a pipe that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> lift<IN, OUT, M, A>(Func<A> f) \n        where M : MonadIO<M> =>\n        new PipeTLazy<IN, OUT, M, A>(() => pure<IN, OUT, M, A>(f()));\n    \n    /// <summary>\n    /// Create a pipe that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> lift<IN, OUT, M, A>(Memo<A> f) \n        where M : MonadIO<M> =>\n        new PipeTLazy<IN, OUT, M, A>(() => pure<IN, OUT, M, A>(f.Value));\n    \n    /// <summary>\n    /// Create a lazy pipe \n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> liftT<IN, OUT, M, A>(Func<PipeT<IN, OUT, M, A>> f) \n        where M : MonadIO<M> =>\n        new PipeTLazy<IN, OUT, M, A>(f);\n    \n    /// <summary>\n    /// Create a memoised pipe \n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> liftT<IN, OUT, M, A>(Memo<PipeT<IN, OUT, M>, A> f) \n        where M : MonadIO<M> =>\n        new PipeTMemo<IN, OUT, M, A>(f);\n    \n    /// <summary>\n    /// Create an asynchronous lazy pipe \n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> liftT<IN, OUT, M, A>(Func<ValueTask<PipeT<IN, OUT, M, A>>> f) \n        where M : MonadIO<M> =>\n        new PipeTLazyAsync<IN, OUT, M, A>(f);\n\n    /// <summary>\n    /// Create an asynchronous pipe \n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> liftT<IN, OUT, M, A>(ValueTask<PipeT<IN, OUT, M, A>> task)\n        where M : MonadIO<M> =>\n        new PipeTLazyAsync<IN, OUT, M, A>(() => task);\n    \n    /// <summary>\n    /// Create a pipe that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> liftM<IN, OUT, M, A>(K<M, A> ma) \n        where M : MonadIO<M> =>\n        new PipeTLiftM<IN, OUT, M, A>(ma.Map(pure<IN, OUT, M, A>));\n    \n    /// <summary>\n    /// Create a pipe that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> liftM<IN, OUT, M, A>(ValueTask<K<M, A>> ma) \n        where M : MonadIO<M> =>\n        new PipeTLazyAsync<IN, OUT, M, A>(() => ma.Map(liftM<IN, OUT, M, A>));\n    \n    /// <summary>\n    /// Create a pipe that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> liftIO<IN, OUT, M, A>(IO<A> ma) \n        where M : MonadIO<M> =>\n        liftM<IN, OUT, M, A>(M.LiftIOMaybe(ma));\n\n    /// <summary>\n    /// Continually repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> repeat<IN, OUT, M, A>(PipeT<IN, OUT, M, A> ma)\n        where M : MonadIO<M> =>\n        ma.Bind(_ => repeat(ma));\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> repeat<IN, OUT, M, A>(Schedule schedule, PipeT<IN, OUT, M, A> ma)\n        where M : MonadIO<M>\n    {\n        return from s in pure<IN, OUT, M, Iterator<Duration>>(schedule.Run().GetIterator())\n               from r in ma\n               from t in go(s, ma, r)\n               select t;\n\n        static PipeT<IN, OUT, M, A> go(Iterator<Duration> schedule, PipeT<IN, OUT, M, A> ma, A latest) =>\n            schedule.IsEmpty\n                ? pure<IN, OUT, M, A>(latest)\n                : liftIO<IN, OUT, M, Unit>(IO.yieldFor(schedule.Head))\n                   .Bind(_ => ma.Bind(x => go(schedule.Tail, ma, x))); \n    }\n\n    /// <summary>\n    /// Continually lift and repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> repeatM<IN, OUT, M, A>(K<M, A> ma)\n        where M : MonadIO<M> =>\n        repeat(liftM<IN, OUT, M, A>(ma));\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, A> repeatM<IN, OUT, M, A>(Schedule schedule, K<M, A> ma)\n        where M : MonadIO<M> =>\n        repeat(schedule, liftM<IN, OUT, M, A>(ma));\n            \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> fold<IN, OUT, M, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        OUT Init, \n        PipeT<IN, OUT, M, A> Item)\n        where M : MonadIO<M>\n    {\n        var state = Init;\n        var sch   = Time.Run().GetIterator();\n        return Item.Bind(\n            x =>\n            {\n                if (sch.IsEmpty)\n                {\n                    sch.Dispose();\n                    sch = Time.Run().GetIterator();\n                    var nstate = state;\n                    state = Init;\n                    return yield<M, IN, OUT>(nstate);\n                }\n                else\n                {\n                    state = Fold(state, x);\n                    var delay = sch.Head;\n                    sch = sch.Tail;\n                    return liftIO<IN, OUT, M, Unit>(IO.yieldFor(delay));\n                }\n            });\n    }\n    \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> foldUntil<IN, OUT, M, A>(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init, \n        PipeT<IN, OUT, M, A> Item)\n        where M : MonadIO<M>\n    {\n        var state = Init;\n        return Item.Bind(\n            x =>\n            {\n                if (Pred((state, x)))\n                {\n                    var nstate = state;\n                    state = Init;\n                    return yield<M, IN, OUT>(nstate);\n                }\n                else\n                {\n                    state = Fold(state, x);\n                    return PipeTCached<IN, OUT, M>.unitP;\n                }\n            });\n    }\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> foldUntil<IN, OUT, M, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init, \n        PipeT<IN, OUT, M, A> Item)\n        where M : MonadIO<M>\n    {\n        var state = Init;\n        var sch   = Time.Run().GetIterator();\n        return Item.Bind(\n            x =>\n            {\n                if (sch.IsEmpty || Pred((state, x)))\n                {\n                    sch.Dispose();\n                    sch = Time.Run().GetIterator();\n                    var nstate = state;\n                    state = Init;\n                    return yield<M, IN, OUT>(nstate);\n                }\n                else\n                {\n                    state = Fold(state, x);\n                    var delay = sch.Head;\n                    sch = sch.Tail;\n                    return liftIO<IN, OUT, M, Unit>(IO.yieldFor(delay));\n                }\n            });\n    }\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> foldWhile<IN, OUT, M, A>(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init, \n        PipeT<IN, OUT, M, A> Item)\n        where M : MonadIO<M>\n    {\n        var state = Init;\n        return Item.Bind(\n            x =>\n            {\n                if (Pred((state, x)))\n                {\n                    state = Fold(state, x);\n                    return PipeTCached<IN, OUT, M>.unitP;\n                }\n                else\n                {\n                    var nstate = state;\n                    state = Init;\n                    return yield<M, IN, OUT>(nstate);\n                }\n            });\n    }\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> foldWhile<IN, OUT, M, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init, \n        PipeT<IN, OUT, M, A> Item)\n        where M : MonadIO<M>\n    {\n        var state = Init;\n        var sch   = Time.Run().GetIterator();\n        return Item.Bind(\n            x =>\n            {\n                if (sch.IsEmpty || !Pred((state, x)))\n                {\n                    sch.Dispose();\n                    sch = Time.Run().GetIterator();\n                    var nstate = state;\n                    state = Init;\n                    return yield<M, IN, OUT>(nstate);\n                }\n                else\n                {\n                    state = Fold(state, x);\n                    var delay = sch.Head;\n                    sch = sch.Tail;\n                    return liftIO<IN, OUT, M, Unit>(IO.yieldFor(delay));\n                }\n            });\n    }\n    \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> fold<IN, OUT, M>(\n        Schedule Time,\n        Func<OUT, IN, OUT> Fold, \n        OUT Init)\n        where M : MonadIO<M> =>\n        awaiting<M, IN, OUT>().Fold(Time, Fold, Init);\n    \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> foldUntil<IN, OUT, M>(\n        Func<OUT, IN, OUT> Fold, \n        Func<(OUT State, IN Value), bool> Pred, \n        OUT Init)\n        where M : MonadIO<M> =>\n        awaiting<M, IN, OUT>().FoldUntil(Fold, Pred, Init);\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> foldUntil<IN, OUT, M>(\n        Schedule Time,\n        Func<OUT, IN, OUT> Fold, \n        Func<(OUT State, IN Value), bool> Pred, \n        OUT Init)\n        where M : MonadIO<M> =>\n        awaiting<M, IN, OUT>().FoldUntil(Time, Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> foldWhile<IN, OUT, M>(\n        Func<OUT, IN, OUT> Fold,\n        Func<(OUT State, IN Value), bool> Pred,\n        OUT Init)\n        where M : MonadIO<M> =>\n        awaiting<M, IN, OUT>().FoldWhile(Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static PipeT<IN, OUT, M, Unit> foldWhile<IN, OUT, M>(\n        Schedule Time,\n        Func<OUT, IN, OUT> Fold, \n        Func<(OUT State, IN Value), bool> Pred, \n        OUT Init)\n        where M : MonadIO<M> =>\n        awaiting<M, IN, OUT>().FoldWhile(Time, Fold, Pred, Init);\n    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/PipeT/PipeT.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Async.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic class PipeT<IN, OUT, M> : \n    MonadT<PipeT<IN, OUT, M>, M>,\n    MonadUnliftIO<PipeT<IN, OUT, M>>\n    where M : MonadIO<M>, Monad<M>\n{\n    static K<PipeT<IN, OUT, M>, B> Monad<PipeT<IN, OUT, M>>.Bind<A, B>(\n        K<PipeT<IN, OUT, M>, A> ma, \n        Func<A, K<PipeT<IN, OUT, M>, B>> f) => \n        ma.As().Bind(x => f(x).As());\n\n    static K<PipeT<IN, OUT, M>, B> Monad<PipeT<IN, OUT, M>>.Recur<A, B>(A value, Func<A, K<PipeT<IN, OUT, M>, Next<A, B>>> f) =>\n        Monad.unsafeRecur(value, f);\n\n    static K<PipeT<IN, OUT, M>, B> Functor<PipeT<IN, OUT, M>>.Map<A, B>(\n        Func<A, B> f, \n        K<PipeT<IN, OUT, M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<PipeT<IN, OUT, M>, A> Applicative<PipeT<IN, OUT, M>>.Pure<A>(A value) => \n        PipeT.pure<IN, OUT, M, A>(value);\n\n    static K<PipeT<IN, OUT, M>, B> Applicative<PipeT<IN, OUT, M>>.Apply<A, B>(\n        K<PipeT<IN, OUT, M>, Func<A, B>> mf,\n        K<PipeT<IN, OUT, M>, A> ma) =>\n        ma.As().ApplyBack(mf.As());\n\n    static K<PipeT<IN, OUT, M>, B> Applicative<PipeT<IN, OUT, M>>.Apply<A, B>(\n        K<PipeT<IN, OUT, M>, Func<A, B>> mf,\n        Memo<PipeT<IN, OUT, M>, A> ma) =>\n        new PipeTMemo<IN, OUT, M, A>(ma).ApplyBack(mf.As());\n\n    static K<PipeT<IN, OUT, M>, B> Applicative<PipeT<IN, OUT, M>>.Action<A, B>(\n        K<PipeT<IN, OUT, M>, A> ma, \n        K<PipeT<IN, OUT, M>, B> mb) =>\n        PipeT.liftM<IN, OUT, M, B>(ma.As().Run().Action(mb.As().Run()));\n\n    static K<PipeT<IN, OUT, M>, A> Applicative<PipeT<IN, OUT, M>>.Actions<A>(IterableNE<K<PipeT<IN, OUT, M>, A>> fas) =>\n        PipeT.liftM<IN, OUT, M, A>(fas.Select(fa => fa.As().Run().Kind()).Actions());\n\n    static K<PipeT<IN, OUT, M>, A> MonadT<PipeT<IN, OUT, M>, M>.Lift<A>(K<M, A> ma) => \n        PipeT.liftM<IN, OUT, M, A>(ma);\n\n    static K<PipeT<IN, OUT, M>, A> MonadIO<PipeT<IN, OUT, M>>.LiftIO<A>(IO<A> ma) => \n        PipeT.liftIO<IN, OUT, M, A>(ma);\n\n    static K<PipeT<IN, OUT, M>, B> MonadUnliftIO<PipeT<IN, OUT, M>>.MapIO<A, B>(K<PipeT<IN, OUT, M>, A> ma, Func<IO<A>, IO<B>> f) => \n        ma.As().MapM(m => M.MapIOMaybe(m, f));\n\n    static K<PipeT<IN, OUT, M>, IO<A>> MonadUnliftIO<PipeT<IN, OUT, M>>.ToIO<A>(K<PipeT<IN, OUT, M>, A> ma) => \n        ma.As().MapM(M.ToIOMaybe);\n    \n    static K<PipeT<IN, OUT, M>, ForkIO<A>> MonadUnliftIO<PipeT<IN, OUT, M>>.ForkIO<A>(\n        K<PipeT<IN, OUT, M>, A> ma,\n        Option<TimeSpan> timeout) =>\n        MonadT.lift<PipeT<IN, OUT, M>, M, ForkIO<A>>(ma.As().Run().ForkIOMaybe(timeout));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/PipeT/PipeT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class PipeTExtensions\n{\n    extension<IN, OUT, M, A>(K<PipeT<IN, OUT, M>, A>)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static PipeT<IN, OUT, M, A> operator +(K<PipeT<IN, OUT, M>, A> ma) =>\n           (PipeT<IN, OUT, M, A>) ma;\n        \n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static PipeT<IN, OUT, M, A> operator >>(K<PipeT<IN, OUT, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/PipeT/PipeT.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `PipeT` monad-transformer base-type for Pipes streaming components:\n///\n///   * `ProducerT` is a `PipeT` with the `IN` 'closed off' with `Unit`\n///   * `ConsumerT` is a `PipeT` with the `OUT` 'closed off' with `Void`\n///   * `EffectT` is a `PipeT` with the `IN` and `OUT` 'closed off' with `Unit` upstream and `Void` downstream\n/// \n/// </summary>\n/// <typeparam name=\"IN\">Type of values to be consumed</typeparam>\n/// <typeparam name=\"OUT\">Type of values to be produced</typeparam>\n/// <typeparam name=\"M\">Lifted monad type</typeparam>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record PipeT<IN, OUT, M, A> : K<PipeT<IN, OUT, M>, A>\n    where M : MonadIO<M>\n{\n    [Pure]\n    public PipeT<IN, OUT1, M, A> Compose<OUT1>(PipeT<OUT, OUT1, M, A> rhs) =>\n        rhs.PairEachAwaitWithYield(_ => this);\n\n    [Pure]\n    public ConsumerT<IN, M, A> Compose(ConsumerT<OUT, M, A> rhs) =>\n        rhs.Proxy.PairEachAwaitWithYield(_ => this);\n\n    [Pure]\n    public static PipeT<IN, OUT, M, A> operator | (PipeT<IN, OUT, M, A> lhs, PipeT<OUT, OUT, M, A> rhs) =>\n        lhs.Compose(rhs);\n\n    [Pure]\n    public static ProducerT<OUT, M, A> operator | (ProducerT<IN, M, A> lhs, PipeT<IN, OUT, M, A> rhs) =>\n        lhs.Compose(rhs);\n\n    [Pure]\n    public static ConsumerT<IN, M, A> operator | (PipeT<IN, OUT, M, A> lhs, ConsumerT<OUT, M, A> rhs) =>\n        lhs.Compose(rhs.Proxy);\n    \n    [Pure]\n    public static implicit operator PipeT<IN, OUT, M, A>(Pure<A> rhs) =>\n        PipeT.pure<IN, OUT, M, A>(rhs.Value);\n    \n    [Pure]\n    public abstract PipeT<IN, OUT, M, B> Map<B>(Func<A, B> f);\n    \n    [Pure]\n    public abstract PipeT<IN, OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f);\n    \n    [Pure]\n    public abstract PipeT<IN, OUT, M, B> ApplyBack<B>(PipeT<IN, OUT, M, Func<A, B>> ff);\n    \n    [Pure]\n    public abstract PipeT<IN, OUT, M, B> Action<B>(PipeT<IN, OUT, M, B> fb);\n    \n    [Pure]\n    public abstract PipeT<IN, OUT, M, B> Bind<B>(Func<A, PipeT<IN, OUT, M, B>> f);\n    \n    [Pure]\n    public PipeT<IN, OUT, M, B> Bind<B>(Func<A, IO<B>> f) =>\n        Bind(x => PipeT.liftIO<IN, OUT, M, B>(f(x)));\n    \n    [Pure]\n    public PipeT<IN, OUT, M, B> Bind<B>(Func<A, K<M, B>> f) =>\n        Bind(x => PipeT.liftM<IN, OUT, M, B>(f(x)));\n    \n    [Pure]\n    public PipeT<IN, OUT, M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Map(x => f(x).Value);\n    \n    [Pure]\n    public PipeT<IN, OUT, M, B> Bind<B>(Func<A, Lift<B>> f) =>\n        Map(x => f(x).Function());\n    \n    [Pure]\n    public PipeT<IN, OUT, M, B> BindAsync<B>(Func<A, ValueTask<PipeT<IN, OUT, M, B>>> f) =>\n        Bind(x => PipeT.liftT(f(x)));\n\n    [Pure]\n    public PipeT<IN, OUT, M, B> Select<B>(Func<A, B> f) =>\n        Map(f);\n   \n    [Pure]\n    public PipeT<IN, OUT, M, C> SelectMany<B, C>(Func<A, PipeT<IN, OUT, M, B>> f, Func<A, B, C> g) =>\n        Bind(x => f(x).Map(y => g(x, y)));\n   \n    [Pure]\n    public PipeT<IN, OUT, M, C> SelectMany<B, C>(Func<A, K<M, B>> f, Func<A, B, C> g) =>\n        Bind(x => f(x).Map(y => g(x, y)));\n   \n    [Pure]\n    public PipeT<IN, OUT, M, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        Bind(x => f(x).Map(y => g(x, y)));\n   \n    [Pure]\n    public PipeT<IN, OUT, M, C> SelectMany<B, C>(Func<A, Pure<B>> f, Func<A, B, C> g) =>\n        Map(x => g(x, f(x).Value));\n   \n    [Pure]\n    public PipeT<IN, OUT, M, C> SelectMany<B, C>(Func<A, Lift<B>> f, Func<A, B, C> g) =>\n        Map(x => g(x, f(x).Function()));\n    \n    [Pure]\n    internal abstract PipeT<IN1, OUT, M, A> ReplaceAwait<IN1>(Func<PipeT<IN1, OUT, M, IN>> producer);\n    \n    [Pure]\n    internal abstract PipeT<IN, OUT1, M, A> ReplaceYield<OUT1>(Func<OUT, PipeT<IN, OUT1, M, Unit>> consumer);\n    \n    [Pure]\n    internal abstract PipeT<IN1, OUT, M, A> PairEachAwaitWithYield<IN1>(Func<Unit, PipeT<IN1, IN, M, A>> producer);\n    \n    [Pure]\n    internal abstract PipeT<IN, OUT1, M, A> PairEachYieldWithAwait<OUT1>(Func<OUT, PipeT<OUT, OUT1, M, A>> consumer);\n                \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public PipeT<IN, OUT, M, Unit> Fold(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        OUT Init) =>\n        PipeT.fold(Time, Fold, Init, this);\n\n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public PipeT<IN, OUT, M, Unit> FoldUntil(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldUntil(Fold, Pred, Init, this);\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public PipeT<IN, OUT, M, Unit> FoldUntil(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldUntil(Time, Fold, Pred, Init, this);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public PipeT<IN, OUT, M, Unit> FoldWhile(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldWhile(Fold, Pred, Init, this);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public PipeT<IN, OUT, M, Unit> FoldWhile(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldWhile(Time, Fold, Pred, Init, this);\n    \n    [Pure]\n    internal abstract K<M, A> Run();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Producer/Producer.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class ProducerExtensions\n{\n    /// <summary>\n    /// Transformation from `PipeT` to `ProducerT`.\n    /// </summary>\n    public static Producer<RT, OUT, A> ToProducer<RT, OUT, A>(this K<PipeT<Unit, OUT, Eff<RT>>, A> pipe) =>\n        new(pipe.As());\n    \n    /// <summary>\n    /// Transformation from `PipeT` to `ProducerT`.\n    /// </summary>\n    public static Producer<RT, OUT, A> ToProducer<RT, OUT, A>(this K<Pipe<RT, Unit, OUT>, A> pipe) =>\n        new(pipe.As().Proxy);\n    \n    /// <summary>\n    /// Downcast\n    /// </summary>\n    public static Producer<RT, OUT, A> As<RT, OUT, A>(this K<Producer<RT, OUT>, A> ma) =>\n        (Producer<RT, OUT, A>)ma;\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Producer<RT, OUT, C> SelectMany<RT, OUT, A, B, C>(\n        this K<Eff<RT>, A> ma, \n        Func<A, Producer<RT, OUT, B>> f,\n        Func<A, B, C> g) =>\n        Producer.liftM<RT, OUT, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Producer<RT, OUT, C> SelectMany<RT, OUT, A, B, C>(\n        this IO<A> ma, \n        Func<A, Producer<RT, OUT, B>> f,\n        Func<A, B, C> g) =>\n        Producer.liftIO<RT, OUT, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Producer<RT, OUT, C> SelectMany<RT, OUT, A, B, C>(\n        this Pure<A> ma, \n        Func<A, Producer<RT, OUT, B>> f,\n        Func<A, B, C> g) =>\n        Producer.pure<RT, OUT, A>(ma.Value).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Producer<RT, OUT, C> SelectMany<RT, OUT, A, B, C>(\n        this Lift<A> ff, \n        Func<A, Producer<RT, OUT, B>> f,\n        Func<A, B, C> g) =>\n        Producer.lift<RT, OUT, A>(ff.Function).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Producer<RT, OUT, B> Bind<RT, OUT, A, B>(\n        this K<Eff<RT>, A> ma, \n        Func<A, Producer<RT, OUT, B>> f) =>\n        Producer.liftM<RT, OUT, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Producer<RT, OUT, B> Bind<RT, OUT, A, B>(\n        this IO<A> ma, \n        Func<A, Producer<RT, OUT, B>> f) =>\n        Producer.liftIO<RT, OUT, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Producer<RT, OUT, B> Bind<RT, OUT, A, B>(\n        this Pure<A> ma, \n        Func<A, Producer<RT, OUT, B>> f) =>\n        Producer.pure<RT, OUT, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public static Producer<RT, OUT, B> Bind<RT, OUT, A, B>(\n        this Lift<A> ff, \n        Func<A, Producer<RT, OUT, B>> f) =>\n        Producer.lift<RT, OUT, A>(ff.Function).Bind(f);\n    \n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static Producer<RT, OUT, C> SelectMany<RT, OUT, A, C>(\n        this K<Producer<RT, OUT>, A> ma,\n        Func<A, Guard<Error, Unit>> bind,\n        Func<A, Unit, C> project) =>\n        ma.Bind(a => bind(a) switch\n                     {\n                         { Flag: true } => Producer.pure<RT, OUT, C>(project(a, default)),\n                         var guard      => Producer.error<RT, OUT, C>(guard.OnFalse())\n                     }).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    public static Producer<RT, OUT, C> SelectMany<RT, OUT, B, C>(\n        this Guard<Error, Unit> ma,\n        Func<Unit, K<Producer<RT, OUT>, B>> bind,\n        Func<Unit, B, C> project) =>\n        ma switch\n        {\n            { Flag: true } => bind(default).Map(b => project(default, b)).As(),\n            var guard      => Producer.error<RT, OUT, C>(guard.OnFalse())\n        };    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Producer/Producer.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pipes;\n\npublic static class Producer\n{\n    /// <summary>\n    /// Yield a value downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> yield<RT, OUT>(OUT value) =>\n        PipeT.yield<Eff<RT>, Unit, OUT>(value);\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> yieldAll<RT, OUT>(IEnumerable<OUT> values) =>\n        PipeT.yieldAll<Eff<RT>, Unit, OUT>(values);\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> yieldAll<RT, OUT>(IAsyncEnumerable<OUT> values) =>\n        PipeT.yieldAll<Eff<RT>, Unit, OUT>(values);\n    \n    /// <summary>\n    /// Evaluate the `M` monad repeatedly, yielding its bound values downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> yieldRepeat<RT, OUT>(K<Eff<RT>, OUT> ma) =>\n        PipeT.yieldRepeat<Eff<RT>, Unit, OUT>(ma);\n\n    /// <summary>\n    /// Evaluate the `IO` monad repeatedly, yielding its bound values downstream\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> yieldRepeatIO<RT, OUT>(IO<OUT> ma) =>\n        PipeT.yieldRepeatIO<Eff<RT>, Unit, OUT>(ma);\n    \n    /// <summary>\n    /// Create a producer that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> pure<RT, OUT, A>(A value) =>\n        PipeT.pure<Unit, OUT, Eff<RT>, A>(value);\n    \n    /// <summary>\n    /// Create a producer that always fails\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> error<RT, OUT, A>(Error value) =>\n        PipeT.error<Unit, OUT, Eff<RT>, A>(value);\n    \n    /// <summary>\n    /// Create a producer that yields nothing at all\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> empty<RT, OUT, A>() =>\n        PipeT.empty<Unit, OUT, Eff<RT>, A>();\n    \n    /// <summary>\n    /// Create a producer that lazily returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> lift<RT, OUT, A>(Func<A> f)  =>\n        PipeT.lift<Unit, OUT, Eff<RT>, A>(f);\n    \n    /// <summary>\n    /// Create a producer that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> liftM<RT, OUT, A>(K<Eff<RT>, A> ma) =>\n        PipeT.liftM<Unit, OUT, Eff<RT>, A>(ma);\n    \n    /// <summary>\n    /// Create a producer that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> liftIO<RT, OUT, A>(IO<A> ma) =>\n        PipeT.liftIO<Unit, OUT, Eff<RT>, A>(ma);\n        \n    /// <summary>\n    /// Create a lazy proxy \n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> liftT<RT, OUT, A>(Func<Producer<RT, OUT, A>> f) =>\n        PipeT.liftT(() => f().Proxy);\n    \n    /// <summary>\n    /// Create an asynchronous lazy proxy \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> liftT<RT, OUT, A>(Func<ValueTask<Producer<RT, OUT, A>>> f) =>\n        PipeT.liftT(() => f().Map(p => p.Proxy));\n    \n    /// <summary>\n    /// Create an asynchronous proxy \n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> liftT<RT, OUT, A>(ValueTask<Producer<RT, OUT, A>> f) =>\n        PipeT.liftT(f.Map(p => p.Proxy));\n\n    /// <summary>\n    /// Continually repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> repeat<RT, OUT, A>(Producer<RT, OUT, A> ma) =>\n        PipeT.repeat(ma.Proxy);\n    \n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> repeat<RT, OUT, A>(Schedule schedule, Producer<RT, OUT, A> ma) =>\n        PipeT.repeat(schedule, ma.Proxy);\n\n    /// <summary>\n    /// Continually lift and repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> repeatM<RT, OUT, A>(K<Eff<RT>, A> ma) =>\n        PipeT.repeatM<Unit, OUT, Eff<RT>, A>(ma);\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, A> repeatM<RT, OUT, A>(Schedule schedule, K<Eff<RT>, A> ma) =>\n        PipeT.repeatM<Unit, OUT, Eff<RT>, A>(schedule, ma);\n                \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> fold<RT, OUT, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        OUT Init,\n        Producer<RT, OUT, A> Item) =>\n        PipeT.fold(Time, Fold, Init, Item.Proxy);\n\n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> foldUntil<RT, OUT, A>(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init,\n        Producer<RT, OUT, A> Item) =>\n        PipeT.foldUntil(Fold, Pred, Init, Item.Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> foldUntil<RT, OUT, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init,\n        Producer<RT, OUT, A> Item) =>\n        PipeT.foldUntil(Time, Fold, Pred, Init, Item.Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> foldWhile<RT, OUT, M, A>(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init,\n        Producer<RT, OUT, A> Item) =>\n        PipeT.foldWhile(Fold, Pred, Init, Item.Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static Producer<RT, OUT, Unit> foldWhile<RT, OUT, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init,\n        Producer<RT, OUT, A> Item) =>\n        PipeT.foldWhile(Time, Fold, Pred, Init, Item.Proxy);\n\n    /// <summary>\n    /// Merge multiple producers\n    /// </summary>\n    /// <param name=\"producers\">Producers to merge</param>\n    /// <param name=\"settings\">Buffer settings</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns>Merged producer</returns>\n    public static Producer<RT, OUT, Unit> merge<RT, OUT>(\n        params Producer<RT, OUT, Unit>[] producers) =>\n        merge(toSeq(producers));\n    \n    /// <summary>\n    /// Merge multiple producers\n    /// </summary>\n    /// <param name=\"producers\">Producers to merge</param>\n    /// <param name=\"settings\">Buffer settings</param>\n    /// <typeparam name=\"RT\">Effect runtime type</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <returns>Merged producer</returns>\n    public static Producer<RT, OUT, Unit> merge<RT, OUT>(\n        Seq<Producer<RT, OUT, Unit>> producers, \n        Buffer<OUT>? settings = null) =>\n        ProducerT.merge(producers.Map(p => new ProducerT<OUT, Eff<RT>, Unit>(p.Proxy)), settings);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Producer/Producer.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Async.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic class Producer<RT, OUT> : \n    MonadT<Producer<RT, OUT>, Eff<RT>>,\n    MonadUnliftIO<Producer<RT, OUT>>\n{\n    static K<Producer<RT, OUT>, B> Monad<Producer<RT, OUT>>.Bind<A, B>(\n        K<Producer<RT, OUT>, A> ma, \n        Func<A, K<Producer<RT, OUT>, B>> f) => \n        ma.As().Bind(x => f(x).As());\n\n    static K<Producer<RT, OUT>, B> Monad<Producer<RT, OUT>>.Recur<A, B>(A value, Func<A, K<Producer<RT, OUT>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<Producer<RT, OUT>, B> Functor<Producer<RT, OUT>>.Map<A, B>(\n        Func<A, B> f, \n        K<Producer<RT, OUT>, A> ma) => \n        ma.As().Map(f);\n\n    static K<Producer<RT, OUT>, A> Applicative<Producer<RT, OUT>>.Pure<A>(A value) => \n        Producer.pure<RT, OUT, A>(value);\n\n    static K<Producer<RT, OUT>, B> Applicative<Producer<RT, OUT>>.Apply<A, B>(\n        K<Producer<RT, OUT>, Func<A, B>> mf,\n        K<Producer<RT, OUT>, A> ma) =>\n        ma.As().ApplyBack(mf.As());\n    \n    static K<Producer<RT, OUT>, B> Applicative<Producer<RT, OUT>>.Apply<A, B>(\n        K<Producer<RT, OUT>, Func<A, B>> mf,\n        Memo<Producer<RT, OUT>, A> ma) =>\n        new PipeTMemo<Unit, OUT, Eff<RT>, A>(ma.Lower().Map(ma => ma.As().Proxy.Kind()).Lift())\n           .ApplyBack(mf.As().Proxy)\n           .ToProducer();\n    \n    static K<Producer<RT, OUT>, A> MonadT<Producer<RT, OUT>, Eff<RT>>.Lift<A>(K<Eff<RT>, A> ma) => \n        Producer.liftM<RT, OUT, A>(ma);\n\n    static K<Producer<RT, OUT>, A> MonadIO<Producer<RT, OUT>>.LiftIO<A>(IO<A> ma) => \n        Producer.liftIO<RT, OUT, A>(ma);\n\n    static K<Producer<RT, OUT>, B> MonadUnliftIO<Producer<RT, OUT>>.MapIO<A, B>(K<Producer<RT, OUT>, A> ma, Func<IO<A>, IO<B>> f) => \n        ma.As().MapIO(f);\n\n    static K<Producer<RT, OUT>, IO<A>> MonadUnliftIO<Producer<RT, OUT>>.ToIO<A>(K<Producer<RT, OUT>, A> ma) => \n        ma.MapIO(IO.pure);\n\n    static K<Producer<RT, OUT>, B> Applicative<Producer<RT, OUT>>.Action<A, B>(\n        K<Producer<RT, OUT>, A> ma, \n        K<Producer<RT, OUT>, B> mb) =>\n        Producer.liftM<RT, OUT, B>(ma.As().Run().Action(mb.As().Run()));\n\n    static K<Producer<RT, OUT>, A> Applicative<Producer<RT, OUT>>.Actions<A>(\n        IterableNE<K<Producer<RT, OUT>, A>> fas) =>\n        fas.Select(fa => fa.As().Proxy.Kind())\n           .Actions()\n           .ToProducer();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Producer/Producer.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class ProducerExtensions\n{\n    extension<RT, OUT, A>(K<Producer<RT, OUT>, A>)\n    {\n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static Producer<RT, OUT, A> operator +(K<Producer<RT, OUT>, A> ma) =>\n           (Producer<RT, OUT, A>) ma;\n        \n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static Producer<RT, OUT, A> operator >>(K<Producer<RT, OUT>, A> ma, Lower lower) =>\n           +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/Producer/Producer.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `Producer` streaming producer monad-transformer instance\n/// </summary>\npublic readonly record struct Producer<RT, OUT, A>(PipeT<Unit, OUT, Eff<RT>, A> Proxy) : K<Producer<RT, OUT>, A>\n{\n    [Pure]\n    public Producer<RT, OUT1, A> Compose<OUT1>(PipeT<OUT, OUT1, Eff<RT>, A> rhs) =>\n        Proxy.Compose(rhs).ToProducer();\n\n    [Pure]\n    public Producer<RT, OUT1, A> Compose<OUT1>(Pipe<RT, OUT, OUT1, A> rhs) =>\n        Proxy.Compose(rhs.Proxy);\n\n    [Pure]\n    public Effect<RT, A> Compose(ConsumerT<OUT, Eff<RT>, A> rhs) =>\n        Proxy.Compose(rhs.Proxy).ToEffect();\n\n    [Pure]\n    public Effect<RT, A> Compose(Consumer<RT, OUT, A> rhs) =>\n        Proxy.Compose(rhs.Proxy).ToEffect();\n\n    [Pure]\n    public static Effect<RT, A> operator | (Producer<RT, OUT, A> lhs, ConsumerT<OUT, Eff<RT>, A> rhs) =>\n        lhs.Proxy.Compose(rhs.Proxy).ToEffect();\n\n    [Pure]\n    public static Effect<RT, A> operator | (Producer<RT, OUT, A> lhs, Consumer<RT, OUT, A> rhs) =>\n        lhs.Proxy.Compose(rhs.Proxy).ToEffect();\n    \n    [Pure]\n    public Producer<RT, OUT, B> Map<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n    \n    [Pure]\n    public Producer<RT, OUT, B> MapM<B>(Func<Eff<RT, A>, Eff<RT, B>> f) =>\n        Proxy.MapM(mx => f(mx.As()));\n\n    [Pure]\n    public Producer<RT, OUT, B> MapIO<B>(Func<IO<A>, IO<B>> f) =>\n        Proxy.MapIO(f);\n\n    [Pure]\n    public Producer<RT, OUT, B> ApplyBack<B>(Producer<RT, OUT, Func<A, B>> ff) =>\n        Proxy.ApplyBack(ff.Proxy);\n    \n    [Pure]\n    public Producer<RT, OUT, B> Action<B>(Producer<RT, OUT, B> fb) =>\n        Proxy.Action(fb.Proxy);\n    \n    [Pure]\n    public Producer<RT, OUT, B> Bind<B>(Func<A, Producer<RT, OUT, B>> f) =>\n        Proxy.Bind(x => f(x).Proxy);\n    \n    [Pure]\n    public Producer<RT, OUT, B> Bind<B>(Func<A, K<Eff<RT>, B>> f) => \n        Proxy.Bind(f); \n    \n    [Pure]\n    public Producer<RT, OUT, B> Bind<B>(Func<A, IO<B>> f) => \n        Proxy.Bind(f); \n       \n    [Pure]\n    public Producer<RT, OUT, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Proxy.Bind(f);\n   \n    [Pure]\n    public Producer<RT, OUT, B> Bind<B>(Func<A, Lift<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    public Producer<RT, OUT, B> Select<B>(Func<A, B> f) =>\n        Map(f);\n   \n    [Pure]\n    public Producer<RT, OUT, C> SelectMany<B, C>(Func<A, Producer<RT, OUT, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(x => f(x).Proxy, g);\n   \n    [Pure]\n    public Producer<RT, OUT, C> SelectMany<B, C>(Func<A, K<Eff<RT>, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Producer<RT, OUT, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Producer<RT, OUT, C> SelectMany<B, C>(Func<A, Pure<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public Producer<RT, OUT, C> SelectMany<B, C>(Func<A, Lift<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n                \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Producer<RT, OUT, Unit> Fold(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        OUT Init) =>\n        PipeT.fold(Time, Fold, Init, Proxy);\n\n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Producer<RT, OUT, Unit> FoldUntil(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldUntil(Fold, Pred, Init, Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Producer<RT, OUT, Unit> FoldUntil(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldUntil(Time, Fold, Pred, Init, Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Producer<RT, OUT, Unit> FoldWhile(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldWhile(Fold, Pred, Init, Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public Producer<RT, OUT, Unit> FoldWhile(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldWhile(Time, Fold, Pred, Init, Proxy);   \n    \n    [Pure]\n    public static implicit operator Producer<RT, OUT, A>(PipeT<Unit, OUT, Eff<RT>, A> pipe) =>\n        pipe.ToProducer();\n    \n    [Pure]\n    public static implicit operator Producer<RT, OUT, A>(Pipe<RT, Unit, OUT, A> pipe) =>\n        pipe.ToProducer();\n    \n    [Pure]\n    public static implicit operator Producer<RT, OUT, A>(ProducerT<OUT, Eff<RT>, A> pipe) =>\n        pipe.Proxy.ToProducer();\n    \n    [Pure]\n    public static implicit operator Producer<RT, OUT, A>(Pure<A> rhs) =>\n        Producer.pure<RT, OUT, A>(rhs.Value);\n\n    [Pure]\n    internal Eff<RT, A> Run() =>\n        Proxy.Run().As();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ProducerT/ProducerT.Extensions.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class ProducerTExtensions\n{\n    /// <summary>\n    /// Transformation from `PipeT` to `ProducerT`.\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, A> ToProducer<OUT, M, A>(this K<PipeT<Unit, OUT, M>, A> pipe)\n        where M : MonadIO<M> =>\n        new(pipe.As());\n    \n    /// <summary>\n    /// Downcast\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, A> As<OUT, M, A>(this K<ProducerT<OUT, M>, A> ma)\n        where M : MonadIO<M> =>\n        (ProducerT<OUT, M, A>)ma;\n    \n    /// <summary>\n    /// Convert to the `Eff` version of `Producer`\n    /// </summary>\n    [Pure]\n    public static Producer<RT, OUT, A> ToEff<RT, OUT, A>(this K<ProducerT<OUT, Eff<RT>>, A> ma) =>\n        ma.As();\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, C> SelectMany<OUT, M, A, B, C>(\n        this K<M, A> ma, \n        Func<A, ProducerT<OUT, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        ProducerT.liftM<OUT, M, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, C> SelectMany<OUT, M, A, B, C>(\n        this IO<A> ma, \n        Func<A, ProducerT<OUT, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        ProducerT.liftIO<OUT, M, A>(ma).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, C> SelectMany<OUT, M, A, B, C>(\n        this Pure<A> ma, \n        Func<A, ProducerT<OUT, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        ProducerT.pure<OUT, M, A>(ma.Value).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, C> SelectMany<OUT, M, A, B, C>(\n        this Lift<A> ff, \n        Func<A, ProducerT<OUT, M, B>> f,\n        Func<A, B, C> g)\n        where M : MonadIO<M> =>\n        ProducerT.lift<OUT, M, A>(ff.Function).SelectMany(f, g);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, B> Bind<OUT, M, A, B>(\n        this K<M, A> ma, \n        Func<A, ProducerT<OUT, M, B>> f)\n        where M : MonadIO<M> =>\n        ProducerT.liftM<OUT, M, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, B> Bind<OUT, M, A, B>(\n        this IO<A> ma, \n        Func<A, ProducerT<OUT, M, B>> f)\n        where M : MonadIO<M> =>\n        ProducerT.liftIO<OUT, M, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, B> Bind<OUT, M, A, B>(\n        this Pure<A> ma, \n        Func<A, ProducerT<OUT, M, B>> f)\n        where M : MonadIO<M> =>\n        ProducerT.pure<OUT, M, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, B> Bind<OUT, M, A, B>(\n        this Lift<A> ff, \n        Func<A, ProducerT<OUT, M, B>> f)\n        where M : MonadIO<M> =>\n        ProducerT.lift<OUT, M, A>(ff.Function).Bind(f);\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, C> SelectMany<OUT, E, M, A, C>(\n        this K<ProducerT<OUT, M>, A> ma,\n        Func<A, Guard<E, Unit>> bind,\n        Func<A, Unit, C> project)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        ma.Bind(a => bind(a) switch\n                     {\n                         { Flag: true } => ProducerT.pure<OUT, M, C>(project(a, default)),\n                         var guard      => ProducerT.fail<OUT, E, M, C>(guard.OnFalse())\n                     }).As();\n\n    /// <summary>\n    /// Monad bind operation\n    /// </summary>\n    [Pure]\n    public static ProducerT<OUT, M, C> SelectMany<OUT, E, M, B, C>(\n        this Guard<E, Unit> ma,\n        Func<Unit, K<ProducerT<OUT, M>, B>> bind,\n        Func<Unit, B, C> project)\n        where M : MonadIO<M>, Fallible<E, M> =>\n        ma switch\n        {\n            { Flag: true } => bind(default).Map(b => project(default, b)).As(),\n            var guard      => ProducerT.fail<OUT, E, M, C>(guard.OnFalse())\n        };\n\n    [Pure]\n    public static ProducerT<OUT, M, B> MapIO<OUT, M, A, B>(\n        this K<ProducerT<OUT, M>, A> ma,\n        Func<IO<A>, IO<B>> f) \n        where M : MonadUnliftIO<M> =>\n        ma.As().MapM(m => M.MapIOMaybe(m, f));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ProducerT/ProducerT.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Pipes;\n\npublic static class ProducerT\n{\n    /// <summary>\n    /// Yield a value downstream\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> yield<M, OUT>(OUT value) \n        where M : MonadIO<M> =>\n        PipeT.yield<M, Unit, OUT>(value);\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> yieldAll<M, OUT>(IEnumerable<OUT> values)\n        where M : MonadIO<M> =>\n        PipeT.yieldAll<M, Unit, OUT>(values);\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> yieldAll<M, OUT>(IAsyncEnumerable<OUT> values)\n        where M : MonadIO<M> =>\n        PipeT.yieldAll<M, Unit, OUT>(values);\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> yieldAll<M, OUT>(Source<OUT> values)\n        where M : MonadIO<M> =>\n        PipeT.yieldAll<M, Unit, OUT>(values);\n\n    /// <summary>\n    /// Yield all values downstream\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> yieldAll<M, OUT>(SourceT<M, OUT> values)\n        where M : MonadIO<M> =>\n        PipeT.yieldAll<M, Unit, OUT>(values);\n    \n    /// <summary>\n    /// Evaluate the `M` monad repeatedly, yielding its bound values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> yieldRepeat<M, OUT>(K<M, OUT> ma)\n        where M : MonadIO<M> =>\n        PipeT.yieldRepeat<M, Unit, OUT>(ma);\n\n    /// <summary>\n    /// Evaluate the `IO` monad repeatedly, yielding its bound values downstream\n    /// </summary>\n    /// <typeparam name=\"IN\">Stream value to consume</typeparam>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> yieldRepeatIO<M, OUT>(IO<OUT> ma)\n        where M : MonadIO<M> =>\n        PipeT.yieldRepeatIO<M, Unit, OUT>(ma);\n    \n    /// <summary>\n    /// Create a producer that simply returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> pure<OUT, M, A>(A value)\n        where M : MonadIO<M> =>\n        PipeT.pure<Unit, OUT, M, A>(value);\n    \n    /// <summary>\n    /// Create a producer that always fails\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"E\">Failure type</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> fail<OUT, E, M, A>(E value) \n        where M : MonadIO<M>, Fallible<E, M> =>\n        PipeT.fail<Unit, OUT, E, M, A>(value);\n    \n    /// <summary>\n    /// Create a producer that always fails\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> error<OUT, M, A>(Error value) \n        where M : MonadIO<M>, Fallible<M> =>\n        PipeT.error<Unit, OUT, M, A>(value);\n    \n    /// <summary>\n    /// Create a producer that yields nothing at all\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> empty<OUT, M, A>() \n        where M : MonadIO<M>, MonoidK<M> =>\n        PipeT.empty<Unit, OUT, M, A>();\n    \n    /// <summary>\n    /// Create a producer that lazily returns a bound value without yielding anything\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> lift<OUT, M, A>(Func<A> f) \n        where M : MonadIO<M> =>\n        PipeT.lift<Unit, OUT, M, A>(f);\n    \n    /// <summary>\n    /// Create a producer that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> liftM<OUT, M, A>(K<M, A> ma) \n        where M : MonadIO<M> =>\n        PipeT.liftM<Unit, OUT, M, A>(ma);\n    \n    /// <summary>\n    /// Create a producer that simply returns the bound value of the lifted monad without yielding anything\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> liftIO<OUT, M, A>(IO<A> ma) \n        where M : MonadIO<M> =>\n        PipeT.liftIO<Unit, OUT, M, A>(ma);\n        \n    /// <summary>\n    /// Create a lazy proxy \n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> liftT<OUT, M, A>(Func<ProducerT<OUT, M, A>> f) \n        where M : MonadIO<M> =>\n        PipeT.liftT(() => f().Proxy);\n    \n    /// <summary>\n    /// Create an asynchronous lazy proxy \n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> liftT<OUT, M, A>(Func<ValueTask<ProducerT<OUT, M, A>>> f) \n        where M : MonadIO<M> =>\n        PipeT.liftT(() => f().Map(p => p.Proxy));\n    \n    /// <summary>\n    /// Create an asynchronous proxy \n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> liftT<OUT, M, A>(ValueTask<ProducerT<OUT, M, A>> f) \n        where M : MonadIO<M> =>\n        PipeT.liftT(f.Map(p => p.Proxy));\n\n    /// <summary>\n    /// Continually repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> repeat<OUT, M, A>(ProducerT<OUT, M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeat(ma.Proxy).ToProducer();\n    \n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> repeat<OUT, M, A>(Schedule schedule, ProducerT<OUT, M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeat(schedule, ma.Proxy).ToProducer();\n\n    /// <summary>\n    /// Continually lift and repeat the provided operation\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> repeatM<OUT, M, A>(K<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeatM<Unit, OUT, M, A>(ma).ToProducer();\n\n    /// <summary>\n    /// Repeat the provided operation based on the schedule provided\n    /// </summary>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, A> repeatM<OUT, M, A>(Schedule schedule, K<M, A> ma)\n        where M : MonadIO<M> =>\n        PipeT.repeatM<Unit, OUT, M, A>(schedule, ma).ToProducer();\n                \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> fold<OUT, M, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        OUT Init,\n        ProducerT<OUT, M, A> Item)\n        where M : MonadIO<M> =>\n        PipeT.fold(Time, Fold, Init, Item.Proxy);\n\n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> foldUntil<OUT, M, A>(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init,\n        ProducerT<OUT, M, A> Item)\n        where M : MonadIO<M> =>\n        PipeT.foldUntil(Fold, Pred, Init, Item.Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> foldUntil<OUT, M, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init,\n        ProducerT<OUT, M, A> Item)\n        where M : MonadIO<M> =>\n        PipeT.foldUntil(Time, Fold, Pred, Init, Item.Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> foldWhile<OUT, M, A>(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init,\n        ProducerT<OUT, M, A> Item)\n        where M : MonadIO<M> =>\n        PipeT.foldWhile(Fold, Pred, Init, Item.Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <param name=\"Item\">Pipe to fold</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public static ProducerT<OUT, M, Unit> foldWhile<OUT, M, A>(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init,\n        ProducerT<OUT, M, A> Item)\n        where M : MonadIO<M> =>\n        PipeT.foldWhile(Time, Fold, Pred, Init, Item.Proxy);\n\n    /// <summary>\n    /// Merge multiple producers\n    /// </summary>\n    /// <param name=\"producers\">Producers to merge</param>\n    /// <param name=\"settings\">Buffer settings</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns>Merged producer</returns>\n    public static ProducerT<OUT, M, Unit> merge<OUT, M>(\n        params ProducerT<OUT, M, Unit>[] producers)\n        where M : MonadUnliftIO<M> =>\n        merge(toSeq(producers));\n    \n    /// <summary>\n    /// Merge multiple producers\n    /// </summary>\n    /// <param name=\"producers\">Producers to merge</param>\n    /// <param name=\"settings\">Buffer settings</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <returns>Merged producer</returns>\n    public static ProducerT<OUT, M, Unit> merge<OUT, M>(\n        Seq<ProducerT<OUT, M, Unit>> producers, \n        Buffer<OUT>? settings = null)\n        where M : MonadUnliftIO<M>\n    {\n        if (producers.Count == 0) return pure<OUT, M, Unit>(default);\n\n        return from conduit in Pure(Conduit.make(settings ?? Buffer<OUT>.Unbounded))\n               from signal  in Signal.countdown<M>(producers.Count)\n               from forks   in forkEffects(producers, signal, conduit)\n               from _       in conduit.ToProducerT<M>()\n               from x       in forks.Traverse(f => f.Cancel).As()\n               select unit;\n    }\n\n    static K<M, Seq<ForkIO<Unit>>> forkEffects<M, OUT>(\n        Seq<ProducerT<OUT, M, Unit>> producers,\n        CountdownSignal<M> signal,\n        Conduit<OUT, OUT> conduit)\n        where M : MonadUnliftIO<M> =>\n        producers.Map(p => (p | conduit.ToConsumerT<M>()).Run())\n                 .Traverse(ma => ma.Bind(_ => trigger(signal, conduit))\n                                   .ForkIO());\n\n    static K<M, Unit> trigger<M, OUT>(CountdownSignal<M> signal, Conduit<OUT, OUT> conduit)\n        where M : MonadIO<M> =>\n        signal.Trigger().Bind(f => when(f, conduit.Complete()).As());\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ProducerT/ProducerT.Monad.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Async.Linq;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic class ProducerT<OUT, M> : \n    MonadT<ProducerT<OUT, M>, M>,\n    MonadUnliftIO<ProducerT<OUT, M>>\n    where M : MonadIO<M>\n{\n    static K<ProducerT<OUT, M>, B> Monad<ProducerT<OUT, M>>.Bind<A, B>(\n        K<ProducerT<OUT, M>, A> ma, \n        Func<A, K<ProducerT<OUT, M>, B>> f) => \n        ma.As().Bind(x => f(x).As());\n\n    static K<ProducerT<OUT, M>, B> Monad<ProducerT<OUT, M>>.Recur<A, B>(A value, Func<A, K<ProducerT<OUT, M>, Next<A, B>>> f) =>\n        Monad.unsafeRecur(value, f);\n\n    static K<ProducerT<OUT, M>, B> Functor<ProducerT<OUT, M>>.Map<A, B>(\n        Func<A, B> f, \n        K<ProducerT<OUT, M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<ProducerT<OUT, M>, A> Applicative<ProducerT<OUT, M>>.Pure<A>(A value) => \n        ProducerT.pure<OUT, M, A>(value);\n\n    static K<ProducerT<OUT, M>, B> Applicative<ProducerT<OUT, M>>.Apply<A, B>(\n        K<ProducerT<OUT, M>, Func<A, B>> mf,\n        K<ProducerT<OUT, M>, A> ma) =>\n        ma.As().ApplyBack(mf.As());\n    \n    static K<ProducerT<OUT, M>, B> Applicative<ProducerT<OUT, M>>.Apply<A, B>(\n        K<ProducerT<OUT, M>, Func<A, B>> mf,\n        Memo<ProducerT<OUT, M>, A> ma) =>\n        new PipeTMemo<Unit, OUT, M, A>(ma.Lower().Map(ma => ma.As().Proxy.Kind()).Lift())\n           .ApplyBack(mf.As().Proxy)\n           .ToProducer();\n\n    static K<ProducerT<OUT, M>, A> MonadT<ProducerT<OUT, M>, M>.Lift<A>(K<M, A> ma) => \n        ProducerT.liftM<OUT, M, A>(ma);\n\n    static K<ProducerT<OUT, M>, A> MonadIO<ProducerT<OUT, M>>.LiftIO<A>(IO<A> ma) => \n        ProducerT.liftIO<OUT, M, A>(ma);\n\n    static K<ProducerT<OUT, M>, B> MonadUnliftIO<ProducerT<OUT, M>>.MapIO<A, B>(K<ProducerT<OUT, M>, A> ma, Func<IO<A>, IO<B>> f) => \n        ma.As().MapM(m => M.MapIOMaybe(m, f));\n\n    static K<ProducerT<OUT, M>, IO<A>> MonadUnliftIO<ProducerT<OUT, M>>.ToIO<A>(K<ProducerT<OUT, M>, A> ma) => \n        ma.As().MapM(M.ToIOMaybe);\n\n    static K<ProducerT<OUT, M>, B> Applicative<ProducerT<OUT, M>>.Action<A, B>(\n        K<ProducerT<OUT, M>, A> ma, \n        K<ProducerT<OUT, M>, B> mb) =>\n        ProducerT.liftM<OUT, M, B>(ma.As().Run().Action(mb.As().Run()));\n\n    static K<ProducerT<OUT, M>, A> Applicative<ProducerT<OUT, M>>.Actions<A>(\n        IterableNE<K<ProducerT<OUT, M>, A>> fas) =>\n        fas.Select(fa => fa.As().Proxy.Kind())\n           .Actions()\n           .ToProducer();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ProducerT/ProducerT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\npublic static partial class ProducerTExtensions\n{\n    extension<OUT, M, A>(K<ProducerT<OUT, M>, A>)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static ProducerT<OUT, M, A> operator +(K<ProducerT<OUT, M>, A> ma) =>\n           (ProducerT<OUT, M, A>) ma;\n        \n        /// <summary>\n        /// Downcast\n        /// </summary>\n        public static ProducerT<OUT, M, A> operator >>(K<ProducerT<OUT, M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/ProducerT/ProducerT.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Pipes;\n\n/// <summary>\n/// `ProducerT` streaming producer monad-transformer instance\n/// </summary>\npublic readonly record struct ProducerT<OUT, M, A>(PipeT<Unit, OUT, M, A> Proxy) : K<ProducerT<OUT, M>, A>\n    where M : MonadIO<M>\n{\n    [Pure]\n    public ProducerT<OUT1, M, A> Compose<OUT1>(PipeT<OUT, OUT1, M, A> rhs) =>\n        Proxy.Compose(rhs).ToProducer();\n\n    [Pure]\n    public EffectT<M, A> Compose(ConsumerT<OUT, M, A> rhs) =>\n        Proxy.Compose(rhs.Proxy).ToEffect();\n\n    [Pure]\n    public static EffectT<M, A> operator | (ProducerT<OUT, M, A> lhs, ConsumerT<OUT, M, A> rhs) =>\n        lhs.Proxy.Compose(rhs.Proxy).ToEffect();\n    \n    [Pure]\n    public ProducerT<OUT, M, B> Map<B>(Func<A, B> f) =>\n        Proxy.Map(f);\n    \n    [Pure]\n    public ProducerT<OUT, M, B> MapM<B>(Func<K<M, A>, K<M, B>> f) =>\n        Proxy.MapM(f);\n\n    [Pure]\n    public ProducerT<OUT, M, B> ApplyBack<B>(ProducerT<OUT, M, Func<A, B>> ff) =>\n        Proxy.ApplyBack(ff.Proxy);\n    \n    [Pure]\n    public ProducerT<OUT, M, B> Action<B>(ProducerT<OUT, M, B> fb) =>\n        Proxy.Action(fb.Proxy);\n    \n    [Pure]\n    public ProducerT<OUT, M, B> Bind<B>(Func<A, ProducerT<OUT, M, B>> f) =>\n        Proxy.Bind(x => f(x).Proxy);\n    \n    [Pure]\n    public ProducerT<OUT, M, B> Bind<B>(Func<A, K<M, B>> f) => \n        Proxy.Bind(f); \n    \n    [Pure]\n    public ProducerT<OUT, M, B> Bind<B>(Func<A, IO<B>> f) => \n        Proxy.Bind(f); \n       \n    [Pure]\n    public ProducerT<OUT, M, B> Bind<B>(Func<A, Pure<B>> f) =>\n        Proxy.Bind(f);\n   \n    [Pure]\n    public ProducerT<OUT, M, B> Bind<B>(Func<A, Lift<B>> f) =>\n        Proxy.Bind(f);\n\n    [Pure]\n    public ProducerT<OUT, M, B> Select<B>(Func<A, B> f) =>\n        Map(f);\n   \n    [Pure]\n    public ProducerT<OUT, M, C> SelectMany<B, C>(Func<A, ProducerT<OUT, M, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(x => f(x).Proxy, g);\n   \n    [Pure]\n    public ProducerT<OUT, M, C> SelectMany<B, C>(Func<A, K<M, B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public ProducerT<OUT, M, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public ProducerT<OUT, M, C> SelectMany<B, C>(Func<A, Pure<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n   \n    [Pure]\n    public ProducerT<OUT, M, C> SelectMany<B, C>(Func<A, Lift<B>> f, Func<A, B, C> g) =>\n        Proxy.SelectMany(f, g);\n                \n    /// <summary>\n    /// Fold the given pipe until the `Schedule` completes.\n    /// Once complete, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public ProducerT<OUT, M, Unit> Fold(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        OUT Init) =>\n        PipeT.fold(Time, Fold, Init, Proxy);\n\n    /// <summary>\n    /// Fold the given pipe until the predicate is `true`.  Once `true` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public ProducerT<OUT, M, Unit> FoldUntil(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldUntil(Fold, Pred, Init, Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe until the predicate is `true` or the `Schedule` completes.\n    /// Once `true`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public ProducerT<OUT, M, Unit> FoldUntil(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldUntil(Time, Fold, Pred, Init, Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true`.  Once `false` the pipe yields the\n    /// aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public ProducerT<OUT, M, Unit> FoldWhile(\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldWhile(Fold, Pred, Init, Proxy);\n        \n    /// <summary>\n    /// Fold the given pipe while the predicate is `true` or the `Schedule` completes.\n    /// Once `false`, or completed, the pipe yields the aggregated value downstream.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to run each item</param>\n    /// <param name=\"Fold\">Fold function</param>\n    /// <param name=\"Pred\">Until predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"OUT\">Stream value to produce</typeparam>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns></returns>\n    public ProducerT<OUT, M, Unit> FoldWhile(\n        Schedule Time,\n        Func<OUT, A, OUT> Fold, \n        Func<(OUT State, A Value), bool> Pred, \n        OUT Init) =>\n        PipeT.foldWhile(Time, Fold, Pred, Init, Proxy);   \n    \n    [Pure]\n    public static implicit operator ProducerT<OUT, M, A>(PipeT<Unit, OUT, M, A> pipe) =>\n        pipe.ToProducer();\n    \n    [Pure]\n    public static implicit operator ProducerT<OUT, M, A>(Pure<A> rhs) =>\n        ProducerT.pure<OUT, M, A>(rhs.Value);\n\n    [Pure]\n    internal K<M, A> Run() =>\n        Proxy.Run();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Pipes/README.md",
    "content": "> If you find this feature confusing at first, and it wouldn't be surprising as\n  it's quite a complex idea, there are some examples in the [EffectsExample sample in the repo](https://github.com/louthy/language-ext/blob/main/Samples/EffectsExamples/Examples/TextFileChunkStreamExample.cs)\n\nConventional stream programming forces you to choose only two of the\nfollowing three features:\n\n1. **Effects**\n2. **Streaming**\n3. **Composability**\n\nIf you sacrifice _Effects_ you get `IEnumerable`, which you\ncan transform using composable functions in constant space, but without\ninterleaving effects (other than of the _imperative kind_).\n\nIf you sacrifice _Streaming_ you get `Traverse` and `Sequence`, which are \ncomposable and effectful, but do not return a single result until the whole \nlist has first been processed and loaded into memory.\n\nIf you sacrifice _Composability_ you write a tightly coupled for loops,\nand fire off imperative side-effects like they're going out of style.  Which \nis streaming and effectful, but is not modular or separable.\n\n`Pipes` gives you all three features: effectful, streaming, and composable\nprogramming.  `Pipes` also provides a wide variety of stream programming\nabstractions which are all subsets of a single unified machinery:\n\n* Effectful [`Producer`](Producer) and [`ProducerT`](ProducerT),\n* Effectful [`Consumer`](Consumer) and [`ConsumerT`](ConsumerT),\n* Effectful [`Pipe`](Pipe) and [`PipeT`](PipeT) (like Unix pipes)\n* Effectful [`Effect`](Effect) and [`EffectT`](EffectT) \n\n> The `T` suffix types (`ProducerT`, `ConsumerT`, `PipeT`, and `EffectT`) are the \n> more generalist monad-transformers.  They can lift any monad `M` you like into them,\n> supplementing the behaviour of `Pipes` with the behaviour of `M`.  The non-`T` \n> suffix types (`Producer`, `Consumer`, `Pipe`, and `Effect`) only support the lifting\n> of the `Eff<RT, A>` type.  They're slightly easier to use, just less flexible.\n\nAll of these are connectable and you can combine them together in clever and\nunexpected ways because they all share the same underlying type: [`PipeT`](PipeT).\n\nThe pipes ecosystem decouples stream processing stages from each other so\nthat you can mix and match diverse stages to produce useful streaming\nprograms.  If you are a library writer, pipes lets you package up streaming\ncomponents into a reusable interface.  If you are an application writer,\npipes lets you connect pre-made streaming components with minimal effort to\nproduce a highly-efficient program that streams data in constant memory.\n\nTo enforce loose coupling, components can only communicate using two commands:\n\n* `yield`: Send output data\n* `awaiting`: Receive input data\n\nPipes has four types of components built around these two commands:\n\n* [`Producer`](Producer) and [`ProducerT`](ProducerT) yield values downstream and can only do so using: `Producer.yield` and `ProducerT.yield`.\n* [`Consumer`](Consumer) and [`ConsumerT`](ConsumerT) await values from upstream and can only do so using: `Consumer.awaiting` and `ConsumerT.awaiting`.\n* [`Pipe`](Pipe) and [`PipeT`](PipeT) can both await and yield, using: `Pipe.awaiting`, `PipeT.awaiting`, `Pipe.yield`, and `PipeT.yield`. \n* [`Effect`](Effect) and [`EffectT`](EffectT) can neither yield nor await and they model non-streaming components.\n\nPipes uses parametric polymorphism (i.e. generics) to overload all operations. The operator `|` connects `Producer`, `Consumer`, and `Pipe` by 'fusing' \nthem together.  Eventually they will 'fuse' together into an `Effect` or `EffectT`.  This final state can be `.Run()`, you must fuse to an `Effect` or \n`EffectT` to be able to invoke any of the pipelines.\n\n`Producer`, `ProducerT`, `Consumer`, `ConsumerT`, `Pipe`, `Effect`, and `EffectT` are all special cases of a\nsingle underlying type: [`PipeT`](PipeT).  \n\nYou can think of it as having the following shape:\n  \n    PipeT<IN, OUT, M, A>\n\n          Upstream | Downstream\n              +---------+\n              |         |\n         IN --►         --► OUT  -- Information flowing downstream\n              |    |    |\n              +----|----+\n                   |\n                   A\n        \n Pipes uses type synonyms to hide unused inputs or outputs and clean up\n type signatures.  These type synonyms come in two flavors:\n\n * Concrete type synonyms that explicitly close unused inputs and outputs of\n   the `Proxy` type.\n\n * Polymorphic type synonyms that don't explicitly close unused inputs or\n   outputs.\n\n The concrete type synonyms use `Unit` to close unused inputs and `Void` (the\n uninhabited type) to close unused outputs:\n\n * `EffectT`: explicitly closes both ends, forbidding `awaiting` and `yield`:\n\n        EffectT<M, A> = PipeT<Unit, Void, M, A>\n         \n                 Upstream | Downstream\n\n                     +---------+\n                     |         |\n              Unit --►         --► Void\n                     |    |    |\n                     +----|----+\n                          |\n                          A\n\n * `ProducerT`: explicitly closes the upstream end, forbidding `awaiting`:\n\n        ProducerT<OUT, M, A> = PipeT<Unit, OUT, M, A>\n         \n                 Upstream | Downstream\n\n                     +---------+\n                     |         |\n              Unit --►         --► OUT\n                     |    |    |\n                     +----|----+\n                          |\n                          A\n   \n * `ConsumerT`: explicitly closes the downstream end, forbidding `yield`:\n\n         ConsumerT<IN, M, A> = PipeT<IN, Void, M, A>\n        \n                 Upstream | Downstream\n\n                     +---------+\n                     |         |\n                IN --►         --► Void\n                     |    |    |\n                     +----|----+\n                          |\n                          A\n          \nWhen you compose `PipeT` using `|` all you are doing is placing them\nside by side and fusing them laterally.  For example, when you compose a\n`ProducerT`, `PipeT`, and a `ConsumerT`, you can think of information flowing\nlike this:\n\n                ProducerT                     PipeT                  ConsumerT\n             +-------------+             +------------+           +-------------+\n             |             |             |            |           |             |\n      Unit --►  readLine   --►  string --►  parseInt  --►  int  --►  writeLine  --► Void\n             |      |      |             |      |     |           |      |      |\n             +------|------+             +------|-----+           +------|------+\n                    |                           |                        |  \n                    A                           A                        A\n\n Composition fuses away the intermediate interfaces, leaving behind an `EffectT`:\n\n                            EffectT\n            +-------------------------------------+\n            |                                     |\n     Unit --►   readLine | parseInt | writeLine   --► Void\n            |                                     |\n            +------------------|------------------+\n                               |\n                               A\n\nThis `EffectT` can be `Run()` which will return the composed underlying `M` type.  Or, \nif it's an `Effect` will return the composed underlying `Eff<RT, A>`."
  },
  {
    "path": "LanguageExt.Streaming/README.md",
    "content": "The `Streaming` library of language-ext is all about compositional streams.  There are two key types of streaming\nfunctionality: **closed-streams** and **open-streams**...\n\n## Closed streams\n\nClosed streams are facilitated by the [`Pipes`](Pipes) system.  The types in the `Pipes` system are _compositional\nmonad-transformers_ that 'fuse' together to produce an [`EffectT<M, A>`](Pipes/EffectT).  This effect is a _closed system_,\nmeaning that there is no way (from the API) to directly interact with the effect from the outside: it can be executed\nand will return a result if it terminates.\n\nThe pipeline components are:\n\n* [`ProducerT<OUT, M, A>`](Pipes/ProducerT)\n* [`PipeT<IN, OUT, M, A>`](Pipes/PipeT)\n* [`ConsumerT<IN, M, A>`](Pipes/ConsumerT)\n\nThese are the components that fuse together (using the `|` operator) to make an [`EffectT<M, A>`](Pipes/EffectT).  The\ntypes are _monad-transformers_ that support lifting monads with the `MonadIO` trait only (which constrains `M`).  This \nmakes sense, otherwise the closed-system would have no effect other than heating up the CPU.\n\nThere are also more specialised versions of the above that only support the lifting of the `Eff<RT, A>` effect-monad:\n\n* [`Producer<RT, OUT, A>`](Pipes/Producer)\n* [`Pipe<RT, IN, OUT, A>`](Pipes/Pipe)\n* [`Consumer<RT, IN, A>`](Pipes/Consumer)\n\nThey all fuse together into an [`Effect<RT, A>`](Pipes/Effect).\n\nPipes are especially useful if you want to build reusable streaming components that you can glue together ad infinitum.\nPipes are, arguably, less useful for day-to-day stream processing, like handling events, but your mileage may vary.\n\n_More details on the [`Pipes page`](Pipes)._\n\n## Open streams\n\nOpen streams are closer to what most C# devs have used classically.  They are like events or `IObservable` streams.\nThey yield values and (under certain circumstances) accept inputs.\n\n* [`Source`](Source) and [`SourceT`](SourceT) yield values synchronously or asynchronously depending on their construction.\n* [`Sink`](Sink) and [`SinkT`](SinkT) receives values and propagates them through the channel they're attached to.\n* [`Conduit`](Conduit) and [`ConduitT`](ConduitT) provides and input transducer (acts like a `Sink`), an internal buffer, and an output transducer (acts like a `Source`). \n\n> I'm calling these 'open streams' because we can `Post` values to a `Sink`/`SinkT` and we can `Reduce` values yielded by\n> `Source`/`SourceT`.  So, they are 'open' for public manipulation, unlike `Pipes` which fuse the public access away.\n\n### [`Source`](Source)\n\n[`Source<A>`](Source) is the 'classic stream': you can lift any of the following types into it: `System.Threading.Channels.Channel<A>`,\n`IEnumerable<A>`, `IAsyncEnumerable<A>`, or singleton values.  To process a stream, you need to use one of the `Reduce`\nor `ReduceAsync` variants.  These take `Reducer` delegates as arguments.  They are essentially a fold over the stream of\nvalues, which results in an aggregated state once the stream has completed.  These reducers can be seen to play a similar\nrole to `Subscribe` in `IObservable` streams, but are more principled because they return a value (which we can leverage\nto carry state for the duration of the stream).\n\n`Source` also supports some built-in reducers:\n\n* `Last` - aggregates no state, simply returns the last item yielded\n* `Iter` - this forces evaluation of the stream, aggregating no state, and ignoring all yielded values.\n* `Collect` - adds all yielded values to a `Seq<A>`, which is then returned upon stream completion.\n\n### [`SourceT`](SourceT)\n\n[`SourceT<M, A>`](SourceT) is the classic-stream _embellished_ - it turns the stream into a monad-transformer that can\nlift any `MonadIO`-enabled monad (`M`), allowing side effects to be embedded into the stream in a principled way.\n\nSo, for example, to use the `IO<A>` monad with `SourceT`, simply use: `SourceT<IO, A>`.  Then you can use one of the\nfollowing `static` methods on the `SourceT` type to lift `IO<A>` effects into a stream:\n\n* `SourceT.liftM(IO<A> effect)` creates a singleton-stream\n* `SourceT.foreverM(IO<A> effect)` creates an infinite stream, repeating the same effect over and over\n* `SourceT.liftM(Channel<IO<A>> channel)` lifts a `System.Threading.Channels.Channel` of effects\n* `SourceT.liftM(IEnumerable<IO<A>> effects)` lifts an `IEnumerable` of effects\n* `SourceT.liftM(IAsyncEnumerable<IO<A>> effects)` lifts an `IAsyncEnumerable` of effects\n\n> Obviously, when lifting non-`IO` monads, the types above change.\n\n`SourceT` also supports the same built-in convenience reducers as `Source` (`Last`, `Iter`, `Collect`).\n\n### [`Sink`](Sink)\n\n[`Sink<A>`](Sink) provides a way to accept many input values.  The values are buffered until consumed.  The sink can be \nthought of as a `System.Threading.Channels.Channel` (which is the buffer that collects the values) that happens to \nmanipulate the values being posted to the buffer just before they are stored.  \n\n> This manipulation is possible because the `Sink` is a `CoFunctor` (contravariant functor).  This is the dual of `Functor`: \nwe can think of `Functor.Map` as converting a value from `A -> B`.  Whereas `CoFunctor.Comap` converts from `B -> A`.  \n\nSo, to manipulate values coming into the `Sink`, use `Comap`.  It will give you a new `Sink` with the manipulation 'built-in'.\n\n### [`SinkT`](SinkT)\n\n[`SinkT<M, A>`](SinkT) provides a way to accept many input values.  The values are buffered until consumed.  The sink can \nbe thought of as a `System.Threading.Channels.Channel` (which is the buffer that collects the values) that happens to \nmanipulate the values being posted to the buffer just before they are stored.\n\n> This manipulation is possible because the `SinkT` is a `CoFunctor` (contravariant functor).  This is the dual of `Functor`:\nwe can think of `Functor.Map` as converting a value from `A -> B`.  Whereas `CoFunctor.Comap` converts from `B -> A`.\n\nSo, to manipulate values coming into the `SinkT`, use `Comap`.  It will give you a new `SinkT` with the manipulation 'built-in'.\n\n`SinkT` is also a transformer that lifts types of `K<M, A>`.\n\n### [`Conduit`](Conduit)\n\n`Conduit<A, B>` can be pictured as so:\n\n    +----------------------------------------------------------------+\n    |                                                                |\n    |  A --> Transducer --> X --> Buffer --> X --> Transducer --> B  |\n    |                                                                |\n    +----------------------------------------------------------------+\n\n* A value of `A` is posted to the `Conduit` (via `Post`)\n* It flows through an input `Transducer`, mapping the `A` value to `X` (an internal type you can't see)\n* The `X` value is then stored in the conduit's internal buffer (a `System.Threading.Channels.Channel`)\n* Any invocation of `Reduce` will force the consumption of the values in the buffer\n* Flowing each value `X` through the output `Transducer`\n\nSo the input and output transducers allow for pre and post-processing of values as they flow through the conduit.  \n`Conduit` is a `CoFunctor`, call `Comap` to manipulate the pre-processing transducer. `Conduit` is also a `Functor`, call\n`Map` to manipulate the post-processing transducer.  There are other non-trait, but common behaviours, like `FoldWhile`,\n`Filter`, `Skip`, `Take`, etc.\n\n> `Conduit` supports access to a `Sink` and a `Source` for more advanced processing.\n\n### [`ConduitT`](Conduit)\n\n`ConduitT<M, A, B>` can be pictured as so:\n\n    +------------------------------------------------------------------------------------------+\n    |                                                                                          |\n    |  K<M, A> --> TransducerM --> K<M, X> --> Buffer --> K<M, X> --> TransducerM --> K<M, B>  |\n    |                                                                                          |\n    +------------------------------------------------------------------------------------------+\n\n* A value of `K<M, A>` is posted to the `Conduit` (via `Post`)\n* It flows through an input `TransducerM`, mapping the `K<M, A>` value to `K<M, X>` (an internal type you can't see)\n* The `K<M, X>` value is then stored in the conduit's internal buffer (a `System.Threading.Channels.Channel`)\n* Any invocation of `Reduce` will force the consumption of the values in the buffer\n* Flowing each value `K<M, A>` through the output `TransducerM`\n\nSo the input and output transducers allow for pre and post-processing of values as they flow through the conduit.  \n`ConduitT` is a `CoFunctor`, call `Comap` to manipulate the pre-processing transducer. `Conduit` is also a `Functor`, call\n`Map` to manipulate the post-processing transducer.  There are other non-trait, but common behaviours, like `FoldWhile`,\n`Filter`, `Skip`, `Take`, etc.\n\n> `ConduitT` supports access to a `SinkT` and a `SourceT` for more advanced processing.\n\n## Open to closed streams\n\nClearly, even for 'closed systems' like the [`Pipes`](Pipes) system, it would be beneficial to be able to post values\ninto the streams from the outside.  And so, the _open-stream components_ can all be converted into `Pipes` components\nlike `ProducerT` and `ConsumerT`.\n\n* `Conduit` and `ConduitT` support `ToProducer`, `ToProducerT`, `ToConsumer`, and `ToConsumerT`.\n* `Sink` and `SinkT` supports `ToConsumer`, and `ToConsumerT`.\n* `Source` and `SourceT` supports `ToProducer`, and `ToProducerT`.\n\nThis allows for the ultimate flexibility in your choice of streaming effect. It also allows for efficient concurrency in\nthe more abstract and compositional world of the pipes. In fact `ProducerT.merge`, which merges many streams into one,\nuses `ConduitT` internally to collect the values and to merge them into a single `ProducerT`."
  },
  {
    "path": "LanguageExt.Streaming/README.nuget.md",
    "content": "The `Streaming` library of language-ext is all about compositional streams.  There are two key types of streaming\nfunctionality: **closed-streams** and **open-streams**...\n\n## Closed streams\n\nClosed streams are facilitated by the [`Pipes`](Pipes) system.  The types in the `Pipes` system are _compositional\nmonad-transformers_ that 'fuse' together to produce an [`EffectT<M, A>`](Pipes/EffectT).  This effect is a _closed system_,\nmeaning that there is no way (from the API) to directly interact with the effect from the outside: it can be executed\nand will return a result if it terminates.\n\nThe pipeline components are:\n\n* [`ProducerT<OUT, M, A>`](Pipes/ProducerT)\n* [`PipeT<IN, OUT, M, A>`](Pipes/PipeT)\n* [`ConsumerT<IN, M, A>`](Pipes/ConsumerT)\n\nThese are the components that fuse together (using the `|` operator) to make an [`EffectT<M, A>`](Pipes/EffectT).  The\ntypes are _monad-transformers_ that support lifting monads with the `MonadIO` trait only (which constrains `M`).  This\nmakes sense, otherwise the closed-system would have no effect other than heating up the CPU.\n\nThere are also more specialised versions of the above that only support the lifting of the `Eff<RT, A>` effect-monad:\n\n* [`Producer<RT, OUT, A>`](Pipes/Producer)\n* [`Pipe<RT, IN, OUT, A>`](Pipes/Pipe)\n* [`Consumer<RT, IN, A>`](Pipes/Consumer)\n\nThey all fuse together into an [`Effect<RT, A>`](Pipes/Effect).\n\nPipes are especially useful if you want to build reusable streaming components that you can glue together ad infinitum.\nPipes are, arguably, less useful for day-to-day stream processing, like handling events, but your mileage may vary.\n\n_More details on the [`Pipes page`](Pipes)._\n\n## Open streams\n\nOpen streams are closer to what most C# devs have used classically.  They are like events or `IObservable` streams.\nThey yield values and (under certain circumstances) accept inputs.\n\n* [`Source`](Source) and [`SourceT`](SourceT) yield values synchronously or asynchronously depending on their construction.\n* [`Sink`](Sink) and [`SinkT`](SinkT) receives values and propagates them through the channel they're attached to.\n* [`Conduit`](Conduit) and [`ConduitT`](ConduitT) provides and input transducer (acts like a `Sink`), an internal buffer, and an output transducer (acts like a `Source`).\n\n> I'm calling these 'open streams' because we can `Post` values to a `Sink`/`SinkT` and we can `Reduce` values yielded by\n> `Source`/`SourceT`.  So, they are 'open' for public manipulation, unlike `Pipes` which fuse the public access away.\n\n### [`Source`](Source)\n\n[`Source<A>`](Source) is the 'classic stream': you can lift any of the following types into it: `System.Threading.Channels.Channel<A>`,\n`IEnumerable<A>`, `IAsyncEnumerable<A>`, or singleton values.  To process a stream, you need to use one of the `Reduce`\nor `ReduceAsync` variants.  These take `Reducer` delegates as arguments.  They are essentially a fold over the stream of\nvalues, which results in an aggregated state once the stream has completed.  These reducers can be seen to play a similar\nrole to `Subscribe` in `IObservable` streams, but are more principled because they return a value (which we can leverage\nto carry state for the duration of the stream).\n\n`Source` also supports some built-in reducers:\n\n* `Last` - aggregates no state, simply returns the last item yielded\n* `Iter` - this forces evaluation of the stream, aggregating no state, and ignoring all yielded values.\n* `Collect` - adds all yielded values to a `Seq<A>`, which is then returned upon stream completion.\n\n### [`SourceT`](SourceT)\n\n[`SourceT<M, A>`](SourceT) is the classic-stream _embellished_ - it turns the stream into a monad-transformer that can\nlift any `MonadIO`-enabled monad (`M`), allowing side effects to be embedded into the stream in a principled way.\n\nSo, for example, to use the `IO<A>` monad with `SourceT`, simply use: `SourceT<IO, A>`.  Then you can use one of the\nfollowing `static` methods on the `SourceT` type to lift `IO<A>` effects into a stream:\n\n* `SourceT.liftM(IO<A> effect)` creates a singleton-stream\n* `SourceT.foreverM(IO<A> effect)` creates an infinite stream, repeating the same effect over and over\n* `SourceT.liftM(Channel<IO<A>> channel)` lifts a `System.Threading.Channels.Channel` of effects\n* `SourceT.liftM(IEnumerable<IO<A>> effects)` lifts an `IEnumerable` of effects\n* `SourceT.liftM(IAsyncEnumerable<IO<A>> effects)` lifts an `IAsyncEnumerable` of effects\n\n> Obviously, when lifting non-`IO` monads, the types above change.\n\n`SourceT` also supports the same built-in convenience reducers as `Source` (`Last`, `Iter`, `Collect`).\n\n### [`Sink`](Sink)\n\n[`Sink<A>`](Sink) provides a way to accept many input values.  The values are buffered until consumed.  The sink can be\nthought of as a `System.Threading.Channels.Channel` (which is the buffer that collects the values) that happens to\nmanipulate the values being posted to the buffer just before they are stored.\n\n> This manipulation is possible because the `Sink` is a `CoFunctor` (contravariant functor).  This is the dual of `Functor`:\nwe can think of `Functor.Map` as converting a value from `A -> B`.  Whereas `CoFunctor.Comap` converts from `B -> A`.\n\nSo, to manipulate values coming into the `Sink`, use `Comap`.  It will give you a new `Sink` with the manipulation 'built-in'.\n\n### [`SinkT`](SinkT)\n\n[`SinkT<M, A>`](SinkT) provides a way to accept many input values.  The values are buffered until consumed.  The sink can\nbe thought of as a `System.Threading.Channels.Channel` (which is the buffer that collects the values) that happens to\nmanipulate the values being posted to the buffer just before they are stored.\n\n> This manipulation is possible because the `SinkT` is a `CoFunctor` (contravariant functor).  This is the dual of `Functor`:\nwe can think of `Functor.Map` as converting a value from `A -> B`.  Whereas `CoFunctor.Comap` converts from `B -> A`.\n\nSo, to manipulate values coming into the `SinkT`, use `Comap`.  It will give you a new `SinkT` with the manipulation 'built-in'.\n\n`SinkT` is also a transformer that lifts types of `K<M, A>`.\n\n### [`Conduit`](Conduit)\n\n`Conduit<A, B>` can be pictured as so:\n\n    +----------------------------------------------------------------+\n    |                                                                |\n    |  A --> Transducer --> X --> Buffer --> X --> Transducer --> B  |\n    |                                                                |\n    +----------------------------------------------------------------+\n\n* A value of `A` is posted to the `Conduit` (via `Post`)\n* It flows through an input `Transducer`, mapping the `A` value to `X` (an internal type you can't see)\n* The `X` value is then stored in the conduit's internal buffer (a `System.Threading.Channels.Channel`)\n* Any invocation of `Reduce` will force the consumption of the values in the buffer\n* Flowing each value `X` through the output `Transducer`\n\nSo the input and output transducers allow for pre and post-processing of values as they flow through the conduit.  \n`Conduit` is a `CoFunctor`, call `Comap` to manipulate the pre-processing transducer. `Conduit` is also a `Functor`, call\n`Map` to manipulate the post-processing transducer.  There are other non-trait, but common behaviours, like `FoldWhile`,\n`Filter`, `Skip`, `Take`, etc.\n\n> `Conduit` supports access to a `Sink` and a `Source` for more advanced processing.\n\n### [`ConduitT`](Conduit)\n\n`ConduitT<M, A, B>` can be pictured as so:\n\n    +------------------------------------------------------------------------------------------+\n    |                                                                                          |\n    |  K<M, A> --> TransducerM --> K<M, X> --> Buffer --> K<M, X> --> TransducerM --> K<M, B>  |\n    |                                                                                          |\n    +------------------------------------------------------------------------------------------+\n\n* A value of `K<M, A>` is posted to the `Conduit` (via `Post`)\n* It flows through an input `TransducerM`, mapping the `K<M, A>` value to `K<M, X>` (an internal type you can't see)\n* The `K<M, X>` value is then stored in the conduit's internal buffer (a `System.Threading.Channels.Channel`)\n* Any invocation of `Reduce` will force the consumption of the values in the buffer\n* Flowing each value `K<M, A>` through the output `TransducerM`\n\nSo the input and output transducers allow for pre and post-processing of values as they flow through the conduit.  \n`ConduitT` is a `CoFunctor`, call `Comap` to manipulate the pre-processing transducer. `Conduit` is also a `Functor`, call\n`Map` to manipulate the post-processing transducer.  There are other non-trait, but common behaviours, like `FoldWhile`,\n`Filter`, `Skip`, `Take`, etc.\n\n> `ConduitT` supports access to a `SinkT` and a `SourceT` for more advanced processing.\n\n## Open to closed streams\n\nClearly, even for 'closed systems' like the [`Pipes`](Pipes) system, it would be beneficial to be able to post values\ninto the streams from the outside.  And so, the _open-stream components_ can all be converted into `Pipes` components\nlike `ProducerT` and `ConsumerT`.\n\n* `Conduit` and `ConduitT` support `ToProducer`, `ToProducerT`, `ToConsumer`, and `ToConsumerT`.\n* `Sink` and `SinkT` supports `ToConsumer`, and `ToConsumerT`.\n* `Source` and `SourceT` supports `ToProducer`, and `ToProducerT`.\n\nThis allows for the ultimate flexibility in your choice of streaming effect. It also allows for efficient concurrency in\nthe more abstract and compositional world of the pipes. In fact `ProducerT.merge`, which merges many streams into one,\nuses `ConduitT` internally to collect the values and to merge them into a single `ProducerT`."
  },
  {
    "path": "LanguageExt.Streaming/Sink/DSL/SinkChoose.cs",
    "content": "using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\nrecord SinkChoose<A, B, C>(Func<A, Either<B, C>> F, Sink<B> Left, Sink<C> Right) : Sink<A>\n{\n    public override Sink<D> Comap<D>(Func<D, A> f) =>\n        new SinkContraMap<A, D>(f, this);\n\n    public override IO<Unit> Post(A value) =>\n        F(value) switch\n        {\n            Either<B, C>.Left(var left)   => Left.Post(left),\n            Either<B, C>.Right(var right) => Right.Post(right),\n            _                             => IO.fail<Unit>(Errors.SinkFull)\n        };\n\n    public override IO<Unit> Complete() =>\n        Left.Complete().Bind(_ => Right.Complete());\n\n    public override IO<Unit> Fail(Error error) =>\n        Left.Fail(error).Bind(_ => Right.Fail(error));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/DSL/SinkCombine.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord SinkCombine<A, B, C>(Func<A, (B Left, C Right)> F, Sink<B> Left, Sink<C> Right) : Sink<A>\n{\n    public override Sink<D> Comap<D>(Func<D, A> f) =>\n        new SinkContraMap<A, D>(f, this);\n\n    public override IO<Unit> Post(A value) =>\n        F(value) switch\n        {\n            var (b, c) =>\n                awaitAll(Left.Post(b).Map(Seq<Error>()).Catch(_ => true, e => IO.pure(Seq(e))),\n                         Right.Post(c).Map(Seq<Error>()).Catch(_ => true, e => IO.pure(Seq(e))))\n                   .Map(es => es.Flatten())\n                   .Bind(es => es switch\n                               {\n                                   [] => unitIO,\n                                   _  => IO.fail<Unit>(Error.Many(es))\n                               }).As()\n        };\n\n    public override IO<Unit> Complete() =>\n        Left.Complete().Bind(_ => Right.Complete());\n\n    public override IO<Unit> Fail(Error error) =>\n        Left.Fail(error).Bind(_ => Right.Fail(error));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/DSL/SinkContraMap.cs",
    "content": "using System;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\nrecord SinkContraMap<A, B>(Func<B, A> F, Sink<A> Sink) : Sink<B>\n{\n    public override Sink<C> Comap<C>(Func<C, B> f) =>\n        new SinkContraMap<A, C>(x => F(f(x)), Sink);\n\n    public override IO<Unit> Post(B value) => \n        Sink.Post(F(value));\n\n    public override IO<Unit> Complete() => \n        Sink.Complete();\n\n    public override IO<Unit> Fail(Error Error) => \n        Sink.Fail(Error);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/DSL/SinkContraMapT.cs",
    "content": "using System;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord SinkContraMapT<A, B>(Transducer<B, A> F, Sink<A> Sink) : Sink<B>\n{\n    public override Sink<C> Comap<C>(Func<C, B> f) =>\n        new SinkContraMapT<A, C>(Transducer.map(f).Compose(F), Sink);\n\n    public override Sink<C> Comap<C>(Transducer<C, B> f) => \n        new SinkContraMapT<A, C>(f.Compose(F), Sink);\n\n    public override IO<Unit> Post(B value) =>\n        F.Reduce<Unit>((_, a) => Sink.Post(a).Map(Reduced.Continue))(unit, value)\n         .Map(x => x.Value);\n\n    public override IO<Unit> Complete() => \n        Sink.Complete();\n\n    public override IO<Unit> Fail(Error Error) => \n        Sink.Fail(Error);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/DSL/SinkEmpty.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord SinkEmpty<A> : Sink<A>\n{\n    public static readonly Sink<A> Default = new SinkEmpty<A>();\n    \n    public override Sink<B> Comap<B>(Func<B, A> f) => \n        new SinkEmpty<B>();\n\n    public override IO<Unit> Post(A value) =>\n        IO.fail<Unit>(Errors.SinkFull);\n\n    public override IO<Unit> Complete() =>\n        unitIO;\n\n    public override IO<Unit> Fail(Error error) =>\n        unitIO;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/DSL/SinkVoid.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord SinkVoid<A> : Sink<A>\n{\n    public static readonly Sink<A> Default = new SinkVoid<A>();\n    \n    public override Sink<B> Comap<B>(Func<B, A> f) => \n        new SinkVoid<B>();\n\n    public override IO<Unit> Post(A value) =>\n        unitIO;\n\n    public override IO<Unit> Complete() =>\n        unitIO;\n\n    public override IO<Unit> Fail(Error error) =>\n        unitIO;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/DSL/SinkWriter.cs",
    "content": "using System;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\n\nnamespace LanguageExt;\n\nrecord SinkWriter<A>(Channel<A> Channel) : Sink<A>\n{\n    public override Sink<B> Comap<B>(Func<B, A> f) => \n        new SinkContraMap<A, B>(f, this);\n\n    public override IO<Unit> Post(A value) =>\n        from f in IO.liftVAsync(e => Channel.Writer.WaitToWriteAsync(e.Token))\n        from r in f ? IO.liftVAsync(() => Channel.Writer.WriteAsync(value).ToUnit())\n                    : IO.fail<Unit>(Errors.SinkFull)\n        select r;\n\n    public override IO<Unit> Complete() =>\n        IO.lift(() => Channel.Writer.Complete());    \n\n    public override IO<Unit> Fail(Error error) =>\n        IO.lift(() => Channel.Writer.Complete(error.ToException()));    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/Sink.CoFunctor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Sink : Decidable<Sink>\n{\n    static K<Sink, A> Cofunctor<Sink>.Comap<A, B>(Func<A, B> f, K<Sink, B> fb) =>\n        fb.As().Comap(f);\n\n    static K<Sink, A> Divisible<Sink>.Divide<A, B, C>(Func<A, (B Left, C Right)> f, K<Sink, B> fb, K<Sink, C> fc) =>\n        new SinkCombine<A, B, C>(f, fb.As(), fc.As());\n\n    static K<Sink, A> Divisible<Sink>.Conquer<A>() =>\n        Sink<A>.Empty;\n\n    static K<Sink, A> Decidable<Sink>.Lose<A>(Func<A, Void> f) =>\n        Sink<A>.Void;\n\n    static K<Sink, A> Decidable<Sink>.Route<A, B, C>(Func<A, Either<B, C>> f, K<Sink, B> fb, K<Sink, C> fc) =>\n        new SinkChoose<A, B, C>(f, fb.As(), fc.As());\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/Sink.Extensions.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class SinkExtensions\n{\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    public static Sink<A> As<A>(this K<Sink, A> ma) =>\n        (Sink<A>)ma;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/Sink.Module.cs",
    "content": "using System.Threading.Channels;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Sink\n{\n    /// <summary>\n    /// Create a sink from a `System.Threading.Channels.Channel`.\n    /// </summary>\n    /// <param name=\"channel\">Channel to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Constructed sink</returns>\n    public static Sink<A> lift<A>(Channel<A> channel) =>\n        new SinkWriter<A>(channel);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Sink/Sink.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Entry point to a channel.  Sinks receive values and propagate them through the\n/// channel they're attached to.  The behaviour depends on the `Buffer` type they\n/// were created with.\n/// </summary>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic abstract record Sink<A> : \n    K<Sink, A>, \n    Monoid<Sink<A>>\n{\n    /// <summary>\n    /// Post a value to the Sink\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.NoSpaceInSink` if the Sink is full or closed.\n    /// </remarks>\n    /// <param name=\"value\">Value to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public abstract IO<Unit> Post(A value);\n    \n    /// <summary>\n    /// Complete and close the Sink\n    /// </summary>\n    public abstract IO<Unit> Complete();\n    \n    /// <summary>\n    /// Complete and close the Sink with an `Error`\n    /// </summary>\n    public abstract IO<Unit> Fail(Error Error);\n\n    /// <summary>\n    /// Contravariant functor map\n    /// </summary>\n    public abstract Sink<X> Comap<X>(Func<X, A> f);\n\n    /// <summary>\n    /// Contravariant functor map\n    /// </summary>\n    public virtual Sink<X> Comap<X>(Transducer<X, A> f) =>\n        new SinkContraMapT<A, X>(f, this);\n\n    /// <summary>\n    /// Combine two Sinks: `lhs` and `rhs` into a single Sink that takes incoming\n    /// values and then posts to the `lhs` and `rhs` Sinks. \n    /// </summary>\n    public Sink<A> Combine(Sink<A> rhs) =>\n        new SinkCombine<A, A, A>(x => (x, x), this, rhs);\n\n    /// <summary>\n    /// Combine two Sinks: `lhs` and `rhs` into a single Sink that takes incoming\n    /// values, maps them to an `(A, B)` tuple, and then posts the first and second\n    /// elements to the `lhs` and `rhs` Sinks. \n    /// </summary>\n    public Sink<X> Combine<X, B>(Func<X, (A Left, B Right)> f, Sink<B> rhs) =>\n        new SinkCombine<X, A, B>(f, this, rhs);\n    \n    /// <summary>\n    /// Combine two Sinks into a single Source.  The values are both\n    /// merged into a new Sink.  \n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side</param>\n    /// <param name=\"rhs\">Right-hand side</param>\n    /// <returns>Merged stream of values</returns>\n    public static Sink<A> operator +(Sink<A> lhs, Sink<A> rhs) =>\n        lhs.Combine(rhs);\n\n    /// <summary>\n    /// Sink that is closed and can't be posted to without an error being raised\n    /// </summary>\n    public static Sink<A> Empty => \n        SinkEmpty<A>.Default;\n\n    /// <summary>\n    /// Sink that swallows everything silently\n    /// </summary>\n    public static Sink<A> Void => \n        SinkVoid<A>.Default;\n\n    /// <summary>\n    /// Convert the `Sink` to a `ConsumerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ConsumerT`</returns>\n    public ConsumerT<A, M, Unit> ToConsumerT<M>()\n        where M : MonadIO<M> =>\n        ConsumerT.repeat(ConsumerT.awaiting<M, A>().Bind(Post));\n\n    /// <summary>\n    /// Convert the `Sink` to a `Consumer` pipe component\n    /// </summary>\n    /// <returns>`Consumer`</returns>\n    public Consumer<RT, A, Unit> ToConsumer<RT>() =>\n        ToConsumerT<Eff<RT>>();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/DSL/SinkChoose.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord SinkTChoose<M, A, B, C>(Func<A, Either<B, C>> F, SinkT<M, B> Left, SinkT<M, C> Right) : SinkT<M, A>\n    where M : MonadIO<M>\n{\n    public override SinkT<M, D> Comap<D>(Func<D, A> f) =>\n        new SinkTContraMap<M, A, D>(f, this);\n\n    public override K<M, Unit> PostM(K<M, A> ma) =>\n        ma.Bind(value =>\n            F(value) switch\n            {\n                Either<B, C>.Left(var left)   => Left.PostM(M.Pure(left)),\n                Either<B, C>.Right(var right) => Right.PostM(M.Pure(right)),\n                _                             => M.LiftIOMaybe(IO.fail<Unit>(Errors.SinkFull))\n            });\n\n    public override K<M, Unit> Complete() =>\n        Left.Complete().Bind(_ => Right.Complete());\n\n    public override K<M, Unit> Fail(Error error) =>\n        Left.Fail(error).Bind(_ => Right.Fail(error));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/DSL/SinkCombine.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord SinkTCombine<M, A, B, C>(Func<A, (B Left, C Right)> F, SinkT<M, B> Left, SinkT<M, C> Right) : SinkT<M, A>\n    where M : MonadIO<M>\n{\n    public override SinkT<M, D> Comap<D>(Func<D, A> f) =>\n        new SinkTContraMap<M, A, D>(f, this);\n\n    public override K<M, Unit> PostM(K<M, A> ma) =>\n        ma.Bind(value =>\n                    F(value) switch\n                    {\n                        var (b, c) =>\n                            awaitAll(Left.PostM(M.Pure(b)).ConstMap(Seq<Error>()), Right.PostM(M.Pure(c)).ConstMap(Seq<Error>()))\n                               .Map(es => es.Flatten())\n                               .Bind(es => es switch\n                                           {\n                                               [] => unitIO,\n                                               _  => IO.fail<Unit>(Error.Many(es))\n                                           })\n                    });\n\n    static K<M, Seq<X>> awaitAll<X>(params K<M, X>[] ms) =>\n        toSeq(ms)\n           .Traverse(M.ToIOMaybe)\n           .Bind(Prelude.awaitAll);\n    \n    public override K<M, Unit> Complete() =>\n        Left.Complete().Bind(_ => Right.Complete());\n\n    public override K<M, Unit> Fail(Error error) =>\n        Left.Fail(error).Bind(_ => Right.Fail(error));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/DSL/SinkContraMap.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord SinkTContraMap<M, A, B>(Func<B, A> F, SinkT<M, A> Sink) : SinkT<M, B>\n    where M : MonadIO<M>\n{\n    public override SinkT<M, C> Comap<C>(Func<C, B> f) =>\n        new SinkTContraMap<M, A, C>(x => F(f(x)), Sink);\n\n    public override K<M, Unit> PostM(K<M, B> ma) => \n        Sink.PostM(ma.Map(F));\n\n    public override K<M, Unit> Complete() => \n        Sink.Complete();\n\n    public override K<M, Unit> Fail(Error Error) => \n        Sink.Fail(Error);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/DSL/SinkContraMapT.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord SinkTContraMapT<M, A, B>(TransducerM<M, B, A> F, SinkT<M, A> Sink) : SinkT<M, B>\n    where M : MonadIO<M>\n{\n    public override SinkT<M, C> Comap<C>(Func<C, B> f) =>\n        new SinkTContraMapT<M, A, C>(TransducerM.map<M, C, B>(f).Compose(F), Sink);\n\n    public override SinkT<M, C> Comap<C>(TransducerM<M, C, B> f) => \n        new SinkTContraMapT<M, A, C>(f.Compose(F), Sink);\n\n    public override K<M, Unit> PostM(K<M, B> mb) =>\n        mb.Bind(b => F.Reduce<Unit>((_, a) => Sink.PostM(M.Pure(a)) * Reduced.Continue)(unit, b))\n          .Map(r => r.Value);\n\n    public override K<M, Unit> Complete() => \n        Sink.Complete();\n\n    public override K<M, Unit> Fail(Error Error) => \n        Sink.Fail(Error);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/DSL/SinkEmpty.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord SinkTEmpty<M, A> : SinkT<M, A>\n    where M : MonadIO<M>\n{\n    public static readonly SinkT<M, A> Default = new SinkTEmpty<M, A>();\n    \n    public override SinkT<M, B> Comap<B>(Func<B, A> f) => \n        SinkTEmpty<M, B>.Default;\n\n    public override K<M, Unit> PostM(K<M, A> ma) =>\n        M.LiftIOMaybe(IO.fail<Unit>(Errors.SinkFull));\n\n    public override K<M, Unit> Complete() =>\n        M.Pure(unit);\n\n    public override K<M, Unit> Fail(Error error) =>\n        M.Pure(unit);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/DSL/SinkVoid.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord SinkTVoid<M, A> : SinkT<M, A>\n    where M : MonadIO<M>\n{\n    public static readonly SinkT<M, A> Default = new SinkTVoid<M, A>();\n    \n    public override SinkT<M, B> Comap<B>(Func<B, A> f) => \n        SinkTVoid<M, B>.Default;\n\n    public override K<M, Unit> PostM(K<M, A> ma) =>\n        M.Pure(unit);\n\n    public override K<M, Unit> Complete() =>\n        M.Pure(unit);\n\n    public override K<M, Unit> Fail(Error error) =>\n        M.Pure(unit);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/DSL/SinkWriter.cs",
    "content": "using System;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord SinkTWriter<M, A>(Channel<K<M, A>> Channel) : SinkT<M, A>\n    where M : MonadIO<M>\n{\n    public override SinkT<M, B> Comap<B>(Func<B, A> f) => \n        new SinkTContraMap<M, A, B>(f, this);\n\n    public override K<M, Unit> PostM(K<M, A> ma) =>\n        M.LiftIOMaybe(from f in IO.liftVAsync(e => Channel.Writer.WaitToWriteAsync(e.Token))\n                 from r in f\n                               ? IO.liftVAsync(() => Channel.Writer.WriteAsync(ma).ToUnit())\n                               : IO.fail<Unit>(Errors.SinkFull)\n                 select r);\n\n    public override K<M, Unit> Complete() =>\n        M.LiftIOMaybe(IO.lift(() => Channel.Writer.Complete()));    \n\n    public override K<M, Unit> Fail(Error error) =>\n        M.LiftIOMaybe(IO.lift(() => Channel.Writer.Complete(error.ToException())));    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/SinkT.CoFunctor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class SinkT<M> : Decidable<SinkT<M>>\n    where M : MonadIO<M>\n{\n    static K<SinkT<M>, A> Cofunctor<SinkT<M>>.Comap<A, B>(Func<A, B> f, K<SinkT<M>, B> fb) =>\n        fb.As().Comap(f);\n\n    static K<SinkT<M>, A> Divisible<SinkT<M>>.Divide<A, B, C>(Func<A, (B Left, C Right)> f, K<SinkT<M>, B> fb, K<SinkT<M>, C> fc) =>\n        new SinkTCombine<M, A, B, C>(f, fb.As(), fc.As());\n\n    static K<SinkT<M>, A> Divisible<SinkT<M>>.Conquer<A>() =>\n        SinkT<M, A>.Empty;\n\n    static K<SinkT<M>, A> Decidable<SinkT<M>>.Lose<A>(Func<A, Void> f) =>\n        SinkT<M, A>.Void;\n\n    static K<SinkT<M>, A> Decidable<SinkT<M>>.Route<A, B, C>(Func<A, Either<B, C>> f, K<SinkT<M>, B> fb, K<SinkT<M>, C> fc) =>\n        new SinkTChoose<M, A, B, C>(f, fb.As(), fc.As());\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/SinkT.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class SinkTExtensions\n{\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    public static SinkT<M, A> As<M, A>(this K<SinkT<M>, A> ma) \n        where M : MonadIO<M> =>\n        (SinkT<M, A>)ma;\n    \n    /// <summary>\n    /// Convert the `Sink` to a `Consumer` pipe component\n    /// </summary>\n    /// <returns>`Consumer`</returns>\n    public static Consumer<RT, A, Unit> ToConsumer<RT, A>(this SinkT<Eff<RT>, A> ma) =>\n        ma.ToConsumerT();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/SinkT.Module.cs",
    "content": "using System.Threading.Channels;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class SinkT\n{\n    /// <summary>\n    /// Create a sink from a `System.Threading.Channels.Channel`.\n    /// </summary>\n    /// <param name=\"channel\">Channel to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Constructed sink</returns>\n    public static SinkT<M, A> lift<M, A>(Channel<K<M, A>> channel) \n        where M : MonadIO<M> =>\n        new SinkTWriter<M, A>(channel);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SinkT/SinkT.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Entry point to a channel.  Sinks receive values and propagate them through the\n/// channel they're attached to.  The behaviour depends on the `Buffer` type they\n/// were created with.\n/// </summary>\n/// <typeparam name=\"M\">Lifted type</typeparam>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic abstract record SinkT<M, A> : \n    K<SinkT<M>, A>, \n    Monoid<SinkT<M, A>>\n    where M : MonadIO<M>\n{\n    /// <summary>\n    /// Post a value to the sink\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.NoSpaceInSink` if the sink is full or closed.\n    /// </remarks>\n    /// <param name=\"ma\">Value to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public abstract K<M, Unit> PostM(K<M, A> ma);\n    \n    /// <summary>\n    /// Post a value to the sink\n    /// </summary>\n    /// <remarks>\n    /// Raises `Errors.NoSpaceInSink` if the sink is full or closed.\n    /// </remarks>\n    /// <param name=\"value\">Value to post</param>\n    /// <returns>IO computation that represents the posting</returns>\n    public K<M, Unit> Post(A value) =>\n        PostM(M.Pure(value));\n    \n    /// <summary>\n    /// Complete and close the sink\n    /// </summary>\n    public abstract K<M, Unit> Complete();\n    \n    /// <summary>\n    /// Complete and close the sink with an `Error`\n    /// </summary>\n    public abstract K<M, Unit> Fail(Error Error);\n\n    /// <summary>\n    /// Contravariant functor map\n    /// </summary>\n    public abstract SinkT<M, X> Comap<X>(Func<X, A> f);\n\n    /// <summary>\n    /// Contravariant functor map\n    /// </summary>\n    public virtual SinkT<M, X> Comap<X>(TransducerM<M, X, A> f) =>\n        new SinkTContraMapT<M, A, X>(f, this);\n\n    /// <summary>\n    /// Combine two Sinks: `lhs` and `rhs` into a single Sink that takes incoming\n    /// values and then posts to the `lhs` and `rhs` Sinks. \n    /// </summary>\n    public SinkT<M, A> Combine(SinkT<M, A> rhs) =>\n        new SinkTCombine<M, A, A, A>(x => (x, x), this, rhs);\n\n    /// <summary>\n    /// Combine two Sinks: `lhs` and `rhs` into a single Sink that takes incoming\n    /// values, maps them to an `(A, B)` tuple, and then posts the first and second\n    /// elements to the `lhs` and `rhs` Sinks. \n    /// </summary>\n    public SinkT<M, X> Combine<X, B>(SinkT<M, B> rhs, Func<X, (A Left, B Right)> f) =>\n        new SinkTCombine<M, X, A, B>(f, this, rhs);\n    \n    /// <summary>\n    /// Combine two Sinks into a single Source.  The values are both\n    /// merged into a new Sink.  \n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side</param>\n    /// <param name=\"rhs\">Right-hand side</param>\n    /// <returns>Merged stream of values</returns>\n    public static SinkT<M, A> operator +(SinkT<M, A> lhs, SinkT<M, A> rhs) =>\n        lhs.Combine(rhs);\n\n    /// <summary>\n    /// Sink that is closed and can't be posted to without an error being raised\n    /// </summary>\n    public static SinkT<M, A> Empty => \n        SinkTEmpty<M, A>.Default;\n\n    /// <summary>\n    /// Sink that swallows everything silently\n    /// </summary>\n    public static SinkT<M, A> Void => \n        SinkTVoid<M, A>.Default;\n\n    /// <summary>\n    /// Convert the `Sink` to a `ConsumerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ConsumerT`</returns>\n    public ConsumerT<A, M, Unit> ToConsumerT() =>\n        ConsumerT.repeat(ConsumerT.awaiting<M, A>().Bind(x => PostM(M.Pure(x))));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Extensions/Source.Extensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Channels;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    public static Source<A> As<A>(this K<Source, A> ma) =>\n        (Source<A>)ma;\n    \n    [Pure]\n    public static Source<A> AsSource<A>(this Channel<A> items) =>\n        Source.lift(items);\n\n    [Pure]\n    public static Source<A> AsSource<A>(this IEnumerable<A> items) =>\n        Source.lift(items);\n    \n    [Pure]\n    public static Source<A> AsSource<A>(this IAsyncEnumerable<A> items) =>\n        Source.lift(items);\n    \n    [Pure]\n    public static Source<A> AsSource<A>(this IObservable<A> items) =>\n        Source.lift(items);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Extensions/Source.Reducers.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Channels;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    /// <summary>\n    /// Force iteration of the stream, yielding a unit `M` structure.\n    /// </summary>\n    /// <remarks>\n    /// The expectation is that the stream uses `IO` for side effects, so this makes them to happen.\n    /// </remarks>\n    public static IO<Unit> Iter<A>(this K<Source, A> ma) =>\n        ma.As().ReduceIO(unit, (_, _) => Reduced.ContinueIO(unit));\n    \n    /// <summary>\n    /// Force iteration of the stream, yielding a unit `M` structure.\n    /// </summary>\n    /// <remarks>\n    /// The expectation is that the stream uses `IO` for side effects, so this makes them to happen.\n    /// </remarks>\n    public static K<M, Unit> Iter<M, A>(this K<Source, A> ma) \n        where M : MonadIO<M> =>\n        M.LiftIOMaybe(ma.Iter());\n\n    /// <summary>\n    /// Force iteration of the stream, yielding the last structure processed\n    /// </summary>\n    public static IO<A> Last<A>(this K<Source, A> ma) =>\n        ma.As()\n          .ReduceIO(Option<A>.None, (_, x) => Reduced.ContinueIO(Some(x)))\n          .Bind(ma => ma switch\n                      {\n                          { IsSome: true, Case: A value } => IO.pure(value),\n                          _                               => IO.empty<A>()\n                      });\n\n    /// <summary>\n    /// Force iteration of the stream, yielding the last structure processed\n    /// </summary>\n    public static K<M, A> Last<M, A>(this K<Source, A> ma)\n        where M : MonadIO<M> =>\n        M.LiftIOMaybe(ma.Last());\n\n    /// <summary>\n    /// Force iteration of the stream and collect all the values into a `Seq`.\n    /// </summary>\n    public static IO<Seq<A>> Collect<A>(this K<Source, A> ma) =>\n        ma.As().ReduceIO<Seq<A>>([], (xs, x) => Reduced.ContinueIO(xs.Add(x)));\n    \n    /// <summary>\n    /// Force iteration of the stream and collect all the values into a `Seq`.\n    /// </summary>\n    public static K<M, Seq<A>> Collect<M, A>(this K<Source, A> ma)\n        where M : MonadIO<M> =>\n        M.LiftIOMaybe(ma.Collect());    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Operators/Source.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    extension<A, B>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static Source<B> operator >>> (K<Source, A> ma, K<Source, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<B> operator * (K<Source, Func<A, B>> mf, K<Source, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<B> operator * (K<Source, A> ma, K<Source, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<A, B, C>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, C>> operator * (\n            K<Source, Func<A, B, C>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, C>> operator * (\n            K<Source, A> ma,\n            K<Source, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<A, B, C, D>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, D>>> operator * (\n            K<Source, Func<A, B, C, D>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, D>>> operator * (\n            K<Source, A> ma,\n            K<Source, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Source, Func<A, B, C, D, E>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Source, A> ma,\n            K<Source, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Source, Func<A, B, C, D, E, F>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Source, A> ma,\n            K<Source, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Source, Func<A, B, C, D, E, F, G>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Source, A> ma,\n            K<Source, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G, H>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Source, Func<A, B, C, D, E, F, G, H>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Source, A> ma,\n            K<Source, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Source, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Source, A> ma,\n            K<Source, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Source, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Source, A> ma,\n            K<Source, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Source, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<Source, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<Source, A> ma,\n            K<Source, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Operators/Source.Operators.Choice.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    extension<A>(K<Source, A> self)\n    {\n        public static Source<A> operator |(K<Source, A> lhs, K<Source, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static Source<A> operator |(K<Source, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(Source.pure(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Operators/Source.Operators.Combine.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    extension<A>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Source<A> operator +(K<Source, A> lhs, K<Source, A> rhs) =>\n            +lhs.Combine(rhs);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static Source<A> operator +(K<Source, A> lhs, Pure<A> rhs) =>\n            +lhs.Combine(Source.pure(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Operators/Source.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    extension<A, B>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<B> operator *(Func<A, B> f, K<Source, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<B> operator *(K<Source, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<A, B, C>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, C>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<A, B, C, D>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, D>>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<A, B, C, D, E>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, E>>>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<A, B, C, D, E, F>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<A, B, C, D, E, F, G>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<A, B, C, D, E, F, G, H, I>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<A, B, C, D, E, F, G, H, I, J>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<A, B, C, D, E, F, G, H, I, J, K>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<Source, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static Source<Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<Source, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Operators/Source.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    extension<A, B>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static Source<B> operator >> (K<Source, A> ma, Func<A, K<Source, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static Source<B> operator >> (K<Source, A> lhs, K<Source, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<A>(K<Source, A> self)\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static Source<A> operator >> (K<Source, A> lhs, K<Source, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Operators/Source.Operators.Zip.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    extension<A, B>(K<Source, A>)\n    {\n        public static Source<(A First, B Second)> operator &(K<Source, A> lhs, K<Source, B> rhs) =>\n            +lhs.Zip(rhs);\n    }\n    \n    extension<A, B, C>(K<Source, (A First, B Second)>)\n    {\n        public static Source<(A First, B Second, C Third)> operator &(K<Source, (A First, B Second)> lhs, K<Source, C> rhs) =>\n            +lhs.Zip(rhs).Map(s => (s.First.First, s.First.Second, s.Second));\n    }    \n    \n    extension<A, B, C, D>(K<Source, (A First, B Second)>)\n    {\n        public static Source<(A First, B Second, C Third, D Fourth)> operator &(K<Source, (A First, B Second)> lhs, K<Source, (C First, D Second)> rhs) =>\n            +lhs.Zip(rhs).Map(s => (s.First.First, s.First.Second, s.Second.First, s.Second.Second));\n    }    \n    \n    extension<A, B, C, D>(K<Source, (A First, B Second, C Third)>)\n    {\n        public static Source<(A First, B Second, C Third, D Fourth)> operator &(K<Source, (A First, B Second, C Third)> lhs, K<Source, D> rhs) =>\n            +lhs.Zip(rhs).Map(s => (s.First.First, s.First.Second, s.First.Third, s.Second));\n    }\n}\n\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Operators/Source.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    extension<A>(K<Source, A> _)\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Source<A> operator +(K<Source, A> ma) =>\n            (Source<A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static Source<A> operator >> (K<Source, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Source.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Channels;\nusing static LanguageExt.Prelude;\nnamespace LanguageExt;\n\npublic partial class Source\n{\n    /// <summary>\n    /// Empty source\n    /// </summary>\n    /// <remarks>\n    /// This is a 'void' source, it yields zero values. \n    /// </remarks>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Uninhabited source</returns>\n    public static Source<A> empty<A>() =>\n        Source<A>.Empty;\n    \n    /// <summary>\n    /// Lift a pure value into the source\n    /// </summary>\n    /// <remarks>\n    /// This is a singleton/unit source, it yields exactly one value. \n    /// </remarks>\n    /// <param name=\"value\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Singleton source</returns>\n    public static Source<A> pure<A>(A value) =>\n        new (SourceT.pure<IO, A>(value));\n\n    /// <summary>\n    /// Lift a pure value into the source and yield it for infinity\n    /// </summary>\n    /// <remarks>\n    /// This is an infinite source, it repeatedly yields a value. \n    /// </remarks>\n    /// <param name=\"value\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Infinite source</returns>\n    public static Source<A> forever<A>(A value) =>\n        new(SourceT.forever<IO, A>(value));\n\n    /// <summary>\n    /// Make a `System.Threading.Channels.Channel` into a source of values\n    /// </summary>\n    /// <param name=\"channel\">Channel to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    public static Source<A> lift<A>(Channel<A> channel) =>\n        new(SourceT.lift<IO, A>(channel));\n\n    /// <summary>\n    /// Make an `IEnumerable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">`IEnumerable` to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    public static Source<A> lift<A>(IEnumerable<A> items) =>\n        new(SourceT.lift<IO, A>(items));\n\n    /// <summary>\n    /// Make an `IAsyncEnumerable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">`IAsyncEnumerable` to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    public static Source<A> lift<A>(IAsyncEnumerable<A> items) =>\n        new(SourceT.lift<IO, A>(items));\n\n    /// <summary>\n    /// Make an `IObservable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">`IObservable` to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    public static Source<A> lift<A>(IObservable<A> items) =>\n        new(SourceT.lift<IO, A>(items));\n    \n    /// <summary>\n    /// Merge sources into a single source\n    /// </summary>\n    /// <param name=\"sources\">Sources</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Source that is the combination of all provided sources</returns>\n    public static Source<A> merge<A>(Seq<Source<A>> sources) =>\n        new(SourceT.merge(sources.Map(s => s.runSource)));\n        \n    /// <summary>\n    /// Merge sources into a single source\n    /// </summary>\n    /// <param name=\"sources\">Sources</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Source that is the combination of all provided sources</returns>\n    public static Source<A> merge<A>(params Source<A>[] sources) =>\n        merge(toSeq(sources));\n\n    /// <summary>\n    /// Zip two sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    public Source<(A First, B Second)> zip<A, B>(Source<A> first, Source<B> second) =>\n        new(SourceT.zip(first.runSource, second.runSource));\n\n    /// <summary>\n    /// Zip three sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <param name=\"third\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    public Source<(A First, B Second, C Third)> zip<A, B, C>(Source<A> first, Source<B> second, Source<C> third) =>\n        new(SourceT.zip(first.runSource, second.runSource, third.runSource));\n\n    /// <summary>\n    /// Zip three sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <param name=\"third\">Stream to zip with this one</param>\n    /// <param name=\"fourth\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    public Source<(A First, B Second, C Third, D Fourth)> zip<A, B, C, D>(Source<A> first, Source<B> second, Source<C> third, Source<D> fourth) =>\n        new(SourceT.zip(first.runSource, second.runSource, third.runSource, fourth.runSource));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Source.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A source / stream of values\n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic readonly record struct Source<A>(SourceT<IO, A> runSource) : \n    K<Source, A>, \n    Monoid<Source<A>>\n{\n    /// <summary>\n    /// A source that never yields a value\n    /// </summary>\n    public static Source<A> Empty =>\n        new (SourceT<IO, A>.Empty);\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public IO<S> FoldReduce<S>(S state, Func<S, A, S> reducer) =>\n        +runSource.FoldReduce(state, reducer);\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public IO<S> Reduce<S>(S state, Reducer<A, S> reducer) =>\n        +runSource.Reduce(state, reducer);\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public IO<S> ReduceIO<S>(S state, ReducerIO<A, S> reducer) =>\n        +runSource.ReduceM(state, (s, v) => reducer(s, v));\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.   \n    /// </summary>\n    /// <param name=\"state\">State to reduce</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Reduced state</returns>\n    public IO<S> ReduceM<S>(S state, ReducerIO<A, S> reducer) =>\n        +runSource.ReduceM(state, (s, v) => reducer(s, v));\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public Source<B> Map<B>(Func<A, B> f) =>\n        new(runSource.Map(f));\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public Source<B> Bind<B>(Func<A, Source<B>> f) =>\n        new(runSource.Bind(x => f(x).runSource));\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public Source<B> Bind<B>(Func<A, K<Source, B>> f) =>\n        new(runSource.Bind(x => f(x).As().runSource));\n\n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>Source where the only values yield are those that pass the predicate</returns>\n    public Source<A> Where(Func<A, bool> f) =>\n        new(runSource.Where(f));\n\n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>Source where the only values yield are those that pass the predicate</returns>\n    public Source<A> Filter(Func<A, bool> f) =>\n        new(runSource.Filter(f));\n\n    /// <summary>\n    /// Applicative apply\n    /// </summary>\n    public Source<B> ApplyBack<B>(Source<Func<A, B>> ff) =>\n        new(runSource.ApplyBack(ff.runSource));\n\n    /// <summary>\n    /// Concatenate two sources into a single source.\n    /// </summary>\n    /// <param name=\"lhs\">Left-hand side</param>\n    /// <param name=\"rhs\">Right-hand side</param>\n    /// <returns>Concatenated stream of values</returns>\n    public Source<A> Combine(Source<A> rhs) =>\n        new(runSource.Combine(rhs.runSource));\n\n    /// <summary>\n    /// The value streams are both merged into a new stream.  Values are yielded\n    /// as they become available.\n    /// </summary>\n    /// <param name=\"this\">Left-hand side</param>\n    /// <param name=\"rhs\">Right-hand side</param>\n    /// <returns>Merged stream</returns>\n    public Source<A> Choose(Source<A> rhs) =>\n        new(runSource.Choose(rhs.runSource));\n\n    /// <summary>\n    /// The value streams are both merged into a new stream.  Values are yielded\n    /// as they become available.\n    /// </summary>\n    /// <param name=\"this\">Left-hand side</param>\n    /// <param name=\"rhs\">Right-hand side</param>\n    /// <returns>Merged stream</returns>\n    public Source<A> Choose(Memo<Source, A> rhs) =>\n        new(runSource.Choose(rhs.Lower().Value.As().runSource));\n    \n    /// <summary>\n    /// Zip two sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    public Source<(A First, B Second)> Zip<B>(Source<B> second) =>\n        new (runSource.Zip(second.runSource));\n\n    /// <summary>\n    /// Zip three sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <param name=\"third\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    public Source<(A First, B Second, C Third)> Zip<B, C>(Source<B> second, Source<C> third) =>\n        new (runSource.Zip(second.runSource, third.runSource));\n\n    /// <summary>\n    /// Zip three sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <param name=\"third\">Stream to zip with this one</param>\n    /// <param name=\"fourth\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    public Source<(A First, B Second, C Third, D Fourth)> Zip<B, C, D>(Source<B> second, Source<C> third, Source<D> fourth) =>\n        new (runSource.Zip(second.runSource, third.runSource, fourth.runSource));\n\n    /// <summary>\n    /// Skip items in the source\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>Transformed source</returns>\n    public Source<A> Skip(int amount) =>\n        new (runSource.Skip(amount));\n\n    /// <summary>\n    /// Limit the number of items processed\n    /// </summary>\n    /// <param name=\"amount\">Amount to take</param>\n    /// <returns>Transformed source</returns>\n    public Source<A> Take(int amount) =>\n        new (runSource.Take(amount));\n\n    /// <summary>\n    /// Fold the values flowing through.  A value is only yielded downstream upon completion of the stream.\n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate state</returns>\n    public Source<S> Fold<S>(Func<S, A, S> Fold, S Init) =>\n        new (runSource.Fold(Fold, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, or the\n    /// source completes.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public Source<S> Fold<S>(Schedule Time, Func<S, A, S> Fold, S Init) =>\n        new (runSource.Fold(Time, Fold, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `false`, or the source completes.\n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public Source<S> FoldWhile<S>(Func<S, A, S> Fold, Func<(S State, A Value), bool> Pred, S Init) =>\n        new (runSource.FoldWhile(Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `true`, or the source completes.\n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public Source<S> FoldUntil<S>(Func<S, A, S> Fold, Func<(S State, A Value), bool> Pred, S Init) =>\n        new(runSource.FoldUntil(Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `false`, or the source completes.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public Source<S> FoldWhile<S>(\n        Schedule Time,\n        Func<S, A, S> Fold,\n        Func<(S State, A Value), bool> Pred,\n        S Init) =>\n        new (runSource.FoldWhile(Time, Fold, Pred, Init));\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `true`, or the source completes.\n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\"></typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public Source<S> FoldUntil<S>(\n        Schedule Time,\n        Func<S, A, S> Fold,\n        Func<(S State, A Value), bool> Pred,\n        S Init) =>\n        new (runSource.FoldUntil(Time, Fold, Pred, Init));\n\n    /// <summary>\n    /// Transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Transformed source</returns>\n    public Source<B> Transform<B>(Transducer<A, B> transducer) =>\n        new(runSource.Transform(transducer));\n\n    /// <summary>\n    /// Transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Transformed source</returns>\n    public Source<B> Transform<B>(TransducerM<IO, A, B> transducer) =>\n        new(runSource.Transform(transducer));\n    \n    /// <summary>\n    /// Convert `Source` to a `ProducerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ProducerT`</returns>\n    public ProducerT<A, M, Unit> ToProducerT<M>()\n        where M : MonadIO<M> =>\n        ProducerT.yieldAll<M, A>(this);\n\n    /// <summary>\n    /// Convert `Source` to a `Producer` pipe component\n    /// </summary>\n    /// <returns>`Producer`</returns>\n    public Producer<RT, A, Unit> ToProducer<RT>() =>\n        ToProducerT<Eff<RT>>();\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public Source<B> Select<B>(Func<A, B> f) =>\n        Map(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public Source<C> SelectMany<B, C>(Func<A, Source<B>> bind, Func<A, B, C> project) =>\n        Bind(a => bind(a).Map(b => project(a, b)));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Source/Trait/Source.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class Source : \n    Monad<Source>, \n    MonoidK<Source>,\n    Alternative<Source>\n{\n    static K<Source, B> Monad<Source>.Bind<A, B>(K<Source, A> ma, Func<A, K<Source, B>> f) => \n        ma.As().Bind(f);\n\n    static K<Source, B> Monad<Source>.Recur<A, B>(A value, Func<A, K<Source, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<Source, B> Functor<Source>.Map<A, B>(Func<A, B> f, K<Source, A> ma) => \n        ma.As().Map(f);\n\n    static K<Source, A> Applicative<Source>.Pure<A>(A value) =>\n        new Source<A>(SourceT.pure<IO, A>(value));\n\n    static K<Source, B> Applicative<Source>.Apply<A, B>(K<Source, Func<A, B>> mf, K<Source, A> ma) => \n        ma.As().ApplyBack(mf.As());\n\n    static K<Source, B> Applicative<Source>.Apply<A, B>(K<Source, Func<A, B>> mf, Memo<Source, A> ma) =>\n        ma.Value.As().ApplyBack(mf.As());\n\n    static K<Source, A> SemigroupK<Source>.Combine<A>(K<Source, A> fa, K<Source, A> fb) =>\n        fa.As().Combine(fb.As());\n\n    static K<Source, A> Choice<Source>.Choose<A>(K<Source, A> fa, K<Source, A> fb) =>\n        fa.As().Choose(fb.As());\n\n    public static K<Source, A> Choose<A>(K<Source, A> fa, Memo<Source, A> fb) => \n        fa.As().Choose(fb);\n\n    static K<Source, A> Alternative<Source>.Empty<A>() =>\n        Source<A>.Empty;\n\n    static K<Source, A> MonoidK<Source>.Empty<A>() =>\n        Source<A>.Empty;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/ApplySourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/*\nrecord ApplySourceT<M, A, B>(SourceT<M, Func<A, B>> FF, SourceT<M, A> FA) : SourceT<M, B>\n    where M : MonadIO<M>, Fallible<M>\n{\n    public override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, B>, S> reducer) =>\n        new Zip2SourceT<M, Func<A, B>, A>(FF, FA).Map(p => p.First(p.Second)).ReduceInternalM(state, reducer);\n}\n\nrecord ApplySourceT2<M, A, B>(SourceT<M, Func<A, B>> FF, Memo<SourceT<M>, A> FA) : SourceT<M, B>\n    where M : MonadIO<M>, Fallible<M>\n{\n    public override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, B>, S> reducer) =>\n        new Zip2SourceT<M, Func<A, B>, A>(FF, FA.Value.As()).Map(p => p.First(p.Second)).ReduceInternalM(state, reducer);\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/BindSourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord BindSourceT<M, A, B>(SourceT<M, A> Source, Func<A, SourceT<M, B>> F) : SourceT<M, B>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, B>, S> reducer) => \n        Source.ReduceInternalM(state, (s, mx) => mx.Bind(x => F(x).ReduceInternalM(s, reducer)));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/ChooseSourceT.cs",
    "content": "using System;\nusing System.Threading;\nusing LanguageExt.Traits;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord ChooseSourceT<M, A>(Seq<SourceT<M, A>> Sources) : SourceT<M, A>\n    where M : MonadIO<M>, Fallible<M> \n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) =>\n        M.BracketIOMaybe(\n            \n            // Get our environment\n            from envIO  in IO.token\n\n            // Create a channel for the merged streams\n            from channel in M.Pure(Channel.CreateUnbounded<K<M, A>>())\n            let writer = channel.Writer\n\n            // For each stream, reduce it (which writes to the merged stream), fork it, and return\n            // This gives us K<M, A> that we can't run directly, so we must bind it...\n            from signal in useMaybe(Signal.countdown<M>(Sources.Count))\n            let trigger = trigger(signal, writer)\n            let error   = error(signal, writer)\n            \n            from forks  in useMaybe(Sources.Map(s => s.ReduceInternalM(unit, (_, ma) => M.Pure(writeAsync(writer, ma)))\n                                                      .Bind(_ => trigger)\n                                                      .Catch(error)\n                                                      .ForkIOMaybe())\n                                           .Sequence()\n                                           .Map(ForkRelease.New))\n\n            // Reduce the merged stream\n            from result in SourceT.liftM<M, A>(channel).ReduceInternalM(state, reducer)\n            \n            // Make sure the forks are shutdown\n            from _      in forks.Cancel()\n\n            select result);\n\n    static Func<Error, K<M, Unit>> error(CountdownSignal<M> signal, ChannelWriter<K<M, A>> writer) =>\n        err => signal.Count\n                     .Bind(signal.Trigger)\n                     .Map(_ => writer.TryComplete())\n                     .Bind(_ => M.Fail<Unit>(err));\n\n    static K<M, Unit> trigger(CountdownSignal<M> signal, ChannelWriter<K<M, A>> writer) =>\n        // Mark channel completed if all sources are complete\n        (f => ignore(f && writer.TryComplete())) * signal.Trigger();\n\n    static Reduced<Unit> writeAsync<X>(ChannelWriter<K<M, X>> writer, K<M, X> value) =>\n        writer.TryWrite(value)\n            ? Reduced.Unit\n            : Reduced.Done(unit);\n\n    class ForkRelease(K<Seq, ForkIO<Unit>> Forks) : IDisposable\n    {\n        int disposed;\n        public static ForkRelease New(K<Seq, ForkIO<Unit>> forks) =>\n            new (forks);\n\n        public IO<Unit> Cancel() =>\n            IO.lift(e =>\n                    {\n                        if (Interlocked.CompareExchange(ref disposed, 1, 0) == 0)\n                        {\n                            foreach (var fork in +Forks)\n                            {\n                                fork.Cancel.Run(e);\n                            }\n                        }\n                        return unit;\n                    });\n\n        public void Dispose() =>\n            Cancel().Run();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/CombineSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord CombineSourceT<M, A>(Seq<SourceT<M, A>> Sources) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer)  \n    {\n        return go(state, Sources);\n        K<M, Reduced<S>> go(S state, Seq<SourceT<M, A>> sources) =>\n            sources.Tail.IsEmpty\n                ? sources[0].ReduceInternalM(state, reducer)\n                : sources[0].ReduceInternalM(state, reducer)\n                            .Bind(ns => ns.Continue ? go(ns.Value, sources.Tail) : M.Pure(ns));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/DoneSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord DoneSourceT<M> : SourceT<M, Unit>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, Unit>, S> reducer) => \n        M.Pure(Reduced.Done(state));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/EmptySourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord EmptySourceT<M, A> : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    public static readonly SourceT<M, A> Default = new EmptySourceT<M, A>();\n\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) => \n        M.Pure(Reduced.Done(state));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/FilterSourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FilterSourceT<M, A>(SourceT<M, A> Source, Func<A, bool> Predicate) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) => \n        Source.ReduceInternal(state, \n                              (s, x) => Predicate(x) \n                                            ? reducer(s, M.Pure(x)) \n                                            : M.Pure(Reduced.Continue(s)));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/FoldUntilSourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FoldUntilSourceT<M, A, S>(\n    SourceT<M, A> Source,\n    Schedule Schedule,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Pred,\n    S State) : SourceT<M, S>\n    where M : MonadIO<M>\n{\n    // TODO: Schedule\n    internal override K<M, Reduced<S1>> ReduceInternalM<S1>(S1 state, ReducerM<M, K<M, S>, S1> reducer) =>\n        Source.ReduceInternalM((FState: State, IState: state),\n                               (rs, ma) => from a in ma\n                                           let ns = Folder(rs.FState, a)\n                                           from r in Pred((ns, a))\n                                                         ? reducer(rs.IState, M.Pure(ns)).Map(s1 => s1.Map(s2 => (ns, s2)))\n                                                         : M.Pure(Reduced.Continue((ns, rs.IState)))\n                                           select r)\n              .Map(s => s.Map(s1 => s1.IState));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/FoldWhileSourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FoldWhileSourceT<M, A, S>(\n    SourceT<M, A> Source,\n    Schedule Schedule,\n    Func<S, A, S> Folder,\n    Func<(S State, A Value), bool> Pred,\n    S State) : SourceT<M, S>\n    where M : MonadIO<M>\n{\n    // TODO: Schedule\n    internal override K<M, Reduced<S1>> ReduceInternalM<S1>(S1 state, ReducerM<M, K<M, S>, S1> reducer) =>\n        Source.ReduceInternalM((FState: State, IState: state),\n                               (s, ma) =>\n                                   ma >> (a => Pred((s.FState, a))\n                                                    ? M.Pure(Reduced.Continue((Folder(s.FState, a), s.IState)))\n                                                    : reducer(s.IState, M.Pure(s.FState))\n                                                        .Map(s1 => s1.Map(s2 => (s.FState, s2)))))\n              .Map(s => s.Map(s1 => s1.IState));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/FoldablePureSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FoldablePureSourceT<F, M, A>(K<F, A> Items) : SourceT<M, A>\n    where M : MonadIO<M>\n    where F : Foldable<F>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer)\n    {\n        return steps() >> (f => Monad.recur(f, go));\n\n        IO<Fold<A, S>> steps() =>\n            // Needs to remain lazy\n            IO.lift(e => Items.FoldStep(state));\n        \n        K<M, Next<Fold<A, S>, Reduced<S>>> go(Fold<A, S> fold) =>\n            IO.token.Bind(t => t.IsCancellationRequested\n                                   ? done(state)\n                                   : fold switch\n                                     {\n                                         Fold<A, S>.Done(var s) =>\n                                             done(s),\n\n                                         Fold<A, S>.Loop(var s, var a, var n) =>\n                                             reducer(s, M.Pure(a)) *\n                                             (ns => ns.Continue\n                                                        ? next(n(ns.Value))\n                                                        : reduced(ns))\n                                     });\n\n        K<M, Next<Fold<A, S>, Reduced<S>>> done(S state) =>\n            M.Pure(reduced(Reduced.Done(state)));\n\n        Next<Fold<A, S>, Reduced<S>> reduced(Reduced<S> reduced) =>\n            Next.Done<Fold<A, S>, Reduced<S>>(reduced);\n\n        Next<Fold<A, S>, Reduced<S>> next(Fold<A, S> tail) =>\n            Next.Loop<Fold<A, S>, Reduced<S>>(tail);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/FoldableSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FoldableSourceT<F, M, A>(K<F, K<M, A>> Items) : SourceT<M, A>\n    where M : MonadIO<M>\n    where F : Foldable<F>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer)\n    {\n        return steps() >> (f => Monad.recur(f, go));\n\n        IO<Fold<K<M, A>, S>> steps() =>\n            // Needs to remain lazy\n            IO.lift(e => Items.FoldStep(state));\n\n        K<M, Next<Fold<K<M, A>, S>, Reduced<S>>> go(Fold<K<M, A>, S> fold) =>\n            IO.token.Bind(t => t.IsCancellationRequested\n                                   ? done(state)\n                                   : fold switch\n                                     {\n                                         Fold<K<M, A>, S>.Done(var s) =>\n                                             done(s),\n\n                                         Fold<K<M, A>, S>.Loop(var s, var ma, var n) =>\n                                             reducer(s, ma) *\n                                             (ns => ns.Continue\n                                                        ? next(n(ns.Value))\n                                                        : reduced(ns))\n                                     });\n\n        K<M, Next<Fold<K<M, A>, S>, Reduced<S>>> done(S state) =>\n            M.Pure(reduced(Reduced.Done(state)));\n\n        Next<Fold<K<M, A>, S>, Reduced<S>> reduced(Reduced<S> reduced) =>\n            Next.Done<Fold<K<M, A>, S>, Reduced<S>>(reduced);\n\n        Next<Fold<K<M, A>, S>, Reduced<S>> next(Fold<K<M, A>, S> tail) =>\n            Next.Loop<Fold<K<M, A>, S>, Reduced<S>>(tail);        \n    }        \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/ForeverSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord ForeverSourceT<M, A>(K<M, A> Value) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S initialState, ReducerM<M, K<M, A>, S> reducer)\n    {\n        return Monad.recur(initialState, go);\n        K<M, Next<S, Reduced<S>>> go(S state) =>\n            reducer(state, Value) *\n            (rs => rs switch\n                   {\n                       { Continue: true, Value: var s } => Next.Loop<S, Reduced<S>>(s),\n                       _                                => Next.Done<S, Reduced<S>>(rs)\n                   });\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/IteratorAsyncSourceT.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord IteratorAsyncSourceT<M, A>(IAsyncEnumerable<K<M, A>> Items) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) \n    {\n        return Monad.recur((state, Items.GetIteratorAsync()), go);\n\n        K<M, Next<(S state, IteratorAsync<K<M, A>> iter), Reduced<S>>>\n            go((S state, IteratorAsync<K<M, A>> iter) self) =>\n            isDone(self) >> (d => d ? done(self.state)\n                                    : reduce(self.iter) >>\n                                      (ns => ns.Continue\n                                                 ? next(ns.Value, tail(self.iter))\n                                                 : reduced(ns)));\n\n        K<M, Reduced<S>> reduce(IteratorAsync<K<M, A>> iter) =>\n            IO.liftVAsync(_ => iter.Head).Bind(h => reducer(state, h));\n        \n        IO<bool> isDone((S state, IteratorAsync<K<M, A>> iter) self) =>\n            IO.liftVAsync(async e => e.Token.IsCancellationRequested || await self.iter.IsEmpty);\n\n        K<M, Next<(S state, IteratorAsync<K<M, A>> iter), Reduced<S>>> done(S state) =>\n            reduced(Reduced.Done(state));\n\n        K<M, Next<(S state, IteratorAsync<K<M, A>> iter), Reduced<S>>> reduced(Reduced<S> reduced) =>\n            M.Pure(Next.Done<(S state, IteratorAsync<K<M, A>> iter), Reduced<S>>(reduced));\n\n        K<M, IteratorAsync<K<M, A>>> tail(IteratorAsync<K<M, A>> iter) =>\n            M.LiftIO(IO.liftVAsync(_ => iter.Tail).Map(i => i.Split()));\n\n        K<M, Next<(S state, IteratorAsync<K<M, A>> iter), Reduced<S>>> next(S state, K<M, IteratorAsync<K<M, A>>> tail) =>\n            tail.Map(t => Next.Loop<(S state, IteratorAsync<K<M, A>> iter), Reduced<S>>((state, t)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/IteratorSyncSourceT.cs",
    "content": "using System.Collections.Generic;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord IteratorSyncSourceT<M, A>(IEnumerable<K<M, A>> Items) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer)\n    {\n        return Monad.recur((state, Items.GetIterator()), go);\n\n        K<M, Next<(S state, Iterator<K<M, A>> iter), Reduced<S>>> go((S state, Iterator<K<M, A>> iter) self) =>\n            isDone(self) >> (d => d ? done(self.state)\n                                    : reducer(state, self.iter.Head) >>\n                                      (ns => ns.Continue\n                                                 ? next(ns.Value, self.iter.Tail)\n                                                 : reduced(ns)));\n\n        IO<bool> isDone((S state, Iterator<K<M, A>> iter) self) =>\n            IO.lift(e => e.Token.IsCancellationRequested || self.iter.IsEmpty);\n\n        K<M, Next<(S state, Iterator<K<M, A>> iter), Reduced<S>>> done(S state) =>\n            reduced(Reduced.Done(state));\n\n        K<M, Next<(S state, Iterator<K<M, A>> iter), Reduced<S>>> reduced(Reduced<S> reduced) =>\n            M.Pure(Next.Done<(S state, Iterator<K<M, A>> iter), Reduced<S>>(reduced));\n\n        K<M, Next<(S state, Iterator<K<M, A>> iter), Reduced<S>>> next(S state, Iterator<K<M, A>> tail) =>\n            M.Pure(Next.Loop<(S state, Iterator<K<M, A>> iter), Reduced<S>>((state, tail.Split())));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/LiftSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord LiftSourceT<M, A>(K<M, A> Value) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) => \n        reducer(state, Value);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/MapIOSourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord MapIOSourceT<M, A, B>(SourceT<M, A> Source, Func<IO<A>, IO<B>> F) : SourceT<M, B>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, B>, S> reducer) =>\n        Source.ReduceInternalM(state, (s, ma) => reducer(s, M.MapIOMaybe(ma, F)));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/MapSourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord MapSourceT<M, A, B>(SourceT<M, A> Source, Func<A, B> F) : SourceT<M, B>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, B>, S> reducer) => \n        Source.ReduceInternalM(state, (s, mx) => reducer(s, mx.Map(F)));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/MultiListenerPureSourceT.cs",
    "content": "using System;\nusing System.Threading;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing System.Threading.Tasks;\nusing System.Threading.Channels;\nusing static LanguageExt.Prelude;\nusing System.Collections.Concurrent;\n\nnamespace LanguageExt;\n\nrecord MultiListenerPureSourceT<M, A>(Channel<A> Source) : SourceT<M, A>\n    where M : MonadIO<M>, Fallible<M>\n{\n    volatile int count;\n    readonly ConcurrentDictionary<Channel<K<M, A>>, Unit> listeners = new();\n    readonly CancellationTokenSource tokenSource = new();\n\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer)\n    {\n        return from channel in mkChannel\n               let final    =  final(channel)\n               from result  in body(channel, state)\n                                .Bind(final.ConstMap)       // Run final if we succeed\n                                .Catch(error<S>(channel))   // Run final if we fail and keep the original state\n               select result;\n\n        K<M, Reduced<S>> body(Channel<K<M, A>> channel, S state) =>\n            from _  in addListener(channel) >> \n                       startup\n            from st in readAll(channel, reducer, state) >>\n                       final(channel)\n            select st;\n    }\n\n    IO<Channel<K<M, A>>> mkChannel =>\n        IO.lift(_ => Channel.CreateUnbounded<K<M, A>>());\n    \n    IO<Unit> addListener(Channel<K<M, A>> channel) =>\n        IO.lift(_ => ignore(listeners.TryAdd(channel, unit)));\n    \n    IO<Unit> startup =>\n        IO.lift(_ =>\n                {\n                    if (Interlocked.Increment(ref count) == 1)\n                    {\n                        // We let the Task run without awaiting, because we don't want to block\n                        ignore(startupAsync());\n                    }\n                    return unit;\n                });\n    \n    async Task startupAsync()\n    {\n        try\n        {\n            var token = tokenSource.Token;\n            while (await Source.Reader.WaitToReadAsync(token))\n            {\n                if (token.IsCancellationRequested)\n                {\n                    return;\n                }\n\n                var x = await Source.Reader.ReadAsync(token);\n                foreach (var listener in listeners.Keys)\n                {\n                    if (await listener.Writer.WaitToWriteAsync(token))\n                    {\n                        await listener.Writer.WriteAsync(M.Pure(x), token);\n                    }\n                }\n            }\n        }\n        catch (Exception e)\n        {\n            foreach (var listener in listeners.Keys)\n            {\n                listener.Writer.TryComplete(e);\n            }\n        }\n        finally\n        {\n            foreach (var listener in listeners.Keys)\n            {\n                listener.Writer.TryComplete();\n            }\n        }\n    }\n\n    K<M, Reduced<S>> readAll<S>(Channel<K<M, A>> channel, ReducerM<M, K<M, A>, S> reducer, S initialState)\n    {\n        return Monad.recur(initialState, go);\n        \n        K<M, Next<S, Reduced<S>>> go(S state) =>\n            IO.token >> (t => t.IsCancellationRequested\n                                  ? complete(state)\n                                  : waitToRead() >>\n                                    (available => available\n                                                      ? reduce(state)\n                                                      : complete(state)));               \n\n        K<M, Next<S, Reduced<S>>> reduce(S state) =>\n            read() >> (head => reducer(state, head) >> next);\n\n        K<M, Next<S, Reduced<S>>> next(Reduced<S> reduced) =>\n            reduced.Continue\n                ? M.Pure(Next.Loop<S, Reduced<S>>(reduced.Value))\n                : M.Pure(Next.Done<S, Reduced<S>>(reduced));\n        \n        IO<bool> waitToRead() =>\n            IO.liftVAsync(e => channel.Reader.WaitToReadAsync(e.Token));\n\n        IO<K<M, A>> read() =>\n            IO.liftVAsync(e => channel.Reader.ReadAsync(e.Token));\n\n        K<M, Next<S, Reduced<S>>> complete(S state) =>\n            M.Pure(Next.Done<S, Reduced<S>>(Reduced.Done(state)));\n    }\n\n    K<M, Unit> final(Channel<K<M, A>> channel) =>\n        M.LiftIO(\n            IO.liftVAsync(async e =>\n                          {\n                              listeners.TryRemove(channel, out _);\n                              if (Interlocked.Decrement(ref count) == 0)\n                              {\n                                  await shutdown();\n                              }\n\n                              return unit;\n                          }));\n    \n    Func<Error, K<M, Reduced<S>>> error<S>(Channel<K<M, A>> channel) =>\n        err =>\n            final(channel) >> M.Fail<Reduced<S>>(err);\n    \n    Task shutdown() =>\n        tokenSource.CancelAsync();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/MultiListenerSourceT.cs",
    "content": "using System;\nusing System.Collections.Concurrent;\nusing System.Threading;\nusing System.Threading.Channels;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord MultiListenerSourceT<M, A>(Channel<K<M, A>> Source) : SourceT<M, A>\n    where M : MonadIO<M>, Fallible<M>\n{\n    volatile int count;\n    readonly ConcurrentDictionary<Channel<K<M, A>>, Unit> listeners = new();\n    readonly CancellationTokenSource tokenSource = new();\n\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer)\n    {\n        return from channel in mkChannel\n               let final    =  final(channel)\n               from result  in body(channel, state)\n                                  .Bind(final.ConstMap)      // Run final if we succeed\n                                  .Catch(error<S>(channel))  // Run final if we fail and rethrow\n               select result;\n\n        K<M, Reduced<S>> body(Channel<K<M, A>> channel, S state) =>\n            from _  in addListener(channel) >>\n                       startup\n            from st in readAll(channel, reducer, state) >>\n                       final(channel)\n            select st;\n    }\n\n    IO<Channel<K<M, A>>> mkChannel =>\n        IO.lift(_ => Channel.CreateUnbounded<K<M, A>>());\n    \n    IO<Unit> addListener(Channel<K<M, A>> channel) =>\n        IO.lift(_ => ignore(listeners.TryAdd(channel, unit)));\n    \n    IO<Unit> startup =>\n        IO.lift(_ =>\n                {\n                    if (Interlocked.Increment(ref count) == 1)\n                    {\n                        // We let the Task run without awaiting, because we don't want to block\n                        ignore(startupAsync());\n                    }\n                    return unit;\n                });\n    \n    async Task startupAsync()\n    {\n        try\n        {\n            var token = tokenSource.Token;\n            while (await Source.Reader.WaitToReadAsync(token))\n            {\n                if (token.IsCancellationRequested)\n                {\n                    return;\n                }\n\n                var x = await Source.Reader.ReadAsync(token);\n                foreach (var listener in listeners.Keys)\n                {\n                    if (await listener.Writer.WaitToWriteAsync(token))\n                    {\n                        await listener.Writer.WriteAsync(x, token);\n                    }\n                }\n            }\n        }\n        catch (Exception e)\n        {\n            foreach (var listener in listeners.Keys)\n            {\n                listener.Writer.TryComplete(e);\n            }\n        }\n        finally\n        {\n            foreach (var listener in listeners.Keys)\n            {\n                listener.Writer.TryComplete();\n            }\n        }\n    }\n\n    K<M, Reduced<S>> readAll<S>(Channel<K<M, A>> channel, ReducerM<M, K<M, A>, S> reducer, S initialState)\n    {\n        return Monad.recur(initialState, go);\n        \n        K<M, Next<S, Reduced<S>>> go(S state) =>\n            IO.token >> (t => t.IsCancellationRequested\n                                  ? complete(state)\n                                  : waitToRead() >>\n                                    (available => available\n                                                      ? reduce(state)\n                                                      : complete(state)));               \n\n        K<M, Next<S, Reduced<S>>> reduce(S state) =>\n            read() >> (head => reducer(state, head) * next);\n\n        Next<S, Reduced<S>> next(Reduced<S> reduced) =>\n            reduced.Continue\n                ? Next.Loop<S, Reduced<S>>(reduced.Value)\n                : Next.Done<S, Reduced<S>>(reduced);\n        \n        IO<bool> waitToRead() =>\n            IO.liftVAsync(e => channel.Reader.WaitToReadAsync(e.Token));\n\n        IO<K<M, A>> read() =>\n            IO.liftVAsync(e => channel.Reader.ReadAsync(e.Token));\n\n        K<M, Next<S, Reduced<S>>> complete(S state) =>\n            M.Pure(Next.Done<S, Reduced<S>>(Reduced.Done(state)));        \n    }\n\n    K<M, Unit> final(Channel<K<M, A>> channel) =>\n        M.LiftIO(\n            IO.liftVAsync(async e =>\n                          {\n                              listeners.TryRemove(channel, out _);\n                              if (Interlocked.Decrement(ref count) == 0)\n                              {\n                                  await shutdown();\n                              }\n\n                              return unit;\n                          }));\n\n    Func<Error, K<M, Reduced<S>>> error<S>(Channel<K<M, A>> channel) =>\n        err =>\n            final(channel) >> M.Fail<Reduced<S>>(err);\n\n    Task shutdown() =>\n        tokenSource.CancelAsync();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/ObservablePureSourceT.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\nusing System.Threading;\n\nnamespace LanguageExt;\n\nrecord ObservablePureSourceT<M, A>(IObservable<A> Items) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) \n    {\n        return M.LiftIO(IO.liftVAsync(e => go(state, Items.ToAsyncEnumerable(e.Token).GetIteratorAsync(), e.Token))).Flatten();\n        async ValueTask<K<M, Reduced<S>>> go(S state, IteratorAsync<A> iter, CancellationToken token)\n        {\n            if(token.IsCancellationRequested) return M.Pure(Reduced.Done(state));\n            if (await iter.IsEmpty) return M.Pure(Reduced.Done(state));\n            var head = await iter.Head;\n            var tail = (await iter.Tail).Split();\n            return reducer(state, M.Pure(head)) >> (ns => ns.Continue \n                                                            ? go(ns.Value, tail, token).GetAwaiter().GetResult()\n                                                            : M.Pure(ns));\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/ObservableSourceT.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\nusing System.Threading;\n\nnamespace LanguageExt;\n\nrecord ObservableSourceT<M, A>(IObservable<K<M, A>> Items) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) \n    {\n        return M.LiftIO(IO.liftVAsync(e => go(state, Items.ToAsyncEnumerable(e.Token).GetIteratorAsync(), e.Token))).Flatten();\n        async ValueTask<K<M, Reduced<S>>> go(S state, IteratorAsync<K<M, A>> iter, CancellationToken token)\n        {\n            if(token.IsCancellationRequested) return M.Pure(Reduced.Done(state));\n            if (await iter.IsEmpty) return M.Pure(Reduced.Done(state));\n            var head = await iter.Head;\n            var tail = (await iter.Tail).Split();\n            return reducer(state, head) >> (ns => ns.Continue \n                                                      ? go(ns.Value, tail, token).GetAwaiter().GetResult()\n                                                      : M.Pure(ns));\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/PureSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord PureSourceT<M, A>(A Value) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) => \n        reducer(state, M.Pure(Value));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/Reader2SourceT.cs",
    "content": "using System.Threading;\nusing System.Threading.Channels;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord Reader2SourceT<M, A, B>(Channel<K<M, A>> ChannelA, Channel<K<M, B>> ChannelB) : SourceT<M, (A First, B Second)>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, (A First, B Second)>, S> reducer)\n    {\n        return M.LiftIO(IO.liftVAsync(e => go(state, e.Token))).Flatten();\n        async ValueTask<K<M, Reduced<S>>> go(S state, CancellationToken token)\n        {\n            if(token.IsCancellationRequested) return M.Pure(Reduced.Done(state));\n            var fa = ChannelA.Reader.WaitToReadAsync(token).AsTask();\n            var fb = ChannelB.Reader.WaitToReadAsync(token).AsTask();\n            await Task.WhenAll(fa, fb);\n            \n            if (!fa.Result || !fb.Result) return M.Pure(Reduced.Done(state));\n\n            var ta = ChannelA.Reader.ReadAsync(token).AsTask();\n            var tb = ChannelB.Reader.ReadAsync(token).AsTask();\n            await Task.WhenAll(ta, tb);\n\n            return reducer(state, ta.Result.Zip(tb.Result)) >>\n                   (ns => ns.Continue\n                              ? go(ns.Value, token).GetAwaiter().GetResult()\n                              : M.Pure(ns));\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/Reader3SourceT.cs",
    "content": "using System.Threading;\nusing System.Threading.Channels;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord Reader3SourceT<M, A, B, C>(\n    Channel<K<M, A>> ChannelA, \n    Channel<K<M, B>> ChannelB, \n    Channel<K<M, C>> ChannelC) : SourceT<M, (A First, B Second, C Third)>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, (A First, B Second, C Third)>, S> reducer)\n    {\n        return M.LiftIO(IO.liftVAsync(e => go(state, e.Token))).Flatten();\n        async ValueTask<K<M, Reduced<S>>> go(S state, CancellationToken token)\n        {\n            if(token.IsCancellationRequested) return M.Pure(Reduced.Done(state));\n            var fa = ChannelA.Reader.WaitToReadAsync(token).AsTask();\n            var fb = ChannelB.Reader.WaitToReadAsync(token).AsTask();\n            var fc = ChannelC.Reader.WaitToReadAsync(token).AsTask();\n            await Task.WhenAll(fa, fb, fc);\n\n            if (!fa.Result || !fb.Result || !fc.Result) return M.Pure(Reduced.Done(state));\n\n            var ta = ChannelA.Reader.ReadAsync(token).AsTask();\n            var tb = ChannelB.Reader.ReadAsync(token).AsTask();\n            var tc = ChannelC.Reader.ReadAsync(token).AsTask();\n            await Task.WhenAll(ta, tb, tc);\n\n            return reducer(state, ta.Result.Zip(tb.Result, tc.Result)) >>\n                   (ns => ns.Continue\n                              ? go(ns.Value, token).GetAwaiter().GetResult()\n                              : M.Pure(ns));\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/Reader4SourceT.cs",
    "content": "using System.Threading;\nusing System.Threading.Channels;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord Reader4SourceT<M, A, B, C, D>(\n    Channel<K<M, A>> ChannelA, \n    Channel<K<M, B>> ChannelB, \n    Channel<K<M, C>> ChannelC, \n    Channel<K<M, D>> ChannelD) : SourceT<M, (A First, B Second, C Third, D Fourth)>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, (A First, B Second, C Third, D Fourth)>, S> reducer)\n    {\n        return M.LiftIO(IO.liftVAsync(e => go(state, e.Token))).Flatten();\n        async ValueTask<K<M, Reduced<S>>> go(S state, CancellationToken token)\n        {\n            if(token.IsCancellationRequested) return M.Pure(Reduced.Done(state));\n            var fa = ChannelA.Reader.WaitToReadAsync(token).AsTask();\n            var fb = ChannelB.Reader.WaitToReadAsync(token).AsTask();\n            var fc = ChannelC.Reader.WaitToReadAsync(token).AsTask();\n            var fd = ChannelD.Reader.WaitToReadAsync(token).AsTask();\n            await Task.WhenAll(fa, fb, fc, fd);\n\n            if (!fa.Result || !fb.Result || !fc.Result || !fd.Result) return M.Pure(Reduced.Done(state));\n\n            var ta = ChannelA.Reader.ReadAsync(token).AsTask();\n            var tb = ChannelB.Reader.ReadAsync(token).AsTask();\n            var tc = ChannelC.Reader.ReadAsync(token).AsTask();\n            var td = ChannelD.Reader.ReadAsync(token).AsTask();\n            await Task.WhenAll(ta, tb, tc, td);\n            \n            return reducer(state, ta.Result.Zip(tb.Result, tc.Result, td.Result)) >> \n                   (ns => ns.Continue \n                              ? go(ns.Value, token).GetAwaiter().GetResult()\n                              : M.Pure(ns));\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/SourcePureSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord SourcePureSourceT<M, A>(Source<A> Source) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) =>\n        M.LiftIO(Source.Reduce(\n                     M.Pure(Reduced.Continue(state)),\n                     (ms, a) => Reduced.Continue(ms >> (ns => ns.Continue\n                                                                  ? reducer(ns.Value, M.Pure(a))\n                                                                  : M.Pure(ns)))))\n         .Flatten();\n\n\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/SourceSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord SourceSourceT<M, A>(Source<K<M, A>> Source) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) =>\n        M.LiftIO(Source.Reduce(\n                     M.Pure(Reduced.Continue(state)),\n                     (ms, ma) => Reduced.Continue(ms >> (ns => ns.Continue\n                                                                   ? reducer(ns.Value, ma)\n                                                                   : M.Pure(ns)))))\n         .Flatten();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/TakeForSourceT.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord TakeForSourceT<M, A>(SourceT<M, A> Source, TimeSpan Duration) : SourceT<M, A>\n    where M : MonadIO<M>, Fallible<Error, M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer) =>\n        from sofar in atomIO(state)\n        from value in M.TimeoutIOMaybe(reduce(state, reducer, sofar), Duration)\n                        | @catch(ErrorCodes.TimedOut, timedOut(sofar))\n                        | @catch(ErrorCodes.Cancelled, timedOut(sofar))\n        select value;\n\n    K<M, Reduced<S>> timedOut<S>(Atom<S> state) =>\n        M.LiftIO(state.ValueIO).Map(Reduced.Done);\n    \n    K<M, Reduced<S>> reduce<S>(S state, ReducerM<M, K<M, A>, S> reducer, Atom<S> sofar) =>\n        Source.ReduceInternalM(\n            state,\n            (s, ma) => from ns in reducer(s, ma)\n                       from _ in sofar.SwapIO(_ => ns.Value)\n                       select ns);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/TakeSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord TakeSourceT<M, A>(SourceT<M, A> Source, int Count) : SourceT<M, A>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer)\n    {\n        var remaining = Count;\n        return Source.ReduceInternalM(state,\n                                      (s, ma) =>\n                                      {\n                                          if (remaining < 1) return M.Pure(Reduced.Done(s));\n                                          remaining--;\n                                          return remaining == 0\n                                                    ? reducer(s, ma).Map(n => Reduced.Done(n.Value))\n                                                    : reducer(s, ma);\n                                      });\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/ToIOSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord ToIOSourceT<M, A>(SourceT<M, A> Source) : SourceT<M, IO<A>>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, IO<A>>, S> reducer) => \n        Source.ReduceInternalM(state, (s, mx) => reducer(s, M.ToIOMaybe(mx)));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/TransformSourceT.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord TransformSourceT<M, A, B>(SourceT<M, A> Source, TransducerM<M, A, B> Transducer) : SourceT<M, B>\n    where M : MonadIO<M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, B>, S> reducer)\n    {\n        var t = Transducer.Reduce<S>((s1, b) => reducer(s1, M.Pure(b)));\n        return Source.ReduceInternalM(state, (s, ma) => ma.Bind(a => t(s, a)));\n    }\n}\n\nrecord TransformSourceT2<M, A, B>(SourceT<M, A> Source, Transducer<A, B> Transducer) : SourceT<M, B>\n    where M : MonadIO<M>\n{\n    readonly TransducerM<M, A, B> TransducerM = Transducer.Lift<M>();\n    \n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, B>, S> reducer)\n    {\n        var t  = TransducerM.Reduce((S s1, B b) => reducer(s1, M.Pure(b)));\n        return Source.ReduceInternalM(state, (s, ma) => ma.Bind(a => t(s, a)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/Zip2SourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord Zip2SourceT<M, A, B>(SourceT<M, A> SourceA, SourceT<M, B> SourceB) : SourceT<M, (A First, B Second)>\n    where M : MonadIO<M>, Fallible<Error, M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, (A First, B Second)>, S> reducer) =>\n        \n        // Create channels that receive the values yielded by the two sources\n        from channelA in M.Pure(Channel.CreateUnbounded<K<M, A>>())\n        from channelB in M.Pure(Channel.CreateUnbounded<K<M, B>>())\n        let writerA = channelA.Writer\n        let writerB = channelB.Writer\n\n        // Triggers which signal when a channel has completed\n        let triggerA = trigger<A>(writerA)\n        let triggerB = trigger<B>(writerB)\n        let error    = error(writerA, writerB)\n\n        // Create a forked first channel                        \n        from forkA in SourceA.ReduceInternalM(unit, (_, ma) => writeAsync(writerA, ma))\n                             .Bind(_ => triggerA)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        // Create a forked second channel                        \n        from forkB in SourceB.ReduceInternalM(unit, (_, ma) => writeAsync(writerB, ma))\n                             .Bind(_ => triggerB)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        let forks = Seq(forkA, forkB)\n                              \n        // Then create a reader iterator that will yield the merged values \n        from result in new Reader2SourceT<M, A, B>(channelA, channelB).ReduceInternalM(state, reducer)\n        \n        // Make sure the forks are shutdown\n        from _ in M.LiftIO(forks.Traverse(f => f.Cancel))\n\n        // Await all of the values - this should not yield anything useful unless an error occurred.\n        from rs in M.LiftIO(forks.Traverse(f => f.Await))\n\n        select result;\n\n    static K<M, Unit> trigger<X>(ChannelWriter<K<M, X>> writer) =>\n        M.LiftIO(IO.lift(() => writer.TryComplete().Ignore()));\n    \n    static Func<Error, K<M, Unit>> error(\n        ChannelWriter<K<M, A>> writerA,\n        ChannelWriter<K<M, B>> writerB) =>\n        err => M.LiftIO(\n                     IO.lift(e => \n                             { \n                                 writerA.TryComplete(); \n                                 writerB.TryComplete(); \n                                 return unit; \n                             }))\n                .Bind(_ => M.Fail<Unit>(err));\n\n    static K<M, Reduced<Unit>> writeAsync<X>(ChannelWriter<X> writer, X value) =>\n        M.LiftIO(IO.liftVAsync(async e =>\n                               {\n                                   await writer.WriteAsync(value, e.Token);\n                                   return Reduced.Continue(unit);\n                               }));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/Zip3SourceT.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord Zip3SourceT<M, A, B, C>(\n    SourceT<M, A> SourceA, \n    SourceT<M, B> SourceB, \n    SourceT<M, C> SourceC) : \n    SourceT<M, (A First, B Second, C Third)>\n    where M : MonadIO<M>, Fallible<Error, M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, (A First, B Second, C Third)>, S> reducer) =>\n        \n        // Create channels that receive the values yielded by the two sources\n        from channelA in M.Pure(Channel.CreateUnbounded<K<M, A>>())\n        from channelB in M.Pure(Channel.CreateUnbounded<K<M, B>>())\n        from channelC in M.Pure(Channel.CreateUnbounded<K<M, C>>())\n        let writerA = channelA.Writer\n        let writerB = channelB.Writer\n        let writerC = channelC.Writer\n\n        // Triggers which signal when a channel has completed\n        let triggerA = trigger<A>(writerA)\n        let triggerB = trigger<B>(writerB)\n        let triggerC = trigger<C>(writerC)\n        let error    = error(writerA, writerB, writerC)\n\n        // Create a forked first channel                        \n        from forkA in SourceA.ReduceInternalM(unit, (_, ma) => writeAsync(writerA, ma))\n                             .Bind(_ => triggerA)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        // Create a forked second channel                        \n        from forkB in SourceB.ReduceInternalM(unit, (_, ma) => writeAsync(writerB, ma))\n                             .Bind(_ => triggerB)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        // Create a forked third channel                        \n        from forkC in SourceC.ReduceInternalM(unit, (_, ma) => writeAsync(writerC, ma))\n                             .Bind(_ => triggerC)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        let forks = Seq(forkA, forkB, forkC)\n\n        // Then create a reader iterator that will yield the merged values \n        from result in new Reader3SourceT<M, A, B, C>(channelA, channelB, channelC).ReduceInternalM(state, reducer)\n\n        // Make sure the forks are shutdown\n        from _      in M.LiftIOMaybe(forks.Traverse(f => f.Cancel))\n\n        // Await all of the values - this should not yield anything useful unless an error occurred.\n        from rs     in M.LiftIO(forks.Traverse(f => f.Await))\n\n        select result;\n    \n    static K<M, Unit> trigger<X>(ChannelWriter<K<M, X>> writer) =>\n        M.LiftIOMaybe(IO.lift(() => writer.TryComplete().Ignore()));\n    \n    static Func<Error, K<M, Unit>> error(\n        ChannelWriter<K<M, A>> writerA,\n        ChannelWriter<K<M, B>> writerB,\n        ChannelWriter<K<M, C>> writerC) =>\n        err => M.LiftIO(\n                     IO.lift(e => \n                             { \n                                 writerA.TryComplete(); \n                                 writerB.TryComplete(); \n                                 writerC.TryComplete(); \n                                 return unit; \n                             }))\n                    .Bind(_ => M.Fail<Unit>(err));\n\n    static K<M, Reduced<Unit>> writeAsync<X>(ChannelWriter<X> writer, X value) =>\n        M.LiftIO(IO.liftVAsync(async e =>\n                               {\n                                   await writer.WriteAsync(value, e.Token);\n                                   return Reduced.Continue(unit);\n                               }));   \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/DSL/Zip4SourceT.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\nrecord Zip4SourceT<M, A, B, C, D>(SourceT<M, A> SourceA, SourceT<M, B> SourceB, SourceT<M, C> SourceC, SourceT<M, D> SourceD) \n    : SourceT<M, (A First, B Second, C Third, D Fourth)>\n    where M : MonadIO<M>, Fallible<Error, M>\n{\n    internal override K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, (A First, B Second, C Third, D Fourth)>, S> reducer) => \n                \n        // Create channels that receive the values yielded by the two sources\n        from channelA in M.Pure(Channel.CreateUnbounded<K<M, A>>())\n        from channelB in M.Pure(Channel.CreateUnbounded<K<M, B>>())\n        from channelC in M.Pure(Channel.CreateUnbounded<K<M, C>>())\n        from channelD in M.Pure(Channel.CreateUnbounded<K<M, D>>())\n        \n        let writerA = channelA.Writer\n        let writerB = channelB.Writer\n        let writerC = channelC.Writer\n        let writerD = channelD.Writer\n\n        // Triggers which signal when a channel has completed\n        let triggerA = trigger<A>(writerA)\n        let triggerB = trigger<B>(writerB)\n        let triggerC = trigger<C>(writerC)\n        let triggerD = trigger<D>(writerD)\n        let error    = error(writerA, writerB, writerC, writerD)\n\n        // Create a forked first channel                        \n        from forkA in SourceA.ReduceInternalM(unit, (_, ma) => writeAsync(writerA, ma))\n                             .Bind(_ => triggerA)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        // Create a forked second channel                        \n        from forkB in SourceB.ReduceInternalM(unit, (_, ma) => writeAsync(writerB, ma))\n                             .Bind(_ => triggerB)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        // Create a forked third channel                        \n        from forkC in SourceC.ReduceInternalM(unit, (_, ma) => writeAsync(writerC, ma))\n                             .Bind(_ => triggerC)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        // Create a forked fourth channel                        \n        from forkD in SourceD.ReduceInternalM(unit, (_, ma) => writeAsync(writerD, ma))\n                             .Bind(_ => triggerD)\n                             .Catch(error)\n                             .ForkIOMaybe()\n\n        let forks = Seq(forkA, forkB, forkC, forkD)\n\n        // Then create a reader iterator that will yield the merged values \n        from result in new Reader4SourceT<M, A, B, C, D>(channelA, channelB, channelC, channelD).ReduceInternalM(state, reducer)\n\n        // Make sure the forks are shutdown\n        from _      in M.LiftIOMaybe(forks.Traverse(f => f.Cancel))\n\n        // Await all of the values - this should not yield anything useful unless an error occurred.\n        from rs     in M.LiftIO(forks.Traverse(f => f.Await))\n\n        select result;\n    \n    static K<M, Unit> trigger<X>(ChannelWriter<K<M, X>> writer) =>\n        M.LiftIOMaybe(IO.lift(() => writer.TryComplete().Ignore()));\n    \n    \n    static Func<Error, K<M, Unit>> error(\n        ChannelWriter<K<M, A>> writerA,\n        ChannelWriter<K<M, B>> writerB,\n        ChannelWriter<K<M, C>> writerC,\n        ChannelWriter<K<M, D>> writerD) =>\n        err => M.LiftIO(\n                     IO.lift(e => \n                             { \n                                 writerA.TryComplete(); \n                                 writerB.TryComplete(); \n                                 writerC.TryComplete(); \n                                 writerD.TryComplete(); \n                                 return unit; \n                             }))\n                .Bind(_ => M.Fail<Unit>(err));\n\n    static K<M, Reduced<Unit>> writeAsync<X>(ChannelWriter<X> writer, X value) =>\n        M.LiftIO(IO.liftVAsync(async e =>\n                               {\n                                   await writer.WriteAsync(value, e.Token);\n                                   return Reduced.Continue(unit);\n                               }));       \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Extensions/SourceT.Combinators.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing System.Diagnostics.Contracts;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n    /// <param name=\"ma\">Stream of values to delay the yielding of</param>\n    /// <typeparam name=\"M\">Lifted monad type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    extension<M, A>(K<SourceT<M>, A> ma) where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Delay the yielding of values by the specified duration\n        /// </summary>\n        /// <param name=\"duration\">Duration to delay the yielding of values for</param>\n        /// <returns></returns>\n        public SourceT<M, A> Delay(TimeSpan duration) =>\n            IO.yieldFor(duration) >> ma >> lower;\n\n        /// <summary>\n        /// Delay the yielding of values by the specified duration\n        /// </summary>\n        /// <param name=\"duration\">Duration to delay the yielding of values for</param>\n        /// <returns></returns>\n        public SourceT<M, A> Delay(Duration duration) =>\n            IO.yieldFor(duration) >> ma >> lower;\n    }\n\n    /// <param name=\"ma\">Source</param>\n    /// <typeparam name=\"M\">Lifted monad trait</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    extension<M, A>(K<SourceT<M>, A> ma) where M : MonadIO<M>, Fallible<M>\n    {\n        /// <summary>\n        /// Take values from the source for a period of time \n        /// </summary>\n        /// <param name=\"duration\">Duration to take values for</param>\n        /// <returns>SourceT</returns>\n        [Pure]\n        public SourceT<M, A> TakeFor(Duration duration) =>\n            new TakeForSourceT<M, A>(+ma, (TimeSpan)duration);\n\n        /// <summary>\n        /// Take values from the source for a period of time \n        /// </summary>\n        /// <param name=\"duration\">Duration to take values for</param>\n        /// <returns>SourceT</returns>\n        [Pure]\n        public SourceT<M, A> TakeFor(TimeSpan duration) =>\n            new TakeForSourceT<M, A>(+ma, duration);\n        \n\n        /// <summary>\n        /// Combine two sources into a single source.  The value streams are both\n        /// merged into a new stream.  Values are yielded as they become available\n        /// regardless of which stream yields it.\n        /// </summary>\n        /// <param name=\"this\">Left-hand side</param>\n        /// <param name=\"rhs\">Right-hand side</param>\n        /// <returns>Merged stream of values</returns>\n        public SourceT<M, A> Choose(K<SourceT<M>, A> rhs) =>\n            (ma, rhs) switch\n            {\n                (EmptySourceT<M, A>, EmptySourceT<M, A>)       => EmptySourceT<M, A>.Default,\n                (var l, EmptySourceT<M, A>)                    => +l,\n                (EmptySourceT<M, A>, var r)                    => +r,\n                (ChooseSourceT<M, A> l, ChooseSourceT<M, A> r) => new ChooseSourceT<M, A>(l.Sources + r.Sources),\n                (ChooseSourceT<M, A> l, var r)                 => new ChooseSourceT<M, A>(l.Sources.Add(+r)),\n                (var l, ChooseSourceT<M, A> r)                 => new ChooseSourceT<M, A>(l.As().Cons(r.Sources)),\n                var (l, r)                                     => new ChooseSourceT<M, A>([+l, +r])\n            };\n\n        /// <summary>\n        /// Combine two sources into a single source.  The value streams are both\n        /// merged into a new stream.  Values are yielded as they become available\n        /// regardless of which stream yields it.\n        /// </summary>\n        /// <param name=\"this\">Left-hand side</param>\n        /// <param name=\"rhs\">Right-hand side</param>\n        /// <returns>Merged stream of values</returns>\n        public SourceT<M, A> Choose(Memo<SourceT<M>, A> rhs) =>\n            ma.Choose(rhs.Value.As());        \n    }\n\n    /// <param name=\"first\">Stream to zip</param>\n    extension<M, A>(K<SourceT<M>, A> first) where M : MonadIO<M>, Fallible<Error, M>\n    {\n        /// <summary>\n        /// Zip two sources into one\n        /// </summary>\n        /// <param name=\"second\">Stream to zip</param>\n        /// <returns>Stream of values where the items from two streams are paired together</returns>\n        public SourceT<M, (A First, B Second)> Zip<B>(K<SourceT<M>, B> second) =>\n            new Zip2SourceT<M, A, B>(first.As(), second.As());\n\n        /// <summary>\n        /// Zip three sources into one\n        /// </summary>\n        /// <param name=\"second\">Stream to zip</param>\n        /// <param name=\"third\">Stream to zip</param>\n        /// <returns>Stream of values where the items from two streams are paired together</returns>\n        public SourceT<M, (A First, B Second, C Third)> Zip<B, C>(\n            K<SourceT<M>, B> second, \n            K<SourceT<M>, C> third) =>\n            new Zip3SourceT<M, A, B, C>(first.As(), second.As(), third.As());\n\n        /// <summary>\n        /// Zip three sources into one\n        /// </summary>\n        /// <param name=\"second\">Stream to zip</param>\n        /// <param name=\"third\">Stream to zip</param>\n        /// <param name=\"fourth\">Stream to zip</param>\n        /// <returns>Stream of values where the items from two streams are paired together</returns>\n        public SourceT<M, (A First, B Second, C Third, D Fourth)> Zip<B, C, D>(\n            K<SourceT<M>, B> second,\n            K<SourceT<M>, C> third,\n            K<SourceT<M>, D> fourth) =>\n            new Zip4SourceT<M, A, B, C, D>(first.As(), second.As(), third.As(), fourth.As());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Extensions/SourceT.Extensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Threading.Channels;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n    /// <summary>\n    /// Downcast\n    /// </summary>\n    [Pure]\n    public static SourceT<M, A> As<M, A>(this K<SourceT<M>, A> ma) \n        where M : MonadIO<M> =>\n        (SourceT<M, A>)ma;\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceT<M, A>(this Channel<A> items)\n        where M : MonadIO<M>, Fallible<M> =>\n        SourceT.lift<M, A>(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceM<M, A>(this Channel<K<M, A>> items)\n        where M : MonadIO<M>, Fallible<M> =>\n        SourceT.liftM(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceT<M, A>(this Source<A> items)\n        where M : MonadIO<M> =>\n        SourceT.lift<M, A>(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceM<M, A>(this Source<K<M, A>> items)\n        where M : MonadIO<M> =>\n        SourceT.liftM(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceT<M, A>(this IEnumerable<A> items)\n        where M : MonadIO<M> =>\n        SourceT.lift<M, A>(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceM<M, A>(this IEnumerable<K<M, A>> items)\n        where M : MonadIO<M> =>\n        SourceT.liftM(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceT<M, A>(this IObservable<A> items)\n        where M : MonadIO<M> =>\n        SourceT.lift<M, A>(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceM<M, A>(this IObservable<K<M, A>> items)\n        where M : MonadIO<M> =>\n        SourceT.liftM(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceT<M, A>(this IAsyncEnumerable<A> items)\n        where M : MonadIO<M> =>\n        SourceT.lift<M, A>(items);\n    \n    [Pure]\n    public static SourceT<M, A> AsSourceM<M, A>(this IAsyncEnumerable<K<M, A>> items)\n        where M : MonadIO<M> =>\n        SourceT.liftM(items);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static SourceT<M, B> Bind<M, A, B>(this IO<A> ma, Func<A, SourceT<M, B>> f)\n        where M : MonadIO<M> =>\n        SourceT.liftIO<M, A>(ma).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static SourceT<M, B> Bind<M, A, B>(this Pure<A> ma, Func<A, SourceT<M, B>> f)\n        where M : MonadIO<M> =>\n        SourceT.pure<M, A>(ma.Value).Bind(f);\n\n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static SourceT<M, B> Bind<M, A, B>(this K<M, A> ma, Func<A, SourceT<M, B>> f)\n        where M : MonadIO<M> =>\n        SourceT.liftM(ma).Bind(f);    \n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static SourceT<M, C> SelectMany<M, A, B, C>(this K<M, A> ma, Func<A, SourceT<M, B>> bind, Func<A, B, C> project) \n        where M : MonadIO<M> =>\n        SourceT.liftM(ma).As().SelectMany(bind, project);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static SourceT<M, C> SelectMany<M, A, B, C>(this IO<A> ma, Func<A, SourceT<M, B>> bind, Func<A, B, C> project) \n        where M : MonadIO<M> =>\n        SourceT.liftIO<M, A>(ma).As().SelectMany(bind, project);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    [Pure]\n    public static SourceT<M, C> SelectMany<M, A, B, C>(this Pure<A> ma, Func<A, SourceT<M, B>> bind, Func<A, B, C> project) \n        where M : MonadIO<M> =>\n        bind(ma.Value).Map(y => project(ma.Value, y));\n    \n    /// <summary>\n    /// Access the `Some` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of optional values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SomeSource<M, A>(this IAsyncEnumerable<OptionT<M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, OptionT<M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsSome\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Some` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of optional values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SomeSource<M, A>(this IAsyncEnumerable<Option<A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Option<A>>(stream)\n        where ox.IsSome\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Some` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of optional values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SomeSource<M, A>(this IEnumerable<OptionT<M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, OptionT<M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsSome\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Some` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of optional values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SomeSource<M, A>(this IEnumerable<Option<A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Option<A>>(stream)\n        where ox.IsSome\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Right` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> RightSource<M, L, A>(this IAsyncEnumerable<EitherT<L, M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, EitherT<L, M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsRight\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Right` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> RightSource<M, L, A>(this IAsyncEnumerable<Either<L, A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Either<L, A>>(stream)\n        where ox.IsRight\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Right` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> RightSource<M, L, A>(this IEnumerable<EitherT<L, M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, EitherT<L, M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsRight\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Right` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> RightSource<M, L, A>(this IEnumerable<Either<L, A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Either<L, A>>(stream)\n        where ox.IsRight\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Left` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, L> LeftSource<M, L, A>(this IAsyncEnumerable<EitherT<L, M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, EitherT<L, M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsLeft\n        select (L)ox;\n\n    /// <summary>\n    /// Access the `Left` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, L> LeftSource<M, L, A>(this IAsyncEnumerable<Either<L, A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Either<L, A>>(stream)\n        where ox.IsLeft\n        select (L)ox;\n\n    /// <summary>\n    /// Access the `Left` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, L> LeftSource<M, L, A>(this IEnumerable<EitherT<L, M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, EitherT<L, M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsLeft\n        select (L)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, L> LeftSource<M, L, A>(this IEnumerable<Either<L, A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Either<L, A>>(stream)\n        where ox.IsLeft\n        select (L)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SuccSource<M, A>(this IAsyncEnumerable<FinT<M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, FinT<M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsSucc\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SuccSource<M, A>(this IAsyncEnumerable<Fin<A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Fin<A>>(stream)\n        where ox.IsSucc\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SuccSource<M, A>(this IEnumerable<FinT<M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, FinT<M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsSucc\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SuccSource<M, A>(this IEnumerable<Fin<A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Fin<A>>(stream)\n        where ox.IsSucc\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Fail` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, Error> FailSource<M, A>(this IAsyncEnumerable<FinT<M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, FinT<M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsFail\n        select (Error)ox;\n\n    /// <summary>\n    /// Access the `Fail` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, Error> FailSource<M, A>(this IAsyncEnumerable<Fin<A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Fin<A>>(stream)\n        where ox.IsFail\n        select (Error)ox;\n\n    /// <summary>\n    /// Access the `Fail` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, Error> FailSource<M, A>(this IEnumerable<FinT<M, A>> stream)\n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, FinT<M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsFail\n        select (Error)ox;\n\n    /// <summary>\n    /// Access the `Fail` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, Error> FailSource<M, A>(this IEnumerable<Fin<A>> stream)\n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Fin<A>>(stream)\n        where ox.IsFail\n        select (Error)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SuccSource<M, L, A>(this IAsyncEnumerable<ValidationT<L, M, A>> stream)\n        where L : Monoid<L> \n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, ValidationT<L, M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsSuccess\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SuccSource<M, L, A>(this IAsyncEnumerable<Validation<L, A>> stream)\n        where L : Monoid<L> \n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Validation<L, A>>(stream)\n        where ox.IsSuccess\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SuccSource<M, L, A>(this IEnumerable<ValidationT<L, M, A>> stream)\n        where L : Monoid<L> \n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, ValidationT<L, M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsSuccess\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Succ` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, A> SuccSource<M, L, A>(this IEnumerable<Validation<L, A>> stream)\n        where L : Monoid<L> \n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Validation<L, A>>(stream)\n        where ox.IsSuccess\n        select (A)ox;\n\n    /// <summary>\n    /// Access the `Fail` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, L> FailSource<M, L, A>(this IAsyncEnumerable<ValidationT<L, M, A>> stream)\n        where L : Monoid<L> \n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, ValidationT<L, M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsFail\n        select (L)ox;\n\n    /// <summary>\n    /// Access the `Fail` values from the asynchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, L> FailsStream<M, L, A>(this IAsyncEnumerable<Validation<L, A>> stream)\n        where L : Monoid<L> \n        where M : MonadIO<M>  =>\n        from ox in SourceT.lift<M, Validation<L, A>>(stream)\n        where ox.IsFail\n        select (L)ox;\n\n    /// <summary>\n    /// Access the `Fail` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, L> FailSource<M, L, A>(this IEnumerable<ValidationT<L, M, A>> stream)\n        where L : Monoid<L> \n        where M : MonadIO<M>  =>\n        from xs in SourceT.lift<M, ValidationT<L, M, A>>(stream)\n        from ox in xs.Run()\n        where ox.IsFail\n        select (L)ox;\n\n    /// <summary>\n    /// Access the `Fail` values from the synchronous stream\n    /// </summary>\n    /// <param name=\"stream\">Stream of values</param>\n    /// <typeparam name=\"M\">Transformer monad</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Stream of values</returns>\n    [Pure]\n    public static SourceT<M, L> FailSource<M, L, A>(this IEnumerable<Validation<L, A>> stream)\n        where L : Monoid<L> \n        where M : MonadIO<M> =>\n        from ox in SourceT.lift<M, Validation<L, A>>(stream)\n        where ox.IsFail\n        select (L)ox;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Extensions/SourceT.Reducers.cs",
    "content": "using System;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n/// <param name=\"ma\"></param>\n    /// <typeparam name=\"M\"></typeparam>\n    /// <typeparam name=\"A\"></typeparam>\n    extension<M, A>(K<SourceT<M>, A> ma) where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Reduce the stream into a unit value.\n        /// </summary>\n        [Pure]\n        public K<M, Unit> Iter() =>\n            ma.As().FoldReduce(unit, (_, _) => unit);\n\n        /// <summary>\n        /// Reduce the stream by collecting all the values into a `Seq` while the predicate holds.\n        /// </summary>\n        [Pure]\n        public K<M, Seq<A>> CollectWhile(Func<(Seq<A> Items, A Item), bool> predicate) =>\n            ma.As().Reduce<Seq<A>>(\n                [], \n                (xs, x) => predicate((xs, x))\n                               ? Reduced.Continue(xs.Add(x))\n                               : Reduced.Done(xs));\n\n        /// <summary>\n        /// Reduce the stream by collecting all the values into a `Seq` while the predicate holds.\n        /// </summary>\n        [Pure]\n        public K<M, Seq<A>> CollectUntil(Func<(Seq<A> Items, A Item), bool> predicate) =>\n            ma.As().Reduce<Seq<A>>(\n                [], \n                (xs, x) => predicate((xs, x))\n                               ? Reduced.Done(xs)\n                               : Reduced.Continue(xs.Add(x)));\n\n        /// <summary>\n        /// Reduce the stream by collecting all the values into a `Seq`.\n        /// </summary>\n        [Pure]\n        public K<M, Seq<A>> Collect() =>\n            ma.As().FoldReduce<Seq<A>>([], (xs, x) => xs.Add(x));\n        \n        /// <summary>\n        /// Reduce the stream, yielding the last structure processed, or the `None` if the stream is empty\n        /// </summary>\n        [Pure]\n        public K<M, Option<A>> LastOrNone() =>\n            ma.As().FoldReduce(Option<A>.None, (_, x) => Some(x));\n        \n        /// <summary>\n        /// Reduce the stream, yielding the first structure processed, or the `None` if the stream is empty\n        /// </summary>\n        [Pure]\n        public K<M, Option<A>> FirstOrNone() =>\n            ma.As().Reduce(Option<A>.None, (_, x) => Reduced.Done(Some(x)));\n        \n        /// <summary>\n        /// Reduce the stream, yielding the last structure processed, or the default value if the stream is empty\n        /// </summary>\n        [Pure]\n        public K<M, A> Last(A defaultValue) =>\n            ma.As().FoldReduce(defaultValue, (_, x) => x);\n\n        /// <summary>\n        /// Reduce the stream, yielding the first structure processed, or the default value if the stream is empty\n        /// </summary>\n        [Pure]\n        public K<M, A> First(A defaultValue) =>\n            ma.As().Reduce(defaultValue, (_, x) => Reduced.Done(x));\n    }    \n    \n    /// <param name=\"ma\"></param>\n    /// <typeparam name=\"M\"></typeparam>\n    /// <typeparam name=\"A\"></typeparam>\n    extension<M, A>(K<SourceT<M>, A> ma) \n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Reduce the stream, yielding the last structure processed, or `M.Empty` if the stream is empty\n        /// </summary>\n        [Pure]\n        public K<M, A> Last() =>\n            ma.LastOrNone()\n              .Bind(ma => ma switch\n                          {\n                              { IsSome: true, Case: A value } => M.Pure(value),\n                              _                               => M.Empty<A>()\n                          });\n        \n        /// <summary>\n        /// Reduce the stream, yielding the first structure processed, or `M.Empty` if the stream is empty\n        /// </summary>\n        [Pure]\n        public K<M, A> First() =>\n            ma.FirstOrNone()\n              .Bind(ma => ma switch\n                          {\n                              { IsSome: true, Case: A value } => M.Pure(value),\n                              _                               => M.Empty<A>()\n                          });        \n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Operators/SourceT.Operators.Applicative.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n    extension<M, A, B>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        \n        /// <summary>\n        /// Applicative sequence operator\n        /// </summary>\n        public static SourceT<M, B> operator >>> (K<SourceT<M>, A> ma, K<SourceT<M>, B> mb) =>\n            +ma.Action(mb);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, B> operator * (K<SourceT<M>, Func<A, B>> mf, K<SourceT<M>, A> ma) =>\n            +mf.Apply(ma);\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, B> operator * (K<SourceT<M>, A> ma, K<SourceT<M>, Func<A, B>> mf) =>\n            +mf.Apply(ma);        \n    }\n    \n    extension<M, A, B, C>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, C>> operator * (\n            K<SourceT<M>, Func<A, B, C>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, C>> operator * (\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C>> mf) =>\n            curry * mf * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, D>>> operator * (\n            K<SourceT<M>, Func<A, B, C, D>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, D>>> operator * (\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C, D>> mf) =>\n            curry * mf * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<SourceT<M>, Func<A, B, C, D, E>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C, D, E>> mf) =>\n            curry * mf * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<SourceT<M>, Func<A, B, C, D, E, F>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C, D, E, F>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<SourceT<M>, Func<A, B, C, D, E, F, G>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C, D, E, F, G>> mf) =>\n            curry * mf * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G, H>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<SourceT<M>, Func<A, B, C, D, E, F, G, H>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C, D, E, F, G, H>> mf) =>\n            curry * mf * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<SourceT<M>, Func<A, B, C, D, E, F, G, H, I>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C, D, E, F, G, H, I>> mf) =>\n            curry * mf * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<SourceT<M>, Func<A, B, C, D, E, F, G, H, I, J>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n        \n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C, D, E, F, G, H, I, J>> mf) =>\n            curry * mf * ma;\n    }\n                                \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<SourceT<M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf, \n            K<SourceT<M>, A> ma) =>\n            curry * mf * ma;\n\n        /// <summary>\n        /// Applicative apply operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator *(\n            K<SourceT<M>, A> ma,\n            K<SourceT<M>, Func<A, B, C, D, E, F, G, H, I, J, K>> mf) =>\n            curry * mf * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Operators/SourceT.Operators.Choice.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n    extension<M, A>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>, Fallible<M>\n    {\n        public static SourceT<M, A> operator |(K<SourceT<M>, A> lhs, K<SourceT<M>, A> rhs) =>\n            +lhs.Choose(rhs);\n\n        public static SourceT<M, A> operator |(K<SourceT<M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Choose(SourceT.pure<M, A>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Operators/SourceT.Operators.Combine.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceExtensions\n{\n    extension<M, A>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static SourceT<M, A> operator +(K<SourceT<M>, A> lhs, K<SourceT<M>, A> rhs) =>\n            +lhs.Combine(rhs);\n\n        /// <summary>\n        /// Semigroup combine operator: an associative binary operation.\n        /// </summary>\n        /// <param name=\"lhs\">Left-hand side operand</param>\n        /// <param name=\"rhs\">Right-hand side operand</param>\n        /// <returns></returns>\n        public static SourceT<M, A> operator +(K<SourceT<M>, A> lhs, Pure<A> rhs) =>\n            +lhs.Combine(SourceT.pure<M, A>(rhs.Value));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Operators/SourceT.Operators.Functor.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n    extension<M, A, B>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, B> operator *(Func<A, B> f, K<SourceT<M>, A> ma) =>\n            +ma.Map(f);\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, B> operator *(K<SourceT<M>, A> ma, Func<A, B> f) =>\n            +ma.Map(f);\n    }\n    \n    extension<M, A, B, C>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, C>> operator * (\n            Func<A, B, C> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, C>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C> f) =>\n            curry(f) * ma;\n    }\n        \n    extension<M, A, B, C, D>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, D>>> operator * (\n            Func<A, B, C, D> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, D>>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C, D> f) =>\n            curry(f) * ma;\n    }\n            \n    extension<M, A, B, C, D, E>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            Func<A, B, C, D, E> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, E>>>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C, D, E> f) =>\n            curry(f) * ma;\n    }\n                \n    extension<M, A, B, C, D, E, F>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            Func<A, B, C, D, E, F> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, F>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C, D, E, F> f) =>\n            curry(f) * ma;\n    }\n                    \n    extension<M, A, B, C, D, E, F, G>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            Func<A, B, C, D, E, F, G> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, G>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C, D, E, F, G> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, H>>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H> f) =>\n            curry(f) * ma;\n    }\n                        \n    extension<M, A, B, C, D, E, F, G, H, I>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, I>>>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I> f) =>\n            curry(f) * ma;\n    }    \n                        \n    extension<M, A, B, C, D, E, F, G, H, I, J>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, J>>>>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J> f) =>\n            curry(f) * ma;\n    }\n                            \n    extension<M, A, B, C, D, E, F, G, H, I, J, K>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            Func<A, B, C, D, E, F, G, H, I, J, K> f, \n            K<SourceT<M>, A> ma) =>\n            curry(f) * ma;\n        \n        /// <summary>\n        /// Functor map operator\n        /// </summary>\n        public static SourceT<M, Func<B, Func<C, Func<D, Func<E, Func<F, Func<G, Func<H, Func<I, Func<J, K>>>>>>>>>> operator * (\n            K<SourceT<M>, A> ma,\n            Func<A, B, C, D, E, F, G, H, I, J, K> f) =>\n            curry(f) * ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Operators/SourceT.Operators.Monad.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n    extension<M, A, B>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Monad bind operator\n        /// </summary>\n        /// <param name=\"ma\">Monad to bind</param>\n        /// <param name=\"f\">Binding function</param>\n        /// <returns>Mapped monad</returns>\n        public static SourceT<M, B> operator >> (K<SourceT<M>, A> ma, Func<A, K<SourceT<M>, B>> f) =>\n            +ma.Bind(f);\n        \n        /// <summary>\n        /// Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such\n        /// as the semicolon) in C#.\n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the second action</returns>\n        public static SourceT<M, B> operator >> (K<SourceT<M>, A> lhs, K<SourceT<M>, B> rhs) =>\n            lhs >> (_ => rhs);\n    }\n    \n    extension<M, A>(K<SourceT<M>, A> self)\n        where M : MonadIO<M>, Alternative<M>\n    {\n        /// <summary>\n        /// Sequentially compose two actions.  The second action is a unit-returning action, so the result of the\n        /// first action is propagated. \n        /// </summary>\n        /// <param name=\"lhs\">First action to run</param>\n        /// <param name=\"rhs\">Second action to run</param>\n        /// <returns>Result of the first action</returns>\n        public static SourceT<M, A> operator >> (K<SourceT<M>, A> lhs, K<SourceT<M>, Unit> rhs) =>\n            lhs >> (x => (_ => x) * rhs);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Operators/SourceT.Operators.Zip.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n    extension<M, A, B>(K<SourceT<M>, A>)\n        where M : MonadIO<M>, Fallible<M>\n    {\n        public static SourceT<M, (A First, B Second)> operator &(K<SourceT<M>, A> lhs, K<SourceT<M>, B> rhs) =>\n            +lhs.Zip(rhs);\n    }\n    \n    extension<M, A, B, C>(K<SourceT<M>, (A First, B Second)>)\n        where M : MonadIO<M>, Fallible<M>\n    {\n        public static SourceT<M, (A First, B Second, C Third)> operator &(K<SourceT<M>, (A First, B Second)> lhs, K<SourceT<M>, C> rhs) =>\n            +lhs.Zip(rhs).Map(s => (s.First.First, s.First.Second, s.Second));\n    }    \n    \n    extension<M, A, B, C, D>(K<SourceT<M>, (A First, B Second)>)\n        where M : MonadIO<M>, Fallible<M>\n    {\n        public static SourceT<M, (A First, B Second, C Third, D Fourth)> operator &(K<SourceT<M>, (A First, B Second)> lhs, K<SourceT<M>, (C First, D Second)> rhs) =>\n            +lhs.Zip(rhs).Map(s => (s.First.First, s.First.Second, s.Second.First, s.Second.Second));\n    }    \n    \n    extension<M, A, B, C, D>(K<SourceT<M>, (A First, B Second, C Third)>)\n        where M : MonadIO<M>, Fallible<M>\n    {\n        public static SourceT<M, (A First, B Second, C Third, D Fourth)> operator &(K<SourceT<M>, (A First, B Second, C Third)> lhs, K<SourceT<M>, D> rhs) =>\n            +lhs.Zip(rhs).Map(s => (s.First.First, s.First.Second, s.First.Third, s.Second));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Operators/SourceT.Operators.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static partial class SourceTExtensions\n{\n    extension<M, A>(K<SourceT<M>, A> _)\n        where M : MonadIO<M>\n    {\n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static SourceT<M, A> operator +(K<SourceT<M>, A> ma) =>\n            (SourceT<M, A>)ma;\n        \n        /// <summary>\n        /// Downcast operator\n        /// </summary>\n        public static SourceT<M, A> operator >> (K<SourceT<M>, A> ma, Lower lower) =>\n            +ma;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/SourceT.Module.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Threading.Channels;\nusing LanguageExt.Async.Linq;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nnamespace LanguageExt;\n\npublic partial class SourceT\n{\n    /// <summary>\n    /// Empty source\n    /// </summary>\n    /// <remarks>\n    /// This is a 'void' source, it yields zero values. \n    /// </remarks>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Uninhabited source</returns>\n    [Pure]\n    public static SourceT<M, A> empty<M, A>() \n        where M : MonadIO<M> =>\n        EmptySourceT<M, A>.Default;\n    \n    /// <summary>\n    /// Lift a pure value into the source\n    /// </summary>\n    /// <remarks>\n    /// This is a singleton/unit source, it yields exactly one value. \n    /// </remarks>\n    /// <param name=\"value\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Singleton source</returns>\n    [Pure]\n    public static SourceT<M, A> pure<M, A>(A value) \n        where M : MonadIO<M> =>\n        new PureSourceT<M, A>(value);\n\n    /// <summary>\n    /// Indicate the stream is complete\n    /// </summary>\n    /// <param name=\"value\"></param>\n    /// <typeparam name=\"M\"></typeparam>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    [Pure]\n    public static SourceT<M, Unit> done<M>() \n        where M : MonadIO<M> =>\n        new DoneSourceT<M>();\n    \n    /// <summary>\n    /// Lift a foldable of pure values into a `SourceT`\n    /// </summary>\n    /// <param name=\"fa\">Foldable of pure values</param>\n    /// <typeparam name=\"F\">Foldable trait type</typeparam>\n    /// <typeparam name=\"M\">Monad trait type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>`SourceT`</returns>\n    [Pure]\n    public static SourceT<M, A> liftFoldable<F, M, A>(K<F, A> fa)\n        where M : MonadIO<M>\n        where F : Foldable<F> =>\n        new FoldablePureSourceT<F, M, A>(fa);\n\n    /// <summary>\n    /// Lift a foldable of monadic values into a `SourceT`\n    /// </summary>\n    /// <param name=\"fma\">Foldable of monadic values</param>\n    /// <typeparam name=\"F\">Foldable trait type</typeparam>\n    /// <typeparam name=\"M\">Monad trait type</typeparam>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>`SourceT`</returns>\n    [Pure]\n    public static SourceT<M, A> liftFoldableM<F, M, A>(K<F, K<M, A>> fma)\n        where M : MonadIO<M>\n        where F : Foldable<F> =>\n        new FoldableSourceT<F, M, A>(fma);\n    \n    /// <summary>\n    /// Lift a structure into the source\n    /// </summary>\n    /// <remarks>\n    /// This is a singleton/unit source, it yields exactly one structure. \n    /// </remarks>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Singleton source</returns>\n    [Pure]\n    public static SourceT<M, A> liftM<M, A>(K<M, A> ma) \n        where M : MonadIO<M> =>\n        new LiftSourceT<M, A>(ma);\n    \n    /// <summary>\n    /// Lift a structure into the source\n    /// </summary>\n    /// <remarks>\n    /// This is a singleton/unit source, it yields exactly one structure. \n    /// </remarks>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Singleton source</returns>\n    [Pure]\n    public static SourceT<M, A> liftIO<M, A>(K<IO, A> ma) \n        where M : MonadIO<M> =>\n        new LiftSourceT<M, A>(M.LiftIO(ma));\n    \n    /// <summary>\n    /// Lift a pure value into the source and yield it for infinity\n    /// </summary>\n    /// <remarks>\n    /// This is an infinite source, it repeatedly yields a value. \n    /// </remarks>\n    /// <param name=\"value\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Infinite source</returns>\n    [Pure]\n    public static SourceT<M, A> forever<M, A>(A value) \n        where M : MonadIO<M> =>\n        new ForeverSourceT<M, A>(M.Pure(value));\n    \n    /// <summary>\n    /// Lift a structure into the source and yield it for infinity\n    /// </summary>\n    /// <remarks>\n    /// This is an infinite source, it repeatedly yields the provided structure. \n    /// </remarks>\n    /// <param name=\"ma\">Value to lift</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Infinite source</returns>\n    [Pure]\n    public static SourceT<M, A> foreverM<M, A>(K<M, A> ma) \n        where M : MonadIO<M> =>\n        new ForeverSourceT<M, A>(ma);\n\n    /// <summary>\n    /// Make a `System.Threading.Channels.Channel` into a source of values\n    /// </summary>\n    /// <param name=\"channel\">Channel to lift</param>\n    /// <param name=\"label\">Label to help debugging</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> lift<M, A>(Channel<A> channel) \n        where M : MonadIO<M>, Fallible<M> =>\n        new MultiListenerPureSourceT<M, A>(channel);\n\n    /// <summary>\n    /// Make a `System.Threading.Channels.Channel` into a source of values\n    /// </summary>\n    /// <param name=\"channel\">Channel to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> liftM<M, A>(Channel<K<M, A>> channel) \n        where M : MonadIO<M>, Fallible<M> =>\n        new MultiListenerSourceT<M, A>(channel);\n\n    /// <summary>\n    /// Make a `Source` into a `SourceT`\n    /// </summary>\n    /// <param name=\"channel\">Channel to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> lift<M, A>(Source<A> channel) \n        where M : MonadIO<M> =>\n        new SourcePureSourceT<M, A>(channel);\n\n    /// <summary>\n    /// Make a `Source` into a `SourceT`\n    /// </summary>\n    /// <param name=\"channel\">Channel to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> liftM<M, A>(Source<K<M, A>> channel) \n        where M : MonadIO<M> =>\n        new SourceSourceT<M, A>(channel);\n\n    /// <summary>\n    /// Make an `IEnumerable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">Enumerable to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> lift<M, A>(IEnumerable<A> items) \n        where M : MonadIO<M> =>\n        new IteratorSyncSourceT<M, A>(items.Select(M.Pure));\n\n    /// <summary>\n    /// Make an `IEnumerable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">Enumerable to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> liftM<M, A>(IEnumerable<K<M, A>> items) \n        where M : MonadIO<M> =>\n        new IteratorSyncSourceT<M, A>(items);\n\n    /// <summary>\n    /// Make an `IObservable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">`IObservable` to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> lift<M, A>(IObservable<A> items) \n        where M : MonadIO<M> =>\n        new ObservablePureSourceT<M, A>(items);\n\n    /// <summary>\n    /// Make an `IObservable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">`IObservable` to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> liftM<M, A>(IObservable<K<M, A>> items) \n        where M : MonadIO<M> =>\n        new ObservableSourceT<M, A>(items);\n\n    /// <summary>\n    /// Make an `IAsyncEnumerable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">`IAsyncEnumerable` to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> lift<M, A>(IAsyncEnumerable<A> items) \n        where M : MonadIO<M> =>\n        new IteratorAsyncSourceT<M, A>(items.Select(M.Pure));\n\n    /// <summary>\n    /// Make an `IAsyncEnumerable` into a source of values\n    /// </summary>\n    /// <param name=\"items\">`IAsyncEnumerable` to lift</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Source of values</returns>\n    [Pure]\n    public static SourceT<M, A> liftM<M, A>(IAsyncEnumerable<K<M, A>> items) \n        where M : MonadIO<M> =>\n        new IteratorAsyncSourceT<M, A>(items);\n    \n    /// <summary>\n    /// Merge sources into a single source\n    /// </summary>\n    /// <param name=\"sources\">Sources</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Source that is the combination of all provided sources</returns>\n    [Pure]\n    public static SourceT<M, A> merge<M, A>(Seq<SourceT<M, A>> sources) \n        where M : MonadIO<M>, Fallible<M> =>\n        sources.Fold(empty<M, A>(), (s, s2) => s.Choose(s2));\n        \n    /// <summary>\n    /// Merge sources into a single source\n    /// </summary>\n    /// <param name=\"sources\">Sources</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Source that is the combination of all provided sources</returns>\n    [Pure]\n    public static SourceT<M, A> merge<M, A>(params SourceT<M, A>[] sources) \n        where M : MonadIO<M>, Fallible<M> =>\n        merge(toSeq(sources));\n\n    /// <summary>\n    /// Zip two sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    [Pure]\n    public static SourceT<M, (A First, B Second)> zip<M, A, B>(SourceT<M, A> first, SourceT<M, B> second) \n        where M : MonadUnliftIO<M>, Fallible<Error, M> =>\n        new Zip2SourceT<M, A, B>(first, second);\n\n    /// <summary>\n    /// Zip three sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <param name=\"third\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    [Pure]\n    public static SourceT<M, (A First, B Second, C Third)> zip<M, A, B, C>(SourceT<M, A> first, SourceT<M, B> second, SourceT<M, C> third) \n        where M : MonadUnliftIO<M>, Fallible<Error, M> =>\n        new Zip3SourceT<M, A, B, C>(first, second, third);\n\n    /// <summary>\n    /// Zip three sources into one\n    /// </summary>\n    /// <param name=\"second\">Stream to zip with this one</param>\n    /// <param name=\"third\">Stream to zip with this one</param>\n    /// <param name=\"fourth\">Stream to zip with this one</param>\n    /// <typeparam name=\"B\">Bound value-type of the stream to zip with this one</typeparam>\n    /// <returns>Stream of values where the items from two streams are paired together</returns>\n    [Pure]\n    public static SourceT<M, (A First, B Second, C Third, D Fourth)> zip<M, A, B, C, D>(SourceT<M, A> first, SourceT<M, B> second, SourceT<M, C> third, SourceT<M, D> fourth) \n        where M : MonadUnliftIO<M>, Fallible<Error, M> =>\n        new Zip4SourceT<M, A, B, C, D>(first, second, third, fourth);\n\n    /// <summary>\n    /// Reduce the stream into a unit value.\n    /// </summary>\n    [Pure]\n    public static K<M, Unit> iter<M, A>(K<SourceT<M>, A> ma) \n        where M : MonadIO<M> =>\n        ma.Iter();\n\n    /// <summary>\n    /// Reduce the stream by collecting all the values into a `Seq` while the predicate holds.\n    /// </summary>\n    [Pure]\n    public static K<M, Seq<A>> collectWhile<M, A>(K<SourceT<M>, A> ma, Func<(Seq<A> Items, A Item), bool> predicate) \n        where M : MonadIO<M> =>\n        ma.CollectWhile(predicate);\n\n    /// <summary>\n    /// Reduce the stream by collecting all the values into a `Seq` while the predicate holds.\n    /// </summary>\n    [Pure]\n    public static K<M, Seq<A>> collectUntil<M, A>(K<SourceT<M>, A> ma, Func<(Seq<A> Items, A Item), bool> predicate) \n        where M : MonadIO<M> =>\n        ma.CollectUntil(predicate);\n\n    /// <summary>\n    /// Reduce the stream by collecting all the values into a `Seq`.\n    /// </summary>\n    [Pure]\n    public static K<M, Seq<A>> collect<M, A>(K<SourceT<M>, A> ma) \n        where M : MonadIO<M> =>\n        ma.Collect();\n    \n    /// <summary>\n    /// Reduce the stream, yielding the last structure processed, or the `None` if the stream is empty\n    /// </summary>\n    [Pure]\n    public static K<M, Option<A>> lastOrNone<M, A>(K<SourceT<M>, A> ma) \n        where M : MonadIO<M> =>\n        ma.LastOrNone();\n    \n    /// <summary>\n    /// Reduce the stream, yielding the first structure processed, or the `None` if the stream is empty\n    /// </summary>\n    [Pure]\n    public static K<M, Option<A>> firstOrNone<M, A>(K<SourceT<M>, A> ma) \n        where M : MonadIO<M> =>\n        ma.FirstOrNone();\n    \n    /// <summary>\n    /// Reduce the stream, yielding the last structure processed, or the default value if the stream is empty\n    /// </summary>\n    [Pure]\n    public static K<M, A> last<M, A>(K<SourceT<M>, A> ma, A defaultValue) \n        where M : MonadIO<M> =>\n        ma.Last(defaultValue);\n\n    /// <summary>\n    /// Reduce the stream, yielding the first structure processed, or the default value if the stream is empty\n    /// </summary>\n    [Pure]\n    public static K<M, A> first<M, A>(K<SourceT<M>, A> ma, A defaultValue) \n        where M : MonadIO<M> =>\n        ma.First(defaultValue);\n    \n    /// <summary>\n    /// Reduce the stream, yielding the last structure processed, or `M.Empty` if the stream is empty\n    /// </summary>\n    [Pure]\n    public static K<M, A> last<M, A>(K<SourceT<M>, A> ma) \n        where M : MonadIO<M>, Alternative<M> =>\n        ma.Last();\n    \n    /// <summary>\n    /// Reduce the stream, yielding the first structure processed, or `M.Empty` if the stream is empty\n    /// </summary>\n    [Pure]\n    public static K<M, A> first<M, A>(K<SourceT<M>, A> ma)\n        where M : MonadIO<M>, Alternative<M> =>\n        ma.First();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/SourceT.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// A source / stream of lifted values\n/// </summary>\n/// <typeparam name=\"A\">Bound value type</typeparam>\npublic abstract record SourceT<M, A> : \n    K<SourceT<M>, A>, \n    Monoid<SourceT<M, A>>\n    where M : MonadIO<M>\n{\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.  This is returned lifted. \n    /// </summary>\n    /// <remarks>Note, this is recursive, so `M` needs to be able to support recursion without\n    /// blowing the stack.  If you have the `IO` monad in your stack, then this will automatically\n    /// be the case.</remarks>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Lifted aggregate state</returns>\n    public K<M, S> Reduce<S>(S state, Reducer<A, S> reducer) =>\n        ReduceM(state, (s, x) => M.Pure(reducer(s, x)));\n    \n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.  This is returned lifted. \n    /// </summary>\n    /// <remarks>Note, this is recursive, so `M` needs to be able to support recursion without\n    /// blowing the stack.  If you have the `IO` monad in your stack, then this will automatically\n    /// be the case.</remarks>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Lifted aggregate state</returns>\n    public K<M, S> FoldReduce<S>(S state, Func<S, A, S> reducer) =>\n        ReduceM(state, (s, x) => M.Pure(Reduced.Continue(reducer(s, x))));\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.  This is returned lifted. \n    /// </summary>\n    /// <remarks>Note, this is recursive, so `M` needs to be able to support recursion without\n    /// blowing the stack.  If you have the `IO` monad in your stack, then this will automatically\n    /// be the case.</remarks>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Lifted aggregate state</returns>\n    public K<M, S> ReduceM<S>(S state, ReducerM<M, A, S> reducer) =>\n        M.Token >> (t => M.BracketIOMaybe(\n                        ReduceInternalM(state,\n                                        (s, mx) => t.IsCancellationRequested\n                                                       ? M.Pure(Reduced.Done(s))\n                                                       : mx.Bind(x => reducer(s, x)))\n                           .Map(r => r.Value)));\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.  This is returned lifted. \n    /// </summary>\n    /// <remarks>Note, this is recursive, so `M` needs to be able to support recursion without\n    /// blowing the stack.  If you have the `IO` monad in your stack, then this will automatically\n    /// be the case.</remarks>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Lifted aggregate state</returns>\n    public K<M, S> FoldReduceM<S>(S state, Func<S, A, K<M, S>> reducer) =>\n        M.Token >> (t => M.BracketIOMaybe(\n                        ReduceInternalM(\n                                state,\n                                (s, mx) => t.IsCancellationRequested\n                                               ? M.Pure(Reduced.Done(s))\n                                               : mx.Bind(x => reducer(s, x).Map(Reduced.Continue)))\n                           .Map(r => r.Value)));\n    \n    /// <summary>\n    /// A source that never yields a value\n    /// </summary>\n    public static SourceT<M, A> Empty =>\n        EmptySourceT<M, A>.Default;\n\n    /// <summary>\n    /// Transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Transformed source</returns>\n    public SourceT<M, B> Transform<B>(Transducer<A, B> transducer) =>\n        new TransformSourceT2<M, A, B>(this, transducer);\n\n    /// <summary>\n    /// Transform with a transducer\n    /// </summary>\n    /// <param name=\"transducer\">Transducer to use to transform</param>\n    /// <typeparam name=\"B\">Target bound value type</typeparam>\n    /// <returns>Transformed source</returns>\n    public SourceT<M, B> Transform<B>(TransducerM<M, A, B> transducer) =>\n        new TransformSourceT<M, A, B>(this, transducer);\n    \n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public virtual SourceT<M, B> Map<B>(Func<A, B> f) =>\n        new MapSourceT<M,A,B>(this, f);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public virtual SourceT<M, B> Bind<B>(Func<A, SourceT<M, B>> f) =>\n        new BindSourceT<M, A, B>(this, f);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public SourceT<M, B> Bind<B>(Func<A, K<SourceT<M>, B>> f) =>\n        Bind(x => f(x).As());\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public virtual SourceT<M, B> Bind<B>(Func<A, IO<B>> f) =>\n        new BindSourceT<M, A, B>(this, x => SourceT.liftIO<M, B>(f(x)));\n    \n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>SourceT where the only values yield are those that pass the predicate</returns>\n    public SourceT<M, A> Where(Func<A, bool> f) =>\n        new FilterSourceT<M, A>(this, f);\n    \n    /// <summary>\n    /// Filter values.  Yielding downstream when `true`\n    /// </summary>\n    /// <param name=\"f\">Filter function</param>\n    /// <returns>SourceT where the only values yield are those that pass the predicate</returns>\n    public SourceT<M, A> Filter(Func<A, bool> f) =>\n        new FilterSourceT<M, A>(this, f);\n\n    /// <summary>\n    /// Applicative apply\n    /// </summary>\n    public virtual SourceT<M, B> ApplyBack<B>(SourceT<M, Func<A, B>> ff) =>\n        ff >> Map >> lower;\n\n    /// <summary>\n    /// Concatenate streams \n    /// </summary>\n    /// <param name=\"this\">Left-hand side</param>\n    /// <param name=\"rhs\">Right-hand side</param>\n    /// <returns>A stream that concatenates the input streams</returns>\n    public SourceT<M, A> Combine(SourceT<M, A> rhs) =>\n        (this, rhs) switch\n        {\n            (EmptySourceT<M, A>, EmptySourceT<M, A>)         => EmptySourceT<M, A>.Default,\n            (var l, EmptySourceT<M, A>)                      => l,\n            (EmptySourceT<M, A>, var r)                      => r,\n            (CombineSourceT<M, A> l, CombineSourceT<M, A> r) => new CombineSourceT<M, A>(l.Sources + r.Sources),\n            (CombineSourceT<M, A> l, var r)                  => new CombineSourceT<M, A>(l.Sources.Add(r)),\n            (var l, CombineSourceT<M, A> r)                  => new CombineSourceT<M, A>(l.Cons(r.Sources)),\n            _                                                => new CombineSourceT<M, A>([this, rhs])\n        };\n\n    /// <summary>\n    /// Skip items in the source\n    /// </summary>\n    /// <param name=\"amount\">Amount to skip</param>\n    /// <returns>Transformed source</returns>\n    public SourceT<M, A> Skip(int amount) =>\n        Transform(TransducerM.skip<M, A>(amount)); \n\n    /// <summary>\n    /// Limit the number of items processed \n    /// </summary>\n    /// <param name=\"amount\">Amount to take</param>\n    /// <returns>Transformed source</returns>\n    public SourceT<M, A> Take(int amount) =>\n        new TakeSourceT<M, A>(this, amount);\n\n    /// <summary>\n    /// Fold the values flowing through.  A value is only yielded downstream upon completion of the stream.\n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate state</returns>\n    public SourceT<M, S> Fold<S>(Func<S, A, S> Fold, S Init) =>\n        new FoldWhileSourceT<M, A, S>(this, Schedule.Forever, Fold, _ => true, Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, or the\n    /// source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public SourceT<M, S> Fold<S>(Schedule Time, Func<S, A, S> Fold, S Init) =>\n        new FoldWhileSourceT<M, A, S>(this, Time, Fold, _ => true, Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public SourceT<M, S> FoldWhile<S>(Func<S, A, S> Fold, Func<(S State, A Value), bool> Pred, S Init) =>\n        new FoldWhileSourceT<M, A, S>(this, Schedule.Forever, Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the predicate returns\n    /// `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public SourceT<M, S> FoldUntil<S>(Func<S, A, S> Fold, Func<(S State, A Value), bool> Pred, S Init) =>\n        new FoldUntilSourceT<M, A, S>(this, Schedule.Forever, Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `false`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public SourceT<M, S> FoldWhile<S>(\n        Schedule Time,\n        Func<S, A, S> Fold,\n        Func<(S State, A Value), bool> Pred,\n        S Init) =>\n        new FoldWhileSourceT<M, A, S>(this, Time, Fold, Pred, Init);\n\n    /// <summary>\n    /// Fold the values flowing through.  Values are yielded downstream when either the schedule expires, the\n    /// predicate returns `true`, or the source completes. \n    /// </summary>\n    /// <param name=\"Time\">Schedule to control the rate of processing</param>\n    /// <param name=\"Fold\">Binary operator</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"Init\">Initial state</param>\n    /// <typeparam name=\"S\"></typeparam>\n    /// <returns>Stream of aggregate states</returns>\n    public SourceT<M, S> FoldUntil<S>(\n        Schedule Time,\n        Func<S, A, S> Fold, \n        Func<(S State, A Value), bool> Pred, \n        S Init) =>\n        new FoldUntilSourceT<M, A, S>(this, Time, Fold, Pred, Init);\n\n    /// <summary>\n    /// Convert `SourceT` to a `ProducerT` pipe component\n    /// </summary>\n    /// <typeparam name=\"M\">Monad to lift (must support `IO`)</typeparam>\n    /// <returns>`ProducerT`</returns>\n    public ProducerT<A, M, Unit> ToProducerT() =>\n        ProducerT.yieldAll(this);\n    \n    /// <summary>\n    /// Sequentially compose two actions.  The second action is a unit returning action, so the result of the\n    /// first action is propagated. \n    /// </summary>\n    /// <param name=\"lhs\">First action to run</param>\n    /// <param name=\"rhs\">Second action to run</param>\n    /// <returns>Result of the first action</returns>\n    public static SourceT<M, A> operator >> (SourceT<M, A> lhs, K<SourceT<M>, Unit> rhs) =>\n        lhs.Bind(x => rhs.Map(_ => x));\n    \n    public static implicit operator SourceT<M, A>(IO<A> ma) =>\n        SourceT.liftIO<M, A>(ma);\n    \n    public static implicit operator SourceT<M, A>(Pure<A> ma) =>\n        SourceT.liftM(M.Pure(ma.Value));\n\n    public static implicit operator SourceT<M, A>(Fail<Error> ma) =>\n        IO.fail<A>(ma.Value);\n\n    /// <summary>\n    /// Functor map\n    /// </summary>\n    public SourceT<M, B> Select<B>(Func<A, B> f) =>\n        Map(f);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public SourceT<M, C> SelectMany<B, C>(Func<A, SourceT<M, B>> bind, Func<A, B, C> project) =>\n        Bind(a => bind(a).Map(b => project(a, b)));\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public SourceT<M, C> SelectMany<B, C>(Func<A, K<M, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => SourceT.liftM(bind(x)), project);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public SourceT<M, C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        SelectMany(a => SourceT.liftIO<M, B>(bind(a)), project);\n    \n    /// <summary>\n    /// Monad bind\n    /// </summary>\n    public SourceT<M, C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(a => project(a, bind(a).Value));\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    // Internal\n    //\n\n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.  This is returned lifted. \n    /// </summary>\n    /// <remarks>Note, this is recursive, so `M` needs to be able to support recursion without\n    /// blowing the stack.  If you have the `IO` monad in your stack, then this will automatically\n    /// be the case.</remarks>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Lifted aggregate state</returns>\n    public K<M, Reduced<S>> ReduceInternal<S>(S state, ReducerM<M, A, S> reducer) =>\n        ReduceInternalM(state, (s, mx) => mx.Bind(x => reducer(s, x)));\n    \n    /// <summary>\n    /// Iterate the stream, flowing values downstream to the reducer, which aggregates a\n    /// result value.  This is returned lifted. \n    /// </summary>\n    /// <remarks>Note, this is recursive, so `M` needs to be able to support recursion without\n    /// blowing the stack.  If you have the `IO` monad in your stack, then this will automatically\n    /// be the case.</remarks>\n    /// <param name=\"state\">Initial state</param>\n    /// <param name=\"reducer\">Reducer</param>\n    /// <typeparam name=\"S\">State type</typeparam>\n    /// <returns>Lifted aggregate state</returns>\n    internal abstract K<M, Reduced<S>> ReduceInternalM<S>(S state, ReducerM<M, K<M, A>, S> reducer);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/SourceT/Trait/SourceT.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic partial class SourceT<M> :\n    MonoidK<SourceT<M>>,\n    MonadUnliftIO<SourceT<M>>\n    where M : MonadIO<M>\n{\n    static K<SourceT<M>, B> Monad<SourceT<M>>.Bind<A, B>(K<SourceT<M>, A> ma, Func<A, K<SourceT<M>, B>> f) => \n        ma.As().Bind(f);\n\n    static K<SourceT<M>, B> Monad<SourceT<M>>.Recur<A, B>(A value, Func<A, K<SourceT<M>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<SourceT<M>, B> Functor<SourceT<M>>.Map<A, B>(Func<A, B> f, K<SourceT<M>, A> ma) => \n        ma.As().Map(f);\n\n    static K<SourceT<M>, A> Applicative<SourceT<M>>.Pure<A>(A value) =>\n        new PureSourceT<M, A>(value);\n\n    static K<SourceT<M>, B> Applicative<SourceT<M>>.Apply<A, B>(K<SourceT<M>, Func<A, B>> mf, K<SourceT<M>, A> ma) =>\n        mf >> ma.Map;\n\n    static K<SourceT<M>, B> Applicative<SourceT<M>>.Apply<A, B>(K<SourceT<M>, Func<A, B>> mf, Memo<SourceT<M>, A> ma) =>\n        mf >> ma.Map;\n\n    static K<SourceT<M>, A> SemigroupK<SourceT<M>>.Combine<A>(K<SourceT<M>, A> fa, K<SourceT<M>, A> fb) =>\n        fa.As().Combine(fb.As());\n\n    static K<SourceT<M>, A> MonoidK<SourceT<M>>.Empty<A>() =>\n        EmptySourceT<M ,A>.Default;\n\n    static K<SourceT<M>, A> MonadIO<SourceT<M>>.LiftIO<A>(IO<A> ma) =>\n        SourceT.liftIO<M, A>(ma);\n\n    static K<SourceT<M>, IO<A>> MonadUnliftIO<SourceT<M>>.ToIO<A>(K<SourceT<M>, A> ma) => \n        new ToIOSourceT<M, A>(ma.As());\n\n    static K<SourceT<M>, B> MonadUnliftIO<SourceT<M>>.MapIO<A, B>(K<SourceT<M>, A> ma, Func<IO<A>, IO<B>> f) =>\n        new MapIOSourceT<M, A, B>(ma.As(), f);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Reduced.cs",
    "content": "using System;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Result of a `Reducer` delegate\n/// </summary>\npublic readonly record struct Reduced<A>(bool Continue, A Value)\n{\n    public Reduced<B> Map<B>(Func<A, B> f) =>\n        new (Continue, f(Value));\n}\n\n/// <summary>\n/// `Reduced〈A〉` constructors\n/// </summary>\npublic static class Reduced\n{\n    static Reduced()\n    {\n        Unit = Continue<Unit>(default);\n        UnitAsync = new ValueTask<Reduced<Unit>>(Unit);\n    }\n    \n    /// <summary>\n    /// Return a result and indicate that we're happy to continue\n    /// </summary>\n    /// <param name=\"value\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`Reduced` structure in a continue state</returns>\n    public static Reduced<A> Continue<A>(A value) =>\n        new(true, value);\n    \n    /// <summary>\n    /// Return a result and indicate that we're done and don't want to process any more\n    /// </summary>\n    /// <param name=\"value\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`Reduced` structure in a done state</returns>\n    public static Reduced<A> Done<A>(A value) =>\n        new(false, value);\n\n    /// <summary>\n    /// `Reduced〈A〉` in a continue state\n    /// </summary>\n    public static readonly Reduced<Unit> Unit;\n    \n    /// <summary>\n    /// Return a result and indicate that we're happy to continue\n    /// </summary>\n    /// <param name=\"value\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`Reduced` structure in a continue state</returns>\n    public static IO<Reduced<A>> ContinueIO<A>(A value) =>\n        IO.pure(new Reduced<A>(true, value));\n    \n    /// <summary>\n    /// Return a result and indicate that we're done and don't want to process any more\n    /// </summary>\n    /// <param name=\"value\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`Reduced` structure in a done state</returns>\n    public static IO<Reduced<A>> DoneIO<A>(A value) =>\n        IO.pure(new Reduced<A>(false, value));\n\n    /// <summary>\n    /// `Reduced〈A〉` in a continue state\n    /// </summary>\n    public static readonly ValueTask<Reduced<Unit>> UnitAsync;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/ReducedM.cs",
    "content": "using System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Result of a `Reducer` delegate\n/// </summary>\npublic readonly record struct ReducedM<M, A>(bool Continue, K<M, A> Value);\n\n/// <summary>\n/// `Reduced〈A〉` constructors\n/// </summary>\npublic static class ReducedM\n{\n    /// <summary>\n    /// Return a result and indicate that we're happy to continue\n    /// </summary>\n    /// <param name=\"value\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`ReducedM` structure in a continue state</returns>\n    public static ReducedM<M, A> Continue<M, A>(A value) \n        where M : Applicative<M> =>\n        new(true, M.Pure(value));\n    \n    /// <summary>\n    /// Return a result and indicate that we're happy to continue\n    /// </summary>\n    /// <param name=\"ma\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`ReducedM` structure in a continue state</returns>\n    public static ReducedM<M, A> Continue<M, A>(K<M, A> ma) \n        where M : Applicative<M> =>\n        new(true, ma);\n    \n    /// <summary>\n    /// Return a result and indicate that we're done and don't want to process any more\n    /// </summary>\n    /// <param name=\"value\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`ReducedM` structure in a done state</returns>\n    public static ReducedM<M, A> Done<M, A>(A value) \n        where M : Applicative<M> =>\n        new(false, M.Pure(value));\n    \n    /// <summary>\n    /// Return a result and indicate that we're done and don't want to process any more\n    /// </summary>\n    /// <param name=\"ma\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`ReducedM` structure in a done state</returns>\n    public static ReducedM<M, A> Done<M, A>(K<M, A> ma) \n        where M : Applicative<M> =>\n        new(false, ma);\n\n    /// <summary>\n    /// `ReducedM〈A〉` in a continue state\n    /// </summary>\n    public static ReducedM<M, Unit> Unit<M>() \n        where M : Applicative<M> =>\n        ReducedMInternal<M>.Unit;\n    \n    /// <summary>\n    /// Return a result and indicate that we're happy to continue\n    /// </summary>\n    /// <param name=\"value\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`ReducedM` structure in a continue state</returns>\n    public static ValueTask<ReducedM<M, A>> ContinueAsync<M, A>(A value) \n        where M : Applicative<M> =>\n        new(new ReducedM<M, A>(true, M.Pure(value)));\n    \n    /// <summary>\n    /// Return a result and indicate that we're happy to continue\n    /// </summary>\n    /// <param name=\"ma\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`ReducedM` structure in a continue state</returns>\n    public static ValueTask<ReducedM<M, A>> ContinueAsync<M, A>(K<M, A> ma) \n        where M : Applicative<M> =>\n        new(new ReducedM<M, A>(true, ma));\n    \n    /// <summary>\n    /// Return a result and indicate that we're done and don't want to process any more\n    /// </summary>\n    /// <param name=\"value\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`ReducedM` structure in a done state</returns>\n    public static ValueTask<ReducedM<M, A>> DoneAsync<M, A>(A value) \n        where M : Applicative<M> =>\n        new(new ReducedM<M, A>(false, M.Pure(value)));\n    \n    /// <summary>\n    /// Return a result and indicate that we're done and don't want to process any more\n    /// </summary>\n    /// <param name=\"ma\">Result</param>\n    /// <typeparam name=\"A\">Result value type</typeparam>\n    /// <returns>`ReducedM` structure in a done state</returns>\n    public static ValueTask<ReducedM<M, A>> DoneAsync<M, A>(K<M, A> ma) \n        where M : Applicative<M> =>\n        new(new ReducedM<M, A>(false, ma));\n\n    /// <summary>\n    /// `ReducedM〈A〉` in a continue state\n    /// </summary>\n    public static ValueTask<ReducedM<M, Unit>> UnitAsync<M>()\n        where M : Applicative<M> =>\n        ReducedMInternal<M>.UnitAsync;\n}\n\n/// <summary>\n/// `Reduced〈A〉` constructors\n/// </summary>\nstatic class ReducedMInternal<M>\n    where M : Applicative<M>\n{\n    static ReducedMInternal()\n    {\n        Unit = new ReducedM<M, Unit>(true, M.Pure<Unit>(default));\n        UnitAsync = new ValueTask<ReducedM<M, Unit>>(Unit);\n    }\n\n    /// <summary>\n    /// `ReducedM〈A〉` in a continue state\n    /// </summary>\n    public static readonly ReducedM<M, Unit> Unit;\n    \n    /// <summary>\n    /// `ReducedM〈A〉` in a continue state\n    /// </summary>\n    public static readonly ValueTask<ReducedM<M, Unit>> UnitAsync;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Reducer.cs",
    "content": "using System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// Reducer delegate\n/// </summary>\n/// <typeparam name=\"S\">State</typeparam>\n/// <typeparam name=\"A\">Value</typeparam>\npublic delegate Reduced<S> Reducer<in A, S>(S state, A input);\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/ReducerIO.cs",
    "content": "using System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// ReducerAsync delegate\n/// </summary>\n/// <typeparam name=\"S\">State</typeparam>\n/// <typeparam name=\"A\">Value</typeparam>\npublic delegate IO<Reduced<S>> ReducerIO<in A, S>(S state, A input);\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/ReducerM.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n/// <summary>\n/// ReducerM delegate\n/// </summary>\n/// <typeparam name=\"S\">State</typeparam>\n/// <typeparam name=\"A\">Value</typeparam>\npublic delegate K<M, Reduced<S>> ReducerM<in M, in A, S>(S state, A input);\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/BindTransducer.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord BindTransducer1<Env, A, B>(Transducer<Env, A> First, Func<A, K<TransduceFrom<Env>, B>> F) : \n    Transducer<Env, B> \n{\n    public override ReducerIO<Env, S> Reduce<S>(ReducerIO<B, S> reducer) =>\n        (s, env) => First.Reduce<S>(\n            (s1, x) =>\n                F(x).As().Reduce(reducer)(s1, env))(s, env);\n\n    public override TransducerM<M, Env, B> Lift<M>() =>\n        new BindTransducerM1<M, Env, A, B>(First.Lift<M>(), x => F(x).As().Lift<M>());\n}\n\nrecord BindTransducer2<Env, A, B>(Transducer<Env, A> First, Func<A, Transducer<Env, B>> F) : \n    Transducer<Env, B> \n{\n    public override ReducerIO<Env, S> Reduce<S>(ReducerIO<B, S> reducer) =>\n        (s, env) => First.Reduce<S>(\n            (s1, x) =>\n                F(x).Reduce(reducer)(s1, env))(s, env);\n\n    public override TransducerM<M, Env, B> Lift<M>() =>\n        new BindTransducerM2<M, Env, A, B>(First.Lift<M>(), x => F(x).Lift<M>());\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/ComposeTransducer.cs",
    "content": "using System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord ComposeTransducer<A, B, C>(Transducer<A, B> TF, Transducer<B, C> TG) : \n    Transducer<A, C> \n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<C, S> reducer) =>\n        (s, x) => TF.Reduce<S>((s1, y) =>  TG.Reduce(reducer)(s1, y))(s, x);\n\n    public override Transducer<A, D> Compose<D>(Transducer<C, D> t) =>\n        new ComposeTransducer<A, B, C, D>(TF, TG, t);\n\n    public override TransducerM<M, A, C> Lift<M>() =>\n        new ComposeTransducerM<M, A, B, C>(TF.Lift<M>(), TG.Lift<M>());\n}\n\nrecord ComposeTransducer<A, B, C, D>(Transducer<A, B> TF, Transducer<B, C> TG, Transducer<C, D> TH) : \n    Transducer<A, D>\n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<D, S> reducer) =>\n        (s, x) => TF.Reduce<S>((s1, y) => TG.Reduce<S>((s2, z) => TH.Reduce(reducer)(s2, z))(s1, y))(s, x);\n\n    public override Transducer<A, E> Compose<E>(Transducer<D, E> t) =>\n        new ComposeTransducer<A, B, C, D, E>(TF, TG, TH, t);\n    \n    public override TransducerM<M, A, D> Lift<M>() =>\n        new ComposeTransducerM<M, A, B, C, D>(TF.Lift<M>(), TG.Lift<M>(), TH.Lift<M>());\n}\n\nrecord ComposeTransducer<A, B, C, D, E>(\n    Transducer<A, B> TF, \n    Transducer<B, C> TG, \n    Transducer<C, D> TH, \n    Transducer<D, E> TI) : \n    Transducer<A, E>\n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<E, S> reducer) =>\n        (s, w) => TF.Reduce<S>(\n                (s1, x) => TG.Reduce<S>(\n                        (s2, y) => TH.Reduce<S>(\n                                (s3, z) => TI.Reduce(reducer)(s3, z))\n                            (s2, y))\n                    (s1, x))\n            (s, w);\n\n    public override Transducer<A, F> Compose<F>(Transducer<E, F> t) =>\n        new ComposeTransducer<A, B, C, D, E, F>(TF, TG, TH, TI, t);\n    \n    public override TransducerM<M, A, E> Lift<M>() =>\n        new ComposeTransducerM<M, A, B, C, D, E>(TF.Lift<M>(), TG.Lift<M>(), TH.Lift<M>(), TI.Lift<M>());\n}\n\nrecord ComposeTransducer<A, B, C, D, E, F>(\n    Transducer<A, B> TF, \n    Transducer<B, C> TG, \n    Transducer<C, D> TH, \n    Transducer<D, E> TI, \n    Transducer<E, F> TJ) : \n    Transducer<A, F>\n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<F, S> reducer) =>\n        (s, v) => TF.Reduce<S>(\n                (s1, w) => TG.Reduce<S>(\n                        (s2, x) => TH.Reduce<S>(\n                                (s3, y) => TI.Reduce<S>(\n                                        (s4, z) => TJ.Reduce(reducer)(s4, z))\n                                    (s3, y))\n                            (s2, x))\n                    (s1, w))\n            (s, v);\n\n    public override Transducer<A, G> Compose<G>(Transducer<F, G> t) =>\n        new ComposeTransducer<A, B, C, D, E, F, G>(TF, TG, TH, TI, TJ, t);\n    \n    public override TransducerM<M, A, F> Lift<M>() =>\n        new ComposeTransducerM<M, A, B, C, D, E, F>(TF.Lift<M>(), TG.Lift<M>(), TH.Lift<M>(), TI.Lift<M>(), TJ.Lift<M>());\n}\n\nrecord ComposeTransducer<A, B, C, D, E, F, G>(\n    Transducer<A, B> TF, \n    Transducer<B, C> TG, \n    Transducer<C, D> TH, \n    Transducer<D, E> TI, \n    Transducer<E, F> TJ, \n    Transducer<F, G> TK) : \n    Transducer<A, G>\n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<G, S> reducer) =>\n        (s, u) => TF.Reduce<S>(\n                (s1, v) => TG.Reduce<S>(\n                        (s2, w) => TH.Reduce<S>(\n                                (s3, x) => TI.Reduce<S>(\n                                        (s4, y) => TJ.Reduce<S>(\n                                                (s5, z) => TK.Reduce(reducer)(s5, z))\n                                            (s4, y))\n                                    (s3, x))\n                            (s2, w))\n                    (s1, v))\n            (s, u);\n    \n    public override TransducerM<M, A, G> Lift<M>() =>\n        new ComposeTransducerM<M, A, B, C, D, E, F, G>(TF.Lift<M>(), TG.Lift<M>(), TH.Lift<M>(), TI.Lift<M>(), TJ.Lift<M>(), TK.Lift<M>());\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/ConstTransducer.cs",
    "content": "namespace LanguageExt;\n\nrecord ConstTransducer<A, B>(B Value) : Transducer<A, B> \n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<B, S> reducer) =>\n        (s, _) => reducer(s, Value);\n\n    public override TransducerM<M, A, B> Lift<M>() => \n        new ConstTransducerM<M, A, B>(Value);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/FilterTransducer.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FilterTransducer<A>(Func<A, bool> Predicate) : Transducer<A, A>\n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<A, S> reducer) =>\n        (s, x) =>\n            IO.liftVAsync(async e => !e.Token.IsCancellationRequested && Predicate(x)\n                                         ? await reducer(s, x).RunAsync(e.Token)\n                                         : Reduced.Continue(s));\n    \n    public override TransducerM<M, A, A> Lift<M>() => \n        new FilterTransducerM<M, A>(Predicate);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/FoldUntilTransducer.cs",
    "content": "using System;\nusing System.Threading.Tasks;\n\n\nnamespace LanguageExt;\n\nrecord FoldUntilTransducer<A, S>(\n    Func<S, A, S> Folder, \n    Func<S, A, bool> Pred, \n    S State) : \n    Transducer<A, S>\n{\n    public override ReducerIO<A, S1> Reduce<S1>(ReducerIO<S, S1> reducer)\n    {\n        var state = State;\n        return (s1, x) => IO.liftVAsync(async e =>\n                                        {\n                                            if(e.Token.IsCancellationRequested) return Reduced.Done(s1);\n                                            state = Folder(state, x);\n                                            if (Pred(state, x))\n                                            {\n                                                switch (await reducer(s1, state).RunAsync(e))\n                                                {\n                                                    case { Continue: true, Value: var nstate }:\n                                                        state = State; // reset\n                                                        return Reduced.Continue(nstate);\n\n                                                    case { Value: var nstate }:\n                                                        return Reduced.Done(nstate);\n                                                }\n                                            }\n                                            else\n                                            {\n                                                return Reduced.Continue(s1);\n                                            }\n                                        });\n    }\n    \n    public override TransducerM<M, A, S> Lift<M>() =>\n        new FoldUntilTransducerM2<M, A, S>(Schedule.Forever, Folder, Pred, State);\n}\n\nrecord FoldUntilTransducer2<A, S>(\n    Schedule Schedule,\n    Func<S, A, S> Folder,\n    Func<S, A, bool> Pred,\n    S State) :\n    Transducer<A, S>\n{\n    public override ReducerIO<A, S1> Reduce<S1>(ReducerIO<S, S1> reducer)\n    {\n        var state = State;\n        var sch   = Duration.Zero.Cons(Schedule.Run()).GetEnumerator();\n        return (s1, x) =>\n                   IO.liftVAsync(async e =>\n                                 {\n                                     if(e.Token.IsCancellationRequested) return Reduced.Done(s1);\n                                     state = Folder(state, x);\n                                     if (Pred(state, x))\n                                     {\n                                         // Schedule\n                                         if (sch.MoveNext())\n                                         {\n                                             if (!sch.Current.IsZero) await Task.Delay((TimeSpan)sch.Current);\n                                         }\n                                         else\n                                         {\n                                             return Reduced.Done(s1);\n                                         }\n\n                                         switch (await reducer(s1, state).RunAsync(e))\n                                         {\n                                             case { Continue: true, Value: var nstate }:\n                                                 state = State; // reset\n                                                 return Reduced.Continue(nstate);\n\n                                             case { Value: var nstate }:\n                                                 return Reduced.Done(nstate);\n                                         }\n                                     }\n                                     else\n                                     {\n                                         return Reduced.Continue(s1);\n                                     }\n                                 });\n    }\n    \n    public override TransducerM<M, A, S> Lift<M>() =>\n        new FoldUntilTransducerM2<M, A, S>(Schedule, Folder, Pred, State);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/FoldWhileTransducer.cs",
    "content": "using System;\nusing System.Threading.Tasks;\n\nnamespace LanguageExt;\n\nrecord FoldWhileTransducer<A, S>(\n    Func<S, A, S> Folder, \n    Func<S, A, bool> Pred, \n    S State) : \n    Transducer<A, S>\n{\n    public override ReducerIO<A, S1> Reduce<S1>(ReducerIO<S, S1> reducer)\n    {\n        var state = State;\n        return (s1, x) =>\n                   IO.liftVAsync(async e =>\n                                 {\n                                     if(e.Token.IsCancellationRequested) return Reduced.Done(s1);\n                                     if (Pred(state, x))\n                                     {\n                                         state = Folder(state, x);\n                                         return Reduced.Continue(s1);\n                                     }\n                                     else\n                                     {\n                                         switch (await reducer(s1, state).RunAsync(e))\n                                         {\n                                             case { Continue: true, Value: var nstate }:\n                                                 state = Folder(State /* reset */, x);\n                                                 return Reduced.Continue(nstate);\n\n                                             case { Value: var nstate }:\n                                                 return Reduced.Done(nstate);\n                                         }\n                                     }\n                                 });\n    }\n    \n    public override TransducerM<M, A, S> Lift<M>() =>\n        new FoldWhileTransducerM<M, A, S>(Folder, Pred, State);\n}\n\nrecord FoldWhileTransducer2<A, S>(\n    Schedule Schedule, \n    Func<S, A, S> Folder, \n    Func<S, A, bool> Pred, \n    S State) : \n    Transducer<A, S>\n{\n    public override ReducerIO<A, S1> Reduce<S1>(ReducerIO<S, S1> reducer)\n    {\n        var state = State;\n        var sch = Duration.Zero.Cons(Schedule.Run()).GetEnumerator();\n        return (s1, x) =>\n                   IO.liftVAsync(async e =>\n                                 {\n                                     if (Pred(state, x))\n                                     {\n                                         state = Folder(state, x);\n                                         return Reduced.Continue(s1);\n                                     }\n                                     else\n                                     {\n                                         // Schedule\n                                         if (sch.MoveNext())\n                                         {\n                                             if (!sch.Current.IsZero) await Task.Delay((TimeSpan)sch.Current);\n                                         }\n                                         else\n                                         {\n                                             return Reduced.Done(s1);\n                                         }\n\n                                         switch (await reducer(s1, state).RunAsync(e))\n                                         {\n                                             case { Continue: true, Value: var nstate }:\n                                                 state = Folder(State /* reset */, x);\n                                                 return Reduced.Continue(nstate);\n\n                                             case { Value: var nstate }:\n                                                 return Reduced.Done(nstate);\n                                         }\n                                     }\n                                 });\n    }\n    \n    public override TransducerM<M, A, S> Lift<M>() =>\n        new FoldWhileTransducerM2<M, A, S>(Schedule, Folder, Pred, State);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/IdentityTransducer.cs",
    "content": "namespace LanguageExt;\n\nrecord IdentityTransducer<A> : Transducer<A, A>\n{\n    public static readonly Transducer<A, A> Default = new IdentityTransducer<A>();\n    \n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<A, S> reducer) =>\n        reducer;\n    \n    public override TransducerM<M, A, A> Lift<M>() => \n        new IdentityTransducerM<M, A>();\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/MapTransducer.cs",
    "content": "using System;\n\nnamespace LanguageExt;\n\nrecord MapTransducer<A, B>(Func<A, B> F) : Transducer<A, B> \n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<B, S> reducer) =>\n        (s, x) => reducer(s, F(x));\n    \n    public override TransducerM<M, A, B> Lift<M>() => \n        new MapTransducerM<M, A, B>(F);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/SelectManyTransducer.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord SelectManyTransducer1<Env, A, B, C>(\n    Transducer<Env, A> First,\n    Func<A, K<TransduceFrom<Env>, B>> F,\n    Func<A, B, C> G) :\n    Transducer<Env, C>\n{\n    public override ReducerIO<Env, S> Reduce<S>(ReducerIO<C, S> reducer) =>\n        (s, env) => First.Reduce<S>((s1, x) =>\n                                        F(x).As().Reduce<S>((s2, y) => reducer(s2, G(x, y)))(s1, env))(s, env);\n    \n    public override TransducerM<M, Env, C> Lift<M>() =>\n        new SelectManyTransducerM1<M, Env, A, B, C>(First.Lift<M>(), x => F(x).As().Lift<M>(), G);\n}\n\nrecord SelectManyTransducer2<Env, A, B, C>(Transducer<Env, A> First, Func<A, Transducer<Env, B>> F, Func<A, B, C> G) : \n    Transducer<Env, C> \n{\n    public override ReducerIO<Env, S> Reduce<S>(ReducerIO<C, S> reducer) =>\n        (s, env) => First.Reduce<S>(\n            (s1, x) =>\n                F(x).Reduce<S>((s2, y) => reducer(s2, G(x, y)))(s1, env))(s, env);\n    \n    public override TransducerM<M, Env, C> Lift<M>() =>\n        new SelectManyTransducerM2<M, Env, A, B, C>(First.Lift<M>(), x => F(x).Lift<M>(), G);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/SkipTransducer.cs",
    "content": "namespace LanguageExt;\n\nrecord SkipTransducer<A>(int Amount) : Transducer<A, A> \n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<A, S> reducer)\n    {\n        var amount = Amount;\n        return (s, x) =>\n                   IO.liftVAsync(async e =>\n                                 {\n                                     if(e.Token.IsCancellationRequested) return Reduced.Done(s);\n                                     if (amount > 0)\n                                     {\n                                         amount--;\n                                         return Reduced.Continue(s);\n                                     }\n                                     else\n                                     {\n                                         return await reducer(s, x).RunAsync(e);\n                                     }\n                                 });\n    }\n    \n    public override TransducerM<M, A, A> Lift<M>() => \n        new SkipTransducerM<M, A>(Amount);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/DSL/TakeTransducer.cs",
    "content": "namespace LanguageExt;\n\nrecord TakeTransducer<A>(int Amount) : Transducer<A, A> \n{\n    public override ReducerIO<A, S> Reduce<S>(ReducerIO<A, S> reducer)\n    {\n        var taken = 0;\n        return (s, x) => \n                   IO.liftVAsync(async e =>\n                                 {\n                                     if(e.Token.IsCancellationRequested) return Reduced.Done(s);\n                                     if (taken < Amount)\n                                     {\n                                         taken++;\n                                         return await reducer(s, x).RunAsync(e);\n                                     }\n                                     else\n                                     {\n                                         return Reduced.Done(s);\n                                     }\n                                 });\n    }\n    \n    public override TransducerM<M, A, A> Lift<M>() => \n        new TakeTransducerM<M, A>(Amount);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/TransduceFrom.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class TransduceFrom<IN> : \n    Monad<TransduceFrom<IN>>,\n    Readable<TransduceFrom<IN>, IN>\n{\n    static K<TransduceFrom<IN>, B> Monad<TransduceFrom<IN>>.Bind<A, B>(\n        K<TransduceFrom<IN>, A> ma,\n        Func<A, K<TransduceFrom<IN>, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<TransduceFrom<IN>, B> Monad<TransduceFrom<IN>>.Recur<A, B>(A value, Func<A, K<TransduceFrom<IN>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<TransduceFrom<IN>, B> Functor<TransduceFrom<IN>>.Map<A, B>(\n        Func<A, B> f,\n        K<TransduceFrom<IN>, A> ma) =>\n        ma.As().Map(f);\n\n    static K<TransduceFrom<IN>, A> Applicative<TransduceFrom<IN>>.Pure<A>(A value) =>\n        Transducer.constant<IN, A>(value);\n\n    static K<TransduceFrom<IN>, B> Applicative<TransduceFrom<IN>>.Apply<A, B>(\n        K<TransduceFrom<IN>, Func<A, B>> mf,\n        K<TransduceFrom<IN>, A> ma) =>\n        mf.Bind(ma.Map);\n\n    static K<TransduceFrom<IN>, B> Applicative<TransduceFrom<IN>>.Apply<A, B>(\n        K<TransduceFrom<IN>, Func<A, B>> mf,\n        Memo<TransduceFrom<IN>, A> ma) =>\n        mf.Bind(ma.Map);\n    \n    public static K<TransduceFrom<IN>, A> Asks<A>(Func<IN, A> f) => \n        Transducer.map(f);\n\n    public static K<TransduceFrom<IN>, A> Local<A>(Func<IN, IN> f, K<TransduceFrom<IN>, A> ma) =>\n        ma.As().Comap(f);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/TransduceTo.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n\npublic class TransduceTo<OUT> : Cofunctor<TransduceTo<OUT>>\n{\n    static K<TransduceTo<OUT>, A> Cofunctor<TransduceTo<OUT>>.\n        Comap<A, B>(Func<A, B> f, K<TransduceTo<OUT>, B> fb) =>\n        Transducer.compose(Transducer.map(f), fb.As());\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/Transducer.Extensions.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class TransducerExtensions\n{\n    /// <summary>\n    /// Downcast operator\n    /// </summary>\n    public static Transducer<A, B> As<A, B>(this K<TransduceFrom<A>, B> ma) =>\n        (Transducer<A, B>)ma;\n    \n    /// <summary>\n    /// Downcast operator\n    /// </summary>\n    public static Transducer<A, B> As<A, B>(this K<TransduceTo<B>, A> ma) =>\n        (Transducer<A, B>)ma;\n}\n\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/Transducer.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class Transducer\n{\n    /// <summary>\n    /// Identity transducer.  Has no effect on values flowing through.\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Identity transducer</returns>\n    public static Transducer<A, A> identity<A>() => \n        IdentityTransducer<A>.Default;\n\n    /// <summary>\n    /// Constant transducer.  Ignores all incoming values and yields the constant value. \n    /// </summary>\n    /// <typeparam name=\"B\">Constant value type</typeparam>\n    /// <returns>Constant transducer</returns>\n    public static Transducer<A, B> constant<A, B>(B value) => \n        new ConstTransducer<A, B>(value);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static Transducer<A, C> compose<A, B, C>(\n        Transducer<A, B> ta, \n        Transducer<B, C> tb) =>\n        new ComposeTransducer<A, B, C>(ta, tb);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <param name=\"tc\">Third transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static Transducer<A, D> compose<A, B, C, D>(\n        Transducer<A, B> ta, \n        Transducer<B, C> tb, \n        Transducer<C, D> tc) =>\n        new ComposeTransducer<A, B, C, D>(ta, tb, tc);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <param name=\"tc\">Third transducer</param>\n    /// <param name=\"td\">Fourth transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static Transducer<A, E> compose<A, B, C, D, E>(\n        Transducer<A, B> ta, \n        Transducer<B, C> tb, \n        Transducer<C, D> tc, \n        Transducer<D, E> td) =>\n        new ComposeTransducer<A, B, C, D, E>(ta, tb, tc, td);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <param name=\"tc\">Third transducer</param>\n    /// <param name=\"td\">Fourth transducer</param>\n    /// <param name=\"te\">Fifth transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static Transducer<A, F> compose<A, B, C, D, E, F>(\n        Transducer<A, B> ta, \n        Transducer<B, C> tb, \n        Transducer<C, D> tc, \n        Transducer<D, E> td, \n        Transducer<E, F> te) =>\n        new ComposeTransducer<A, B, C, D, E, F>(ta, tb, tc, td, te);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <param name=\"tc\">Third transducer</param>\n    /// <param name=\"td\">Fourth transducer</param>\n    /// <param name=\"te\">Fifth transducer</param>\n    /// <param name=\"tf\">Sixth transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static Transducer<A, G> compose<A, B, C, D, E, F, G>(\n        Transducer<A, B> ta, \n        Transducer<B, C> tb, \n        Transducer<C, D> tc, \n        Transducer<D, E> td, \n        Transducer<E, F> te, \n        Transducer<F, G> tf) =>\n        new ComposeTransducer<A, B, C, D, E, F, G>(ta, tb, tc, td, te, tf);\n    \n    /// <summary>\n    /// Skip `amount` items in the sequence before yielding\n    /// </summary>\n    /// <param name=\"amount\">Number of items to skip</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Transducer that skips values</returns>\n    public static Transducer<A, A> skip<A>(int amount) =>\n        new SkipTransducer<A>(amount);\n\n    /// <summary>\n    /// Take `amount` items in the sequence before terminating\n    /// </summary>\n    /// <param name=\"amount\">Number of items to take</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Transducer that takes `amount` values only</returns>\n    public static Transducer<A, A> take<A>(int amount) =>\n        new TakeTransducer<A>(amount);\n\n    /// <summary>\n    /// Functor map transducer\n    /// </summary>\n    /// <param name=\"f\">Function to map values of type `A` to values of type `B`</param>\n    /// <typeparam name=\"A\">Input value type</typeparam>\n    /// <typeparam name=\"B\">Output value type</typeparam>\n    /// <returns>Mapping transducer</returns>\n    public static Transducer<A, B> map<A, B>(Func<A, B> f) =>\n        new MapTransducer<A, B>(f);\n\n    /// <summary>\n    /// Applicative filter transducer \n    /// </summary>\n    /// <param name=\"predicate\">Filters each value flowing through the transducer.  If `true` the value will flow\n    /// downstream;  if `false`, the value is dropped</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Filtering transducer</returns>\n    public static Transducer<A, A> filter<A>(Func<A, bool> predicate) =>\n        new FilterTransducer<A>(predicate);\n\n    /// <summary>\n    /// Monad bind transducer\n    /// </summary>\n    /// <remarks>\n    /// Chains two transducers together\n    /// </remarks>\n    /// <param name=\"ta\">Initial transducer to run</param>\n    /// <param name=\"f\">Chaining function to run with the result of `ta` that will produce a new `Transducer`</param>\n    /// <typeparam name=\"Env\">Input value type</typeparam>\n    /// <typeparam name=\"A\">Result value type of the first transducer</typeparam>\n    /// <typeparam name=\"B\">Result value type of returned transducer</typeparam>\n    /// <returns>A monadic bind transducer operation</returns>\n    public static Transducer<Env, B> bind<Env, A, B>(Transducer<Env, A> ta, Func<A, K<TransduceFrom<Env>, B>> f) =>\n        new BindTransducer1<Env, A, B>(ta, f);    \n\n    /// <summary>\n    /// Monad bind transducer\n    /// </summary>\n    /// <remarks>\n    /// Chains two transducers together\n    /// </remarks>\n    /// <param name=\"ta\">Initial transducer to run</param>\n    /// <param name=\"f\">Chaining function to run with the result of `ta` that will produce a new `Transducer`</param>\n    /// <typeparam name=\"Env\">Input value type</typeparam>\n    /// <typeparam name=\"A\">Result value type of the first transducer</typeparam>\n    /// <typeparam name=\"B\">Result value type of returned transducer</typeparam>\n    /// <returns>A monadic bind transducer operation</returns>\n    public static Transducer<Env, B> bind<Env, A, B>(Transducer<Env, A> ta, Func<A, Transducer<Env, B>> f) =>\n        new BindTransducer2<Env, A, B>(ta, f);\n\n    /// <summary>\n    /// Fold items in the stream while the predicate returns true; once the predicate returns false, the\n    /// aggregated value is yielded downstream. \n    /// </summary>\n    /// <param name=\"Folder\">Aggregating binary fold function</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"State\">Initial state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"S\">Yielded aggregate value type</typeparam>\n    /// <returns>Aggregating binary folding transducer</returns>\n    public static Transducer<A, S> foldWhile<A, S>(\n        Func<S, A, S> Folder,\n        Func<S, A, bool> Pred,\n        S State) =>\n        new FoldWhileTransducer<A, S>(Folder, Pred, State);\n    \n    /// <summary>\n    /// Fold items in the stream while the predicate returns true; once the predicate returns false, the\n    /// aggregated value is yielded downstream. \n    /// </summary>\n    /// <param name=\"Schedule\">Schedule for each yielded item</param>\n    /// <param name=\"Folder\">Aggregating binary fold function</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"State\">Initial state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"S\">Yielded aggregate value type</typeparam>\n    /// <returns>Aggregating binary folding transducer</returns>\n    public static Transducer<A, S> foldWhile<A, S>(\n        Schedule Schedule,\n        Func<S, A, S> Folder,\n        Func<S, A, bool> Pred,\n        S State) =>\n        new FoldWhileTransducer2<A, S>(Schedule, Folder, Pred, State);\n    \n\n    /// <summary>\n    /// Fold items in the stream until the predicate returns true; once the predicate returns true, the\n    /// aggregated value is yielded downstream. \n    /// </summary>\n    /// <param name=\"Folder\">Aggregating binary fold function</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"State\">Initial state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"S\">Yielded aggregate value type</typeparam>\n    /// <returns>Aggregating binary folding transducer</returns>\n    public static Transducer<A, S> foldUntil<A, S>(\n        Func<S, A, S> Folder,\n        Func<S, A, bool> Pred,\n        S State) =>\n        new FoldUntilTransducer<A, S>(Folder, Pred, State);\n    \n    /// <summary>\n    /// Fold items in the stream until the predicate returns true; once the predicate returns true, the\n    /// aggregated value is yielded downstream. \n    /// </summary>\n    /// <param name=\"Schedule\">Schedule for each yielded item</param>\n    /// <param name=\"Folder\">Aggregating binary fold function</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"State\">Initial state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"S\">Yielded aggregate value type</typeparam>\n    /// <returns>Aggregating binary folding transducer</returns>\n    public static Transducer<A, S> foldUntil<A, S>(\n        Schedule Schedule,\n        Func<S, A, S> Folder,\n        Func<S, A, bool> Pred,\n        S State) =>\n        new FoldUntilTransducer2<A, S>(Schedule, Folder, Pred, State);    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/Transducer/Transducer.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic abstract record Transducer<A, B> : \n    K<TransduceFrom<A>, B>,\n    K<TransduceTo<B>, A>\n{\n    /// <summary>\n    /// Fold the input stream using the supplied reducer.  \n    /// </summary>\n    /// <param name=\"reducer\">Reducer that folds the stream of values flowing through the transducer</param>\n    /// <typeparam name=\"S\">State</typeparam>\n    /// <returns></returns>\n    public abstract ReducerIO<A, S> Reduce<S>(ReducerIO<B, S> reducer);\n\n    /// <summary>\n    /// Lift the pure value transducer into a `M` value transducer\n    /// </summary>\n    /// <typeparam name=\"M\">Lifted space</typeparam>\n    /// <returns>Lifted transducer</returns>\n    public abstract TransducerM<M, A, B> Lift<M>()\n        where M : Applicative<M>;\n    \n    /// <summary>\n    /// Compose two transducers together.  The output of the first transducer is the input to the second.\n    /// </summary>\n    public virtual Transducer<A, C> Compose<C>(Transducer<B, C> tg) =>\n        new ComposeTransducer<A, B, C>(this, tg);\n\n    /// <summary>\n    /// Functor map \n    /// </summary>\n    public Transducer<A, C> Map<C>(Func<B, C> f) =>\n        Compose(Transducer.map(f));\n\n    /// <summary>\n    /// Contravariant functor map \n    /// </summary>\n    public Transducer<X, B> Comap<X>(Func<X, A> f) =>\n        Transducer.map(f).Compose(this);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public Transducer<A, C> Bind<C>(Func<B, K<TransduceFrom<A>, C>> f) =>\n        new BindTransducer1<A, B, C>(this, f);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public Transducer<A, C> Bind<C>(Func<B, Transducer<A, C>> f) =>\n        new BindTransducer2<A, B, C>(this, f);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public Transducer<A, D> SelectMany<C, D>(Func<B, K<TransduceFrom<A>, C>> bind, Func<B, C, D> project) =>\n        new SelectManyTransducer1<A, B, C, D>(this, bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public Transducer<A, D> SelectMany<C, D>(Func<B, Transducer<A, C>> bind, Func<B, C, D> project) =>\n        new SelectManyTransducer2<A, B, C, D>(this, bind, project);\n\n    /// <summary>\n    /// Filter values flowing through the transducer. \n    /// </summary>\n    public Transducer<A, B> Filter(Func<B, bool> f) =>\n        Compose(Transducer.filter(f));\n    \n    /// <summary>\n    /// Filter values flowing through the transducer. \n    /// </summary>\n    public Transducer<A, B> Where(Func<B, bool> f) =>\n        Compose(Transducer.filter(f));\n\n    /// <summary>\n    /// Take the first `n` values from the stream.  \n    /// </summary>\n    public Transducer<A, B> Take(int n) =>\n        Compose(Transducer.take<B>(n));\n\n    /// <summary>\n    /// Skip the first `n` values from the stream. \n    /// </summary>\n    public Transducer<A, B> Skip(int n) =>\n        Compose(Transducer.skip<B>(n));\n\n    public Transducer<A, S> FoldWhile<S>(\n        Func<S, B, S> Folder, \n        Func<S, B, bool> Pred, \n        S State) =>\n        Compose(Transducer.foldWhile(Folder, Pred, State));\n    \n    public Transducer<A, S> FoldWhile<S>(\n        Schedule Schedule, \n        Func<S, B, S> Folder, \n        Func<S, B, bool> Pred, \n        S State) =>\n        Compose(Transducer.foldWhile(Schedule, Folder, Pred, State));\n    \n    public Transducer<A, S> FoldUntil<S>(\n        Func<S, B, S> Folder, \n        Func<S, B, bool> Pred, \n        S State) =>\n        Compose(Transducer.foldUntil(Folder, Pred, State));\n    \n    public Transducer<A, S> FoldUntil<S>(\n        Schedule Schedule, \n        Func<S, B, S> Folder, \n        Func<S, B, bool> Pred, \n        S State) =>\n        Compose(Transducer.foldUntil(Schedule, Folder, Pred, State));    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/BindTransducer.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord BindTransducerM1<M, Env, A, B>(TransducerM<M, Env, A> First, Func<A, K<TransduceFromM<M, Env>, B>> F) : \n    TransducerM<M, Env, B> \n{\n    public override ReducerM<M, Env, S> Reduce<S>(ReducerM<M, B, S> reducer) => \n        (s, env) => First.Reduce<S>(\n            (s1, x) =>\n                F(x).As().Reduce(reducer)(s1, env))(s, env);\n}\n\nrecord BindTransducerM2<M, Env, A, B>(TransducerM<M, Env, A> First, Func<A, TransducerM<M, Env, B>> F) : \n    TransducerM<M, Env, B> \n{\n    public override ReducerM<M, Env, S> Reduce<S>(ReducerM<M, B, S> reducer) => \n        (s, env) => First.Reduce<S>(\n            (s1, x) =>\n                F(x).Reduce(reducer)(s1, env))(s, env);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/ComposeTransducer.cs",
    "content": "namespace LanguageExt;\n\nrecord ComposeTransducerM<M, A, B, C>(TransducerM<M, A, B> TF, TransducerM<M, B, C> TG) : \n    TransducerM<M, A, C> \n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, C, S> reducer) =>\n        (s, x) => TF.Reduce<S>((s1, y) => TG.Reduce(reducer)(s1, y))(s, x);\n\n    public override TransducerM<M, A, D> Compose<D>(TransducerM<M, C, D> t) =>\n        new ComposeTransducerM<M, A, B, C, D>(TF, TG, t);\n}\n\nrecord ComposeTransducerM<M, A, B, C, D>(TransducerM<M, A, B> TF, TransducerM<M, B, C> TG, TransducerM<M, C, D> TH) : \n    TransducerM<M, A, D>\n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, D, S> reducer) => \n        (s, x) => TF.Reduce<S>((s1, y) => TG.Reduce<S>((s2, z) => TH.Reduce(reducer)(s2, z))(s1, y))(s, x);\n\n    public override TransducerM<M, A, E> Compose<E>(TransducerM<M, D, E> t) =>\n        new ComposeTransducerM<M, A, B, C, D, E>(TF, TG, TH, t);\n}\n\nrecord ComposeTransducerM<M, A, B, C, D, E>(\n    TransducerM<M, A, B> TF, \n    TransducerM<M, B, C> TG, \n    TransducerM<M, C, D> TH, \n    TransducerM<M, D, E> TI) : \n    TransducerM<M, A, E>\n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, E, S> reducer) => \n        (s, w) => TF.Reduce<S>(\n                (s1, x) => TG.Reduce<S>(\n                        (s2, y) => TH.Reduce<S>(\n                                (s3, z) => TI.Reduce(reducer)(s3, z))\n                            (s2, y))\n                    (s1, x))\n            (s, w);\n\n    public override TransducerM<M, A, F> Compose<F>(TransducerM<M, E, F> t) =>\n        new ComposeTransducerM<M, A, B, C, D, E, F>(TF, TG, TH, TI, t);\n}\n\nrecord ComposeTransducerM<M, A, B, C, D, E, F>(\n    TransducerM<M, A, B> TF, \n    TransducerM<M, B, C> TG, \n    TransducerM<M, C, D> TH, \n    TransducerM<M, D, E> TI, \n    TransducerM<M, E, F> TJ) : \n    TransducerM<M, A, F>\n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, F, S> reducer) => \n        (s, v) => TF.Reduce<S>(\n                (s1, w) => TG.Reduce<S>(\n                        (s2, x) => TH.Reduce<S>(\n                                (s3, y) => TI.Reduce<S>(\n                                        (s4, z) => TJ.Reduce(reducer)(s4, z))\n                                    (s3, y))\n                            (s2, x))\n                    (s1, w))\n            (s, v);\n\n    public override TransducerM<M, A, G> Compose<G>(TransducerM<M, F, G> t) =>\n        new ComposeTransducerM<M, A, B, C, D, E, F, G>(TF, TG, TH, TI, TJ, t);\n}\n\nrecord ComposeTransducerM<M, A, B, C, D, E, F, G>(\n    TransducerM<M, A, B> TF, \n    TransducerM<M, B, C> TG, \n    TransducerM<M, C, D> TH, \n    TransducerM<M, D, E> TI, \n    TransducerM<M, E, F> TJ, \n    TransducerM<M, F, G> TK) : \n    TransducerM<M, A, G>\n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, G, S> reducer) => \n        (s, u) => TF.Reduce<S>(\n                (s1, v) => TG.Reduce<S>(\n                        (s2, w) => TH.Reduce<S>(\n                                (s3, x) => TI.Reduce<S>(\n                                        (s4, y) => TJ.Reduce<S>(\n                                                (s5, z) => TK.Reduce(reducer)(s5, z))\n                                            (s4, y))\n                                    (s3, x))\n                            (s2, w))\n                    (s1, v))\n            (s, u);\n\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/ConstTransducer.cs",
    "content": "namespace LanguageExt;\n\nrecord ConstTransducerM<M, A, B>(B Value) : TransducerM<M, A, B> \n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, B, S> reducer) => \n        (s, _) => reducer(s, Value);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/FilterTransducer.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FilterTransducerM<M, A>(Func<A, bool> Predicate) : TransducerM<M, A, A>\n    where M : Applicative<M>\n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, A, S> reducer) => \n        (s, x) => Predicate(x)\n                      ? reducer(s, x)\n                      : M.Pure(Reduced.Continue(s));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/FoldUntilTransducer.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FoldUntilTransducerM<M, A, S>(\n    Func<S, A, S> Folder, \n    Func<S, A, bool> Pred, \n    S State) : \n    TransducerM<M, A, S>\n    where M : Applicative<M> \n{\n    public override ReducerM<M, A, S1> Reduce<S1>(ReducerM<M, S, S1> reducer) \n    {\n        var state = State;\n        return (s1, x) =>\n               {\n                   state = Folder(state, x);\n                   if (Pred(state, x))\n                   {\n                       return reducer(s1, state);\n                   }\n                   else\n                   {\n                       return M.Pure(Reduced.Done(s1));\n                   }\n               };\n    }\n}\n\nrecord FoldUntilTransducerM2<M, A, S>(\n    Schedule Schedule,\n    Func<S, A, S> Folder,\n    Func<S, A, bool> Pred,\n    S State) :\n    TransducerM<M, A, S>\n    where M : Applicative<M> \n{\n    public override ReducerM<M, A, S1> Reduce<S1>(ReducerM<M, S, S1> reducer)\n    {\n        var state = State;\n        var sch   = Duration.Zero.Cons(Schedule.Run()).GetEnumerator();\n        return (s1, x) =>\n               {\n                   state = Folder(state, x);\n                   if (Pred(state, x))\n                   {\n                       // Schedule\n                       if (sch.MoveNext())\n                       {\n                           if (!sch.Current.IsZero) Task.Delay((TimeSpan)sch.Current).GetAwaiter().GetResult();\n                       }\n                       else\n                       {\n                           return M.Pure(Reduced.Done(s1));\n                       }\n                       return reducer(s1, state);\n                   }\n                   else\n                   {\n                       return M.Pure(Reduced.Done(s1));\n                   }\n               };\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/FoldWhileTransducer.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord FoldWhileTransducerM<M, A, S>(\n    Func<S, A, S> Folder, \n    Func<S, A, bool> Pred, \n    S State) : \n    TransducerM<M, A, S>\n    where M : Applicative<M> \n{\n    public override ReducerM<M, A, S1> Reduce<S1>(ReducerM<M, S, S1> reducer) \n    {\n        var state = State;\n        return (s1, x) =>\n               {\n                   if (Pred(state, x))\n                   {\n                       state = Folder(state, x);\n                       return M.Pure(Reduced.Done(s1));\n                   }\n                   else\n                   {\n                       return reducer(s1, state)\n                          .Map(ns =>\n                               {\n                                   state = Folder(State /* reset */, x);\n                                   return ns;\n                               });\n                   }\n               };\n    }\n}\n\nrecord FoldWhileTransducerM2<M, A, S>(\n    Schedule Schedule, \n    Func<S, A, S> Folder, \n    Func<S, A, bool> Pred, \n    S State) : \n    TransducerM<M, A, S>\n    where M : Applicative<M> \n{\n    public override ReducerM<M, A, S1> Reduce<S1>(ReducerM<M, S, S1> reducer)\n    {\n        var state = State;\n        var sch   = Duration.Zero.Cons(Schedule.Run()).GetEnumerator();\n        return (s1, x) =>\n               {\n                   if (Pred(state, x))\n                   {\n                       state = Folder(state, x);\n                       return M.Pure(Reduced.Done(s1));\n                   }\n                   else\n                   {\n                       // Schedule\n                       if (sch.MoveNext())\n                       {\n                           if (!sch.Current.IsZero) Task.Delay((TimeSpan)sch.Current).GetAwaiter().GetResult();\n                       }\n                       else\n                       {\n                           return M.Pure(Reduced.Done(s1));\n                       }\n\n                       return reducer(s1, state)\n                          .Map(ns =>\n                               {\n                                   state = Folder(State /* reset */, x);\n                                   return ns;\n                               });\n                   }\n               };\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/IdentityTransducer.cs",
    "content": "namespace LanguageExt;\n\nrecord IdentityTransducerM<M, A> : TransducerM<M, A, A>\n{\n    public static readonly TransducerM<M, A, A> Default = new IdentityTransducerM<M, A>();\n    \n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, A, S> reducer) =>\n        reducer;\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/MapTransducer.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord MapTransducerM<M, A, B>(Func<A, B> F) : TransducerM<M, A, B> \n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, B, S> reducer) => \n        (s, x) => reducer(s, F(x));\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/SelectManyTransducer.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord SelectManyTransducerM1<M, Env, A, B, C>(TransducerM<M, Env, A> First, Func<A, K<TransduceFromM<M, Env>, B>> F, Func<A, B, C> G) : \n    TransducerM<M, Env, C> \n{\n    public override ReducerM<M, Env, S> Reduce<S>(ReducerM<M, C, S> reducer) => \n        (s, env) => First.Reduce<S>(\n            (s1, x) =>\n                F(x).As().Reduce<S>((s2, y) => reducer(s2, G(x, y)))(s1, env))(s, env);\n\n}\n\nrecord SelectManyTransducerM2<M, Env, A, B, C>(TransducerM<M, Env, A> First, Func<A, TransducerM<M, Env, B>> F, Func<A, B, C> G) : \n    TransducerM<M, Env, C> \n{\n    public override ReducerM<M, Env, S> Reduce<S>(ReducerM<M, C, S> reducer) => \n        (s, env) => First.Reduce<S>(\n            (s1, x) =>\n                F(x).Reduce<S>((s2, y) => reducer(s2, G(x, y)))(s1, env))(s, env);\n\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/SkipTransducer.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord SkipTransducerM<M, A>(int Amount) : TransducerM<M, A, A>\n    where M : Applicative<M>\n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, A, S> reducer)  \n    {\n        var amount = Amount;\n        return (s, x) =>\n               {\n                   if (amount > 0)\n                   {\n                       amount--;\n                       return M.Pure(Reduced.Continue(s));\n                   }\n                   else\n                   {\n                       return reducer(s, x);\n                   }\n               };\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/DSL/TakeTransducer.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt;\n\nrecord TakeTransducerM<M, A>(int Amount) : TransducerM<M, A, A> \n    where M : Applicative<M>\n{\n    public override ReducerM<M, A, S> Reduce<S>(ReducerM<M, A, S> reducer) \n    {\n        var taken = 0;\n        return (s, x) =>\n               {\n                   if (taken < Amount)\n                   {\n                       taken++;\n                       return reducer(s, x);\n                   }\n                   else\n                   {\n                       return M.Pure(Reduced.Done(s));\n                   }\n               };\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/TransduceFromM.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic class TransduceFromM<M, IN> : \n    Monad<TransduceFromM<M, IN>>,\n    Readable<TransduceFromM<M, IN>, IN>\n{\n    static K<TransduceFromM<M, IN>, B> Monad<TransduceFromM<M, IN>>.Bind<A, B>(\n        K<TransduceFromM<M, IN>, A> ma,\n        Func<A, K<TransduceFromM<M, IN>, B>> f) =>\n        ma.As().Bind(f);\n\n    static K<TransduceFromM<M, IN>, B> Monad<TransduceFromM<M, IN>>.Recur<A, B>(A value, Func<A, K<TransduceFromM<M, IN>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<TransduceFromM<M, IN>, B> Functor<TransduceFromM<M, IN>>.Map<A, B>(\n        Func<A, B> f,\n        K<TransduceFromM<M, IN>, A> ma) =>\n        ma.As().Map(f);\n\n    static K<TransduceFromM<M, IN>, A> Applicative<TransduceFromM<M, IN>>.Pure<A>(A value) =>\n        TransducerM.constant<M, IN, A>(value);\n\n    static K<TransduceFromM<M, IN>, B> Applicative<TransduceFromM<M, IN>>.Apply<A, B>(\n        K<TransduceFromM<M, IN>, Func<A, B>> mf,\n        K<TransduceFromM<M, IN>, A> ma) =>\n        mf.Bind(ma.Map);\n\n    static K<TransduceFromM<M, IN>, B> Applicative<TransduceFromM<M, IN>>.Apply<A, B>(\n        K<TransduceFromM<M, IN>, Func<A, B>> mf,\n        Memo<TransduceFromM<M, IN>, A> ma) =>\n        mf.Bind(ma.Map);\n\n    public static K<TransduceFromM<M, IN>, A> Asks<A>(Func<IN, A> f) => \n        TransducerM.map<M, IN, A>(f);\n\n    public static K<TransduceFromM<M, IN>, A> Local<A>(Func<IN, IN> f, K<TransduceFromM<M, IN>, A> ma) =>\n        ma.As().Comap(f);\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/TransduceToM.TraitImpl.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\n\npublic class TransduceToM<M, OUT> : Cofunctor<TransduceToM<M, OUT>>\n{\n    static K<TransduceToM<M, OUT>, A> Cofunctor<TransduceToM<M, OUT>>.\n        Comap<A, B>(Func<A, B> f, K<TransduceToM<M, OUT>, B> fb) =>\n        TransducerM.map<M, A, B>(f).Compose(fb.As());\n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/TransducerM.Extensions.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class TransducerMExtensions\n{\n    /// <summary>\n    /// Downcast operator\n    /// </summary>\n    public static TransducerM<M, A, B> As<M, A, B>(this K<TransduceFromM<M, A>, B> ma) =>\n        (TransducerM<M, A, B>)ma;\n    \n    /// <summary>\n    /// Downcast operator\n    /// </summary>\n    public static TransducerM<M, A, B> As<M, A, B>(this K<TransduceToM<M, B>, A> ma) =>\n        (TransducerM<M, A, B>)ma;\n    \n    /// <summary>\n    /// Filter values flowing through the transducer. \n    /// </summary>\n    public static TransducerM<M, A, B> Filter<M, A, B>(this TransducerM<M, A, B> tab, Func<B, bool> f) \n        where M : Applicative<M> =>\n        tab.Compose(TransducerM.filter<M, B>(f));\n    \n    /// <summary>\n    /// Filter values flowing through the transducer. \n    /// </summary>\n    public static TransducerM<M, A, B> Where<M, A, B>(this TransducerM<M, A, B> tab, Func<B, bool> f) \n        where M : Applicative<M> =>\n        tab.Compose(TransducerM.filter<M, B>(f));\n\n    /// <summary>\n    /// Take the first `n` values from the stream.  \n    /// </summary>\n    public static TransducerM<M, A, B> Take<M, A, B>(this TransducerM<M, A, B> tab, int n) \n        where M : Applicative<M> =>\n        tab.Compose(TransducerM.take<M, B>(n));\n\n    /// <summary>\n    /// Skip the first `n` values from the stream. \n    /// </summary>\n    public static TransducerM<M, A, B> Skip<M, A, B>(this TransducerM<M, A, B> tab, int n) \n        where M : Applicative<M> =>\n        tab.Compose(TransducerM.skip<M, B>(n));\n\n    public static TransducerM<M, A, S> FoldWhile<M, A, B, S>(\n        this TransducerM<M, A, B> tab, \n        Func<S, B, S> Folder, \n        Func<S, B, bool> Pred, \n        S State) \n        where M : Applicative<M> =>\n        tab.Compose(TransducerM.foldWhile<M, B, S>(Folder, Pred, State));\n    \n    public static TransducerM<M, A, S> FoldWhile<M, A, B, S>(\n        this TransducerM<M, A, B> tab, \n        Schedule Schedule, \n        Func<S, B, S> Folder, \n        Func<S, B, bool> Pred, \n        S State) \n        where M : Applicative<M> =>\n        tab.Compose(TransducerM.foldWhile<M, B, S>(Schedule, Folder, Pred, State));\n    \n    public static TransducerM<M, A, S> FoldUntil<M, A, B, S>(\n        this TransducerM<M, A, B> tab,         \n        Func<S, B, S> Folder, \n        Func<S, B, bool> Pred, \n        S State) \n        where M : Applicative<M> =>\n        tab.Compose(TransducerM.foldUntil<M, B, S>(Folder, Pred, State));\n    \n    public static TransducerM<M, A, S> FoldUntil<M, A, B, S>(\n        this TransducerM<M, A, B> tab, \n        Schedule Schedule, \n        Func<S, B, S> Folder, \n        Func<S, B, bool> Pred, \n        S State) \n        where M : Applicative<M> =>\n        tab.Compose(TransducerM.foldUntil<M, B, S>(Schedule, Folder, Pred, State));      \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/TransducerM.Module.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic static class TransducerM\n{\n    /// <summary>\n    /// Identity transducer.  Has no effect on values flowing through.\n    /// </summary>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Identity transducer</returns>\n    public static TransducerM<M, A, A> identity<M, A>() => \n        IdentityTransducerM<M, A>.Default;\n\n    /// <summary>\n    /// Constant transducer.  Ignores all incoming values and yields the constant value. \n    /// </summary>\n    /// <typeparam name=\"B\">Constant value type</typeparam>\n    /// <returns>Constant transducer</returns>\n    public static TransducerM<M, A, B> constant<M, A, B>(B value) => \n        new ConstTransducerM<M, A, B>(value);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static TransducerM<M, A, C> compose<M, A, B, C>(\n        TransducerM<M, A, B> ta, \n        TransducerM<M, B, C> tb) =>\n        new ComposeTransducerM<M, A, B, C>(ta, tb);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <param name=\"tc\">Third transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static TransducerM<M, A, D> compose<M, A, B, C, D>(\n        TransducerM<M, A, B> ta, \n        TransducerM<M, B, C> tb, \n        TransducerM<M, C, D> tc) =>\n        new ComposeTransducerM<M, A, B, C, D>(ta, tb, tc);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <param name=\"tc\">Third transducer</param>\n    /// <param name=\"td\">Fourth transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static TransducerM<M, A, E> compose<M, A, B, C, D, E>(\n        TransducerM<M, A, B> ta, \n        TransducerM<M, B, C> tb, \n        TransducerM<M, C, D> tc, \n        TransducerM<M, D, E> td) =>\n        new ComposeTransducerM<M, A, B, C, D, E>(ta, tb, tc, td);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <param name=\"tc\">Third transducer</param>\n    /// <param name=\"td\">Fourth transducer</param>\n    /// <param name=\"te\">Fifth transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static TransducerM<M, A, F> compose<M, A, B, C, D, E, F>(\n        TransducerM<M, A, B> ta, \n        TransducerM<M, B, C> tb, \n        TransducerM<M, C, D> tc, \n        TransducerM<M, D, E> td, \n        TransducerM<M, E, F> te) =>\n        new ComposeTransducerM<M, A, B, C, D, E, F>(ta, tb, tc, td, te);\n\n    /// <summary>\n    /// Compose transducers together.  The output of each transducer is fed into the next transducer.\n    /// </summary>\n    /// <param name=\"ta\">First transducer</param>\n    /// <param name=\"tb\">Second transducer</param>\n    /// <param name=\"tc\">Third transducer</param>\n    /// <param name=\"td\">Fourth transducer</param>\n    /// <param name=\"te\">Fifth transducer</param>\n    /// <param name=\"tf\">Sixth transducer</param>\n    /// <returns>Composed transducer</returns>\n    public static TransducerM<M, A, G> compose<M, A, B, C, D, E, F, G>(\n        TransducerM<M, A, B> ta, \n        TransducerM<M, B, C> tb, \n        TransducerM<M, C, D> tc, \n        TransducerM<M, D, E> td, \n        TransducerM<M, E, F> te, \n        TransducerM<M, F, G> tf) =>\n        new ComposeTransducerM<M, A, B, C, D, E, F, G>(ta, tb, tc, td, te, tf);\n    \n    /// <summary>\n    /// Skip `amount` items in the sequence before yielding\n    /// </summary>\n    /// <param name=\"amount\">Number of items to skip</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Transducer that skips values</returns>\n    public static TransducerM<M, A, A> skip<M, A>(int amount) \n        where M : Applicative<M> =>\n        new SkipTransducerM<M, A>(amount);\n\n    /// <summary>\n    /// Take `amount` items in the sequence before terminating\n    /// </summary>\n    /// <param name=\"amount\">Number of items to take</param>\n    /// <typeparam name=\"A\">Value type</typeparam>\n    /// <returns>Transducer that takes `amount` values only</returns>\n    public static TransducerM<M, A, A> take<M, A>(int amount) \n        where M : Applicative<M> =>\n        new TakeTransducerM<M, A>(amount);\n\n    /// <summary>\n    /// Functor map transducer\n    /// </summary>\n    /// <param name=\"f\">Function to map values of type `A` to values of type `B`</param>\n    /// <typeparam name=\"A\">Input value type</typeparam>\n    /// <typeparam name=\"B\">Output value type</typeparam>\n    /// <returns>Mapping transducer</returns>\n    public static TransducerM<M, A, B> map<M, A, B>(Func<A, B> f) =>\n        new MapTransducerM<M, A, B>(f);\n    \n    /// <summary>\n    /// Applicative filter transducer \n    /// </summary>\n    /// <param name=\"predicate\">Filters each value flowing through the transducer.  If `true` the value will flow\n    /// downstream;  if `false`, the value is dropped</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <returns>Filtering transducer</returns>\n    public static TransducerM<M, A, A> filter<M, A>(Func<A, bool> predicate)\n        where M : Applicative<M> =>\n        new FilterTransducerM<M, A>(predicate);\n\n    /// <summary>\n    /// Monad bind transducer\n    /// </summary>\n    /// <remarks>\n    /// Chains two transducers together\n    /// </remarks>\n    /// <param name=\"ta\">Initial transducer to run</param>\n    /// <param name=\"f\">Chaining function to run with the result of `ta` that will produce a new `Transducer`</param>\n    /// <typeparam name=\"Env\">Input value type</typeparam>\n    /// <typeparam name=\"A\">Result value type of the first transducer</typeparam>\n    /// <typeparam name=\"B\">Result value type of returned transducer</typeparam>\n    /// <returns>A monadic bind transducer operation</returns>\n    public static TransducerM<M, Env, B> bind<M, Env, A, B>(TransducerM<M, Env, A> ta, Func<A, K<TransduceFromM<M, Env>, B>> f) =>\n        new BindTransducerM1<M, Env, A, B>(ta, f);    \n\n    /// <summary>\n    /// Monad bind transducer\n    /// </summary>\n    /// <remarks>\n    /// Chains two transducers together\n    /// </remarks>\n    /// <param name=\"ta\">Initial transducer to run</param>\n    /// <param name=\"f\">Chaining function to run with the result of `ta` that will produce a new `Transducer`</param>\n    /// <typeparam name=\"Env\">Input value type</typeparam>\n    /// <typeparam name=\"A\">Result value type of the first transducer</typeparam>\n    /// <typeparam name=\"B\">Result value type of returned transducer</typeparam>\n    /// <returns>A monadic bind transducer operation</returns>\n    public static TransducerM<M, Env, B> bind<M, Env, A, B>(TransducerM<M, Env, A> ta, Func<A, TransducerM<M, Env, B>> f) =>\n        new BindTransducerM2<M, Env, A, B>(ta, f);\n\n    /// <summary>\n    /// Fold items in the stream while the predicate returns true; once the predicate returns false, the\n    /// aggregated value is yielded downstream. \n    /// </summary>\n    /// <param name=\"Folder\">Aggregating binary fold function</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"State\">Initial state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"S\">Yielded aggregate value type</typeparam>\n    /// <returns>Aggregating binary folding transducer</returns>\n    public static TransducerM<M, A, S> foldWhile<M, A, S>(\n        Func<S, A, S> Folder,\n        Func<S, A, bool> Pred,\n        S State) \n        where M : Applicative<M> =>\n        new FoldWhileTransducerM<M, A, S>(Folder, Pred, State);\n    \n    /// <summary>\n    /// Fold items in the stream while the predicate returns true; once the predicate returns false, the\n    /// aggregated value is yielded downstream. \n    /// </summary>\n    /// <param name=\"Schedule\">Schedule for each yielded item</param>\n    /// <param name=\"Folder\">Aggregating binary fold function</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"State\">Initial state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"S\">Yielded aggregate value type</typeparam>\n    /// <returns>Aggregating binary folding transducer</returns>\n    public static TransducerM<M, A, S> foldWhile<M, A, S>(\n        Schedule Schedule,\n        Func<S, A, S> Folder,\n        Func<S, A, bool> Pred,\n        S State) \n        where M : Applicative<M> =>\n        new FoldWhileTransducerM2<M, A, S>(Schedule, Folder, Pred, State);\n    \n\n    /// <summary>\n    /// Fold items in the stream until the predicate returns true; once the predicate returns true, the\n    /// aggregated value is yielded downstream. \n    /// </summary>\n    /// <param name=\"Folder\">Aggregating binary fold function</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"State\">Initial state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"S\">Yielded aggregate value type</typeparam>\n    /// <returns>Aggregating binary folding transducer</returns>\n    public static TransducerM<M, A, S> foldUntil<M, A, S>(\n        Func<S, A, S> Folder,\n        Func<S, A, bool> Pred,\n        S State) \n        where M : Applicative<M> =>\n        new FoldUntilTransducerM<M, A, S>(Folder, Pred, State);\n    \n    /// <summary>\n    /// Fold items in the stream until the predicate returns true; once the predicate returns true, the\n    /// aggregated value is yielded downstream. \n    /// </summary>\n    /// <param name=\"Schedule\">Schedule for each yielded item</param>\n    /// <param name=\"Folder\">Aggregating binary fold function</param>\n    /// <param name=\"Pred\">Predicate</param>\n    /// <param name=\"State\">Initial state</param>\n    /// <typeparam name=\"A\">Bound value type</typeparam>\n    /// <typeparam name=\"S\">Yielded aggregate value type</typeparam>\n    /// <returns>Aggregating binary folding transducer</returns>\n    public static TransducerM<M, A, S> foldUntil<M, A, S>(\n        Schedule Schedule,\n        Func<S, A, S> Folder,\n        Func<S, A, bool> Pred,\n        S State) \n        where M : Applicative<M> =>\n        new FoldUntilTransducerM2<M, A, S>(Schedule, Folder, Pred, State);    \n}\n"
  },
  {
    "path": "LanguageExt.Streaming/Transducers/TransducerM/TransducerM.cs",
    "content": "using System;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt;\n\npublic abstract record TransducerM<M, A, B> : \n    K<TransduceFromM<M, A>, B>,\n    K<TransduceToM<M, B>, A>\n{\n    /// <summary>\n    /// Fold the input stream using the supplied reducer.  \n    /// </summary>\n    /// <param name=\"reducer\">Reducer that folds the stream of values flowing through the transducer</param>\n    /// <typeparam name=\"S\">State</typeparam>\n    /// <returns></returns>\n    public abstract ReducerM<M, A, S> Reduce<S>(ReducerM<M, B, S> reducer);\n\n    /// <summary>\n    /// Compose two transducers together.  The output of the first transducer is the input to the second.\n    /// </summary>\n    public virtual TransducerM<M, A, C> Compose<C>(TransducerM<M, B, C> tg) =>\n        new ComposeTransducerM<M, A, B, C>(this, tg);\n\n    /// <summary>\n    /// Functor map \n    /// </summary>\n    public TransducerM<M, A, C> Map<C>(Func<B, C> f) =>\n        Compose(TransducerM.map<M, B, C>(f));\n\n    /// <summary>\n    /// Contravariant functor map \n    /// </summary>\n    public TransducerM<M, X, B> Comap<X>(Func<X, A> f) =>\n        TransducerM.map<M, X, A>(f).Compose(this);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public TransducerM<M, A, C> Bind<C>(Func<B, K<TransduceFromM<M, A>, C>> f) =>\n        new BindTransducerM1<M, A, B, C>(this, f);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public TransducerM<M, A, C> Bind<C>(Func<B, TransducerM<M, A, C>> f) =>\n        new BindTransducerM2<M, A, B, C>(this, f);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public TransducerM<M, A, D> SelectMany<C, D>(Func<B, K<TransduceFromM<M, A>, C>> bind, Func<B, C, D> project) =>\n        new SelectManyTransducerM1<M, A, B, C, D>(this, bind, project);\n\n    /// <summary>\n    /// Monadic bind\n    /// </summary>\n    public TransducerM<M, A, D> SelectMany<C, D>(Func<B, TransducerM<M, A, C>> bind, Func<B, C, D> project) =>\n        new SelectManyTransducerM2<M, A, B, C, D>(this, bind, project);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/ActivityEnv.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Reflection;\n\nnamespace LanguageExt;\n\npublic record ActivityEnv(\n    ActivitySource ActivitySource, \n    Activity? Activity, \n    string? ParentId) : \n    IDisposable\n{\n    public static ActivityEnv Default;\n\n    static ActivityEnv()\n    {\n        var asm = Assembly.GetEntryAssembly()?.GetName();\n        Default = new ActivityEnv(new ActivitySource(asm?.Name ?? \"\", asm?.Version?.ToString() ?? \"0.0\"), null, null);\n    }\n            \n    public void Dispose()\n    {\n        ActivitySource.Dispose();\n        Activity?.Dispose();\n    }\n\n    public override string ToString() => \n        \"Activity Environment\";\n}\n"
  },
  {
    "path": "LanguageExt.Sys/EffOpt.cs",
    "content": "using System.Runtime.CompilerServices;\n\nnamespace LanguageExt\n{\n    internal static class EffOpt\n    {\n        internal const MethodImplOptions mops = MethodImplOptions.AggressiveInlining;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Sys/LanguageExt.Sys.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <LangVersion>default</LangVersion>\n\n        <PackageVersion>5.0.0-beta-77</PackageVersion>\n        <PackageId>LanguageExt.Sys</PackageId>\n        <Title>LanguageExt.Sys</Title>\n        <Authors>Paul Louth</Authors>\n        <Summary>BCL System namespace wrapped up into Aff and Eff effects for controlled functional side-effects in C#</Summary>\n        <Copyright>Copyright (c) Paul Louth. All rights reserved.</Copyright>\n        <PackageReadmeFile>README.nuget.md</PackageReadmeFile>\n        <Description>Extensions to language-ext framework effects system that wraps the IO behaviours from the .NET BCL</Description>\n        <PackageTags>C#, Functional, Language Extension, Aff, Eff, Monad, Option, Either, Reader, Writer, State, List, Set, Map, Queue, Memo, Memoization, Immutable, Lambda, Pattern Matching, Tuple</PackageTags>\n        <PackageIcon>lang-ext-small.png</PackageIcon>\n        <PackageProjectUrl>https://github.com/louthy/language-ext</PackageProjectUrl>\n        <PackageLicenseExpression>MIT</PackageLicenseExpression>\n        <TargetFramework>net10.0</TargetFramework>\n        <EnableDefaultCompileItems>false</EnableDefaultCompileItems>\n        <OutputType>library</OutputType>\n        <AssemblyVersion>5.0.0.0</AssemblyVersion>\n        <FileVersion>5.0.0.0</FileVersion>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <InternalsVisibleTo Include=\"LanguageExt.Tests\" />\n    </ItemGroup>\n    <ItemGroup>\n      <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n        <None Include=\"README.nuget.md\" Pack=\"true\" PackagePath=\"\\\"/>\n        <None Include=\"..\\Images\\lang-ext-small.png\" Pack=\"true\" PackagePath=\"\\\"/>\n        <ProjectReference Include=\"..\\LanguageExt.Streaming\\LanguageExt.Streaming.csproj\" />\n    </ItemGroup>\n\n    <ItemGroup>\n        <Compile Include=\"**\\*.cs\" />\n        <EmbeddedResource Include=\"**\\*.resx\" />\n    </ItemGroup>\n    <ItemGroup>\n        <Compile Remove=\"obj\\**\" />\n        <EmbeddedResource Remove=\"obj\\**\" />\n        <None Remove=\"obj\\**\" />\n    </ItemGroup>\n\n\n</Project>\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Implementations/ActivitySourceIO.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics;\n\nnamespace LanguageExt.Sys.Live.Implementations;\n\npublic record ActivitySourceIO(ActivityEnv Env) : LanguageExt.Sys.Traits.ActivitySourceIO\n{\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name and activity kind.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"kind\">The activity kind.</param>\n    /// <returns>The created activity object, if it had active listeners, or `None` if it has no event\n    /// listeners.</returns>\n    public IO<Activity?> StartActivity(string name, ActivityKind kind) =>\n        lift(() => Env.ActivitySource.StartActivity(name, kind));\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"kind\">The activity kind.</param>\n    /// <param name=\"parentContext\">The parent `ActivityContext` object to initialize the created activity object\n    /// with</param>\n    /// <param name=\"tags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"links\">The optional `ActivityLink` list to initialise the created activity object with.</param>\n    /// <param name=\"startTime\">The optional start timestamp to set on the created activity object.</param>\n    /// <returns>The created activity object, if it had active listeners, or null if it has no event listeners.</returns>\n    public IO<Activity?> StartActivity(\n        string name,\n        ActivityKind kind,\n        ActivityContext parentContext,\n        HashMap<string, object> tags = default,\n        Seq<ActivityLink> links = default,\n        DateTimeOffset startTime = default) =>\n        lift(() => Env.ActivitySource.StartActivity(\n                 name,\n                 kind,\n                 parentContext,\n                 tags.AsIterable().Map(pair => new KeyValuePair<string, object?>(pair.Key, pair.Value)),\n                 links,\n                 startTime));\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"kind\">The activity kind.</param>\n    /// <param name=\"parentId\">The parent Id to initialize the created activity object with.</param>\n    /// <param name=\"tags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"links\">The optional `ActivityLink` list to initialise the created activity object with.</param>\n    /// <param name=\"startTime\">The optional start timestamp to set on the created activity object.</param>\n    /// <returns>The created activity object, if it had active listeners, or null if it has no event listeners.</returns>\n    public IO<Activity?> StartActivity(\n        string name,\n        ActivityKind kind,\n        string parentId,\n        HashMap<string, object> tags = default,\n        Seq<ActivityLink> links = default,\n        DateTimeOffset startTime = default) =>\n        lift(() => Env.ActivitySource.StartActivity(\n                 name,\n                 kind,\n                 parentId,\n                 tags.AsIterable().Map(pair => new KeyValuePair<string, object?>(pair.Key, pair.Value)),\n                 links,\n                 startTime));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Implementations/ConsoleIO.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Live.Implementations;\n\npublic record ConsoleIO : Sys.Traits.ConsoleIO\n{\n    public static readonly Sys.Traits.ConsoleIO Default =\n        new ConsoleIO();\n\n    public IO<Option<ConsoleKeyInfo>> ReadKey() =>\n        lift(() => Optional(Console.ReadKey()));\n\n    public IO<Unit> Clear() =>\n        lift(Console.Clear);\n\n    public IO<Unit> SetBgColor(ConsoleColor color) =>\n        lift(() => { Console.BackgroundColor = color;});\n\n    public IO<Unit> SetColor(ConsoleColor color) =>\n        lift(() => { Console.ForegroundColor = color; });\n\n    public IO<Unit> ResetColor() =>\n        lift(Console.ResetColor);\n\n    public IO<ConsoleColor> BgColor=>\n        lift(() => Console.BackgroundColor);\n        \n    public IO<ConsoleColor> Color=>\n        lift(() => Console.ForegroundColor);\n\n    public IO<Option<int>> Read() =>\n        lift(() =>\n             {\n                 var k = Console.Read();\n                 return k == -1\n                            ? None\n                            : Some(k);\n             });\n\n    public IO<Option<string>> ReadLine()=>\n        lift(() => Optional(Console.ReadLine()));\n\n    public IO<Unit> WriteLine() =>\n        lift(Console.WriteLine);\n\n    public IO<Unit> WriteLine(string value) =>\n        lift(() => Console.WriteLine(value));\n\n    public IO<Unit> Write(string value) =>\n        lift(() => Console.Write(value));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Implementations/DirectoryIO.cs",
    "content": "using System;\nusing System.IO;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Live.Implementations;\n\npublic record DirectoryIO : Traits.DirectoryIO\n{\n    public static readonly Traits.DirectoryIO Default = \n        new DirectoryIO();\n\n    public IO<DirectoryInfo> Create(string path) =>\n        lift(() => Directory.CreateDirectory(path));\n\n    public IO<Unit> Delete(string path, bool recursive = true) =>\n        lift(() => Directory.Delete(path, recursive));\n\n    public IO<Option<DirectoryInfo>> GetParent(string path) =>\n        lift(() => Optional(Directory.GetParent(path)));\n\n    public IO<bool> Exists(string path) =>\n        lift(() => Directory.Exists(path));\n\n    public IO<Unit> SetCreationTime(string path, DateTime creationTime) =>\n        lift(() => Directory.SetCreationTime(path, creationTime));\n\n    public IO<Unit> SetCreationTimeUtc(string path, DateTime creationTimeUtc) =>\n        lift(() => Directory.SetCreationTimeUtc(path, creationTimeUtc));\n\n    public IO<DateTime> GetCreationTime(string path) =>\n        lift(() => Directory.GetCreationTime(path));\n\n    public IO<DateTime> GetCreationTimeUtc(string path) =>\n        lift(() => Directory.GetCreationTimeUtc(path));\n\n    public IO<Unit> SetLastWriteTime(string path, DateTime lastWriteTime) =>\n        lift(() => Directory.SetLastWriteTime(path, lastWriteTime));\n\n    public IO<Unit> SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc) =>\n        lift(() => Directory.SetLastWriteTime(path, lastWriteTimeUtc));\n\n    public IO<DateTime> GetLastWriteTime(string path) =>\n        lift(() => Directory.GetLastWriteTime(path));\n\n    public IO<DateTime> GetLastWriteTimeUtc(string path) =>\n        lift(() => Directory.GetLastWriteTimeUtc(path));\n\n    public IO<Unit> SetLastAccessTime(string path, DateTime lastAccessTime) =>\n        lift(() => Directory.SetLastAccessTime(path, lastAccessTime));\n\n    public IO<Unit> SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc) =>\n        lift(() => Directory.SetLastAccessTimeUtc(path, lastAccessTimeUtc));\n\n    public IO<DateTime> GetLastAccessTime(string path) =>\n        lift(() => Directory.GetLastAccessTime(path));\n\n    public IO<DateTime> GetLastAccessTimeUtc(string path) =>\n        lift(() => Directory.GetLastAccessTimeUtc(path));\n\n    public IO<Seq<string>> EnumerateDirectories(string path) =>\n        lift(() => Directory.EnumerateDirectories(path).AsIterable().ToSeq());\n\n    public IO<Seq<string>> EnumerateDirectories(string path, string searchPattern) =>\n        lift(() => Directory.EnumerateDirectories(path, searchPattern).AsIterable().ToSeq());\n\n    public IO<Seq<string>> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption) =>\n        lift(() => Directory.EnumerateDirectories(path, searchPattern, searchOption).AsIterable().ToSeq());\n\n    public IO<Seq<string>> EnumerateFiles(string path) =>\n        lift(() => Directory.EnumerateFiles(path).AsIterable().ToSeq());\n\n    public IO<Seq<string>> EnumerateFiles(string path, string searchPattern) =>\n        lift(() => Directory.EnumerateFiles(path, searchPattern).AsIterable().ToSeq());\n\n    public IO<Seq<string>> EnumerateFiles(string path, string searchPattern, SearchOption searchOption) =>\n        lift(() => Directory.EnumerateFiles(path, searchPattern, searchOption).AsIterable().ToSeq());\n\n    public IO<Seq<string>> EnumerateFileSystemEntries(string path) =>\n        lift(() => Directory.EnumerateFileSystemEntries(path).AsIterable().ToSeq());\n\n    public IO<Seq<string>> EnumerateFileSystemEntries(string path, string searchPattern) =>\n        lift(() => Directory.EnumerateFileSystemEntries(path, searchPattern).AsIterable().ToSeq());\n\n    public IO<Seq<string>> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption)  =>\n        lift(() => Directory.EnumerateFileSystemEntries(path, searchPattern, searchOption).AsIterable().ToSeq());\n\n    public IO<string> GetDirectoryRoot(string path) =>\n        lift(() => Directory.GetDirectoryRoot(path));\n\n    public IO<string> GetCurrentDirectory()  =>\n        lift(Directory.GetCurrentDirectory);\n\n    public IO<Unit> SetCurrentDirectory(string path) =>\n        lift(() => Directory.SetCurrentDirectory(path));\n\n    public IO<Unit> Move(string sourceDirName, string destDirName) =>\n        lift(() => Directory.Move(sourceDirName, destDirName));\n\n    public IO<Seq<string>> GetLogicalDrives() =>\n        lift(() => Directory.GetLogicalDrives().AsIterable().ToSeq());\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Implementations/EncodingIO.cs",
    "content": "using System.Text;\n\nnamespace LanguageExt.Sys.Live.Implementations;\n\npublic class EncodingIO : Sys.Traits.EncodingIO\n{\n    public static Sys.Traits.EncodingIO Default = new EncodingIO();\n    \n    public IO<Encoding> Encoding =>\n        LanguageExt.IO.pure(System.Text.Encoding.Default);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Implementations/EnvironmentIO.cs",
    "content": "using System;\nusing System.Collections;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Live.Implementations;\n\npublic record EnvironmentIO : Sys.Traits.EnvironmentIO\n{\n    public static readonly Sys.Traits.EnvironmentIO Default =\n        new EnvironmentIO();\n\n    /// <summary>\n    /// Gets the command line for this process.\n    /// </summary>\n    public IO<string> CommandLine() =>\n        lift(() => Environment.CommandLine);\n\n    /// <summary>\n    /// Sets the fully qualified path of the current working directory.\n    /// </summary>\n    /// directory: fully qualified path of the current working directory.\n    public IO<Unit> SetCurrentDirectory(string directory) =>\n        lift(() => { Environment.CurrentDirectory = directory; });\n\n    /// <summary>\n    /// Gets a unique identifier for the current managed thread.\n    /// </summary>\n    public IO<int> CurrentManagedThreadId() =>\n        lift(() => Environment.CurrentManagedThreadId);\n\n    /// <summary>\n    /// Terminates this process and returns an exit code to the operating \n    /// </summary>\n    public IO<Unit> Exit(int exitCode) =>\n        lift(() => Environment.Exit(exitCode));\n\n    /// <summary>\n    /// Gets the exit code of the process.\n    /// </summary>\n    public IO<int> ExitCode() =>\n        lift(() => Environment.ExitCode);\n\n    /// <summary>\n    /// Sets the exit code of the process.\n    /// </summary>\n    // exitCode: exit code of the process\n    public IO<Unit> SetExitCode(int exitCode) =>\n        lift(() => { Environment.ExitCode = exitCode; });\n\n    /// <summary>\n    /// Replaces the name of each environment variable embedded in the specified string with the string equivalent of the value of the variable, then returns the resulting string.\n    /// </summary>\n    /// name: A string containing the names of zero or more environment variables. Each environment variable is quoted with the percent sign character (%).\n    public IO<string> ExpandEnvironmentVariables(string name) =>\n        lift(() => Environment.ExpandEnvironmentVariables(name));\n\n    /// <summary>\n    /// Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message in error reporting to Microsoft.\n    /// </summary>\n    /// message: A message that explains why the process was terminated, or null if no explanation is provided.\n    public IO<Unit> FailFast(Option<string> message) =>\n        lift(() => Environment.FailFast(message.IfNone(\"\")));\n\n    /// <summary>\n    /// Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message and exception information in error reporting to Microsoft.\n    /// </summary>\n    /// message: A message that explains why the process was terminated, or null if no explanation is provided.\n    /// exception: An exception that represents the error that caused the termination. This is typically the exception in a catch block.\n    public IO<Unit> FailFast(Option<string> message, Option<Exception> exception) =>\n        lift(() => Environment.FailFast(message.IfNone(\"\"), exception.IfNone(() => BottomException.Default)));\n\n    /// <summary>\n    /// Returns a string array containing the command-line arguments for the current process.\n    /// </summary>\n    public IO<Seq<string>> GetCommandLineArgs() =>\n        lift(() => Environment.GetCommandLineArgs().AsIterable().ToSeq());\n\n    /// <summary>\n    /// Retrieves the value of an environment variable from the current process.\n    /// </summary>\n    /// variable: The name of an environment variable.\n    public IO<Option<string>> GetEnvironmentVariable(string variable) =>\n        lift(() => Optional(Environment.GetEnvironmentVariable(variable)));\n\n    /// <summary>\n    /// Retrieves the value of an environment variable from the current process or from the Windows operating system registry key for the current user or local machine.\n    /// </summary>\n    /// variable: The name of an environment variable.\n    public IO<Option<string>> GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) =>\n        lift(() => Optional(Environment.GetEnvironmentVariable(variable, target)));\n\n    /// <summary>\n    /// Retrieves all environment variable names and their values from the current process.\n    /// </summary>\n    public IO<HashMap<string, Option<string>>> GetEnvironmentVariables() =>\n        lift(() =>\n             {\n                 var hm = HashMap<string, Option<string>>();\n                 foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())\n                 {\n                     if (de.Key.ToString() is { } key)\n                     {\n                         hm = hm.Add(key, Optional(de.Value?.ToString()));\n                     }\n                 }\n\n                 return hm;\n             });\n\n    /// <summary>\n    /// Retrieves all environment variable names and their values from the current process, or from the Windows operating system registry key for the current user or local machine.\n    /// </summary>\n    /// target: One of the EnvironmentVariableTarget values. Only EnvironmentVariableTarget.Process is supported on .NET Core running on Unix-based systems.\n    public IO<HashMap<string, Option<string>>> GetEnvironmentVariables(EnvironmentVariableTarget target) =>\n        lift(() =>\n             {\n                 var hm = HashMap<string, Option<string>>();\n                 foreach (DictionaryEntry de in Environment.GetEnvironmentVariables(target))\n                 {\n                     if (de.Key.ToString() is { } key)\n                     {\n                         hm = hm.Add(key, Optional(de.Value?.ToString()));\n                     }\n                 }\n\n                 return hm;\n             });\n\n    /// <summary>\n    /// Gets the path to the system special folder that is identified by the specified enumeration.\n    /// </summary>\n    /// folder: One of enumeration values that identifies a system special folder.\n    public IO<string> GetFolderPath(Environment.SpecialFolder folder) =>\n        lift(() => Environment.GetFolderPath(folder));\n\n    /// <summary>\n    /// Gets the path to the system special folder that is identified by the specified enumeration, and uses a specified option for accessing special folders.\n    /// </summary>\n    /// folder: One of the enumeration values that identifies a system special folder.\n    /// option: One of the enumeration values that specifies options to use for accessing a special folder.\n    public IO<string> GetFolderPath(Environment.SpecialFolder folder, Environment.SpecialFolderOption option) =>\n        lift(() => Environment.GetFolderPath(folder, option));\n\n    /// <summary>\n    /// Returns an array of string containing the names of the logical drives on the current computer.\n    /// </summary>\n    /// string[] Environment.GetLogicalDrives()\n    public IO<Seq<string>> GetLogicalDrives() =>\n        lift(() => Environment.GetLogicalDrives().AsIterable().ToSeq());\n\n    /// <summary>\n    /// Gets a value that indicates whether the current application domain is being unloaded or the common language runtime (CLR) is shutting down.\n    /// </summary>\n    public IO<bool> HasShutdownStarted() =>\n        lift(() => Environment.HasShutdownStarted);\n\n    /// <summary>\n    /// Determines whether the current operating system is a 64-bit operating \n    /// </summary>\n    public IO<bool> Is64BitOperatingSystem() =>\n        lift(() => Environment.Is64BitOperatingSystem);\n\n    /// <summary>\n    /// Determines whether the current process is a 64-bit process.\n    /// </summary>\n    public IO<bool> Is64BitProcess() =>\n        lift(() => Environment.Is64BitProcess);\n\n    /// <summary>\n    /// Gets the NetBIOS name of this local computer.\n    /// </summary>\n    public IO<string> MachineName() =>\n        lift(() => Environment.MachineName);\n\n    /// <summary>\n    /// Gets the newline string defined for this environment.\n    /// </summary>\n    public IO<string> NewLine() =>\n        lift(() => Environment.NewLine);\n\n    /// <summary>\n    /// Gets an OperatingSystem object that contains the current platform identifier and version number.\n    /// </summary>\n    public IO<OperatingSystem> OSVersion() =>\n        lift(() => Environment.OSVersion);\n\n    /// <summary>\n    /// Gets the number of processors on the current machine.\n    /// </summary>\n    public IO<int> ProcessorCount() =>\n        lift(() => Environment.ProcessorCount);\n\n    /// <summary>\n    /// Creates, modifies, or deletes an environment variable stored in the current process.\n    /// </summary>\n    /// variable: The name of an environment variable.\n    /// value: A value to assign to variable .\n    public IO<Unit> SetEnvironmentVariable(string variable, Option<string> value) =>\n        lift(() => Environment.SetEnvironmentVariable(variable, value.IfNone(\"\")));\n\n    /// <summary>\n    /// Creates, modifies, or deletes an environment variable stored in the current process or in the Windows operating system registry key reserved for the current user or local machine.\n    /// </summary>\n    /// variable: The name of an environment variable.\n    /// value: A value to assign to variable.\n    /// target: One of the enumeration values that specifies the location of the environment variable.\n    public IO<Unit> SetEnvironmentVariable(string variable, Option<string> value, EnvironmentVariableTarget target) =>\n        lift(() => Environment.SetEnvironmentVariable(variable, value.IfNone(\"\"), target));\n\n    /// <summary>\n    /// Gets current stack trace information.\n    /// </summary>\n    public IO<string> StackTrace() =>\n        lift(() => Environment.StackTrace);\n\n    /// <summary>\n    /// Gets the fully qualified path of the system directory.\n    /// </summary>\n    public IO<string> SystemDirectory() =>\n        lift(() => Environment.SystemDirectory);\n\n    /// <summary>\n    /// Gets the number of bytes in the operating system's memory page.\n    /// </summary>\n    public IO<int> SystemPageSize() =>\n        lift(() => Environment.SystemPageSize);\n\n    /// <summary>\n    /// Gets the number of milliseconds elapsed since the system started.\n    /// </summary>\n    public IO<long> TickCount() =>\n        lift(() => Environment.TickCount64);\n\n    /// <summary>\n    /// Gets the network domain name associated with the current user.\n    /// </summary>\n    public IO<string> UserDomainName() =>\n        lift(() => Environment.UserDomainName);\n\n    /// <summary>\n    /// Gets a value indicating whether the current process is running in user interactive mode.\n    /// </summary>\n    public IO<bool> UserInteractive() =>\n        lift(() => Environment.UserInteractive);\n\n    /// <summary>\n    /// Gets the user name of the person who is currently logged on to the operating \n    /// </summary>\n    public IO<string> UserName() =>\n        lift(() => Environment.UserName);\n\n    /// <summary>\n    /// Gets a Version object that describes the major, minor, build, and revision numbers of the common language runtime.\n    /// </summary>\n    public IO<Version> Version() =>\n        lift(() => Environment.Version);\n\n    /// <summary>\n    /// Gets the amount of physical memory mapped to the process context.\n    /// </summary>\n    public IO<long> WorkingSet() =>\n        lift(() => Environment.WorkingSet);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Implementations/FileIO.cs",
    "content": "using System.Collections.Generic;\nusing System.IO;\nusing System.Text;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Live.Implementations;\n\n/// <summary>\n/// Real world interaction with the file-system\n/// </summary>\npublic record FileIO : Sys.Traits.FileIO\n{\n    public static readonly Sys.Traits.FileIO Default =\n        new FileIO();\n\n    /// <summary>\n    /// Copy file from one place to another\n    /// </summary>\n    public IO<Unit> Copy(string fromPath, string toPath, bool overwrite = false) =>\n        lift(() => File.Copy(fromPath, toPath, overwrite));\n\n    /// <summary>\n    /// Move file from one place to another\n    /// </summary>\n    public IO<Unit> Move(string fromPath, string toPath) =>\n        lift(() => File.Move(fromPath, toPath));\n\n    /// <summary>\n    /// Move file from one place to another\n    /// </summary>\n    public IO<Unit> Move(string fromPath, string toPath, bool overwrite) =>\n        lift(() => File.Move(fromPath, toPath, overwrite));\n\n    /// <summary>\n    /// Append lines to the end of a file\n    /// </summary>\n    public IO<Unit> AppendAllLines(string path, IEnumerable<string> lines, Encoding encoding) =>\n        liftIO(async env =>\n               {\n                   await File.AppendAllLinesAsync(path, lines, encoding, env.Token).ConfigureAwait(false);\n                   return unit;\n               });\n\n    /// <summary>\n    /// Read all lines from a file\n    /// </summary>\n    public IO<Seq<string>> ReadAllLines(string path, Encoding encoding) =>\n        liftIO(async env => (await File.ReadAllLinesAsync(path, encoding, env.Token).ConfigureAwait(false)).AsIterable().ToSeq());\n\n    /// <summary>\n    /// Write all lines to a file\n    /// </summary>\n    public IO<Unit> WriteAllLines(string path, IEnumerable<string> lines, Encoding encoding) =>\n        liftIO(async env =>\n               {\n                   await File.WriteAllLinesAsync(path, lines, encoding, env.Token).ConfigureAwait(false);\n                   return unit;\n               });\n    \n    /// <summary>\n    /// Read text from a file\n    /// </summary>\n    public IO<string> ReadAllText(string path, Encoding encoding) =>\n        liftIO(env => File.ReadAllTextAsync(path, encoding, env.Token));\n\n    /// <summary>\n    /// Read data from a file\n    /// </summary>\n    public IO<byte[]> ReadAllBytes(string path) =>\n        liftIO(env => File.ReadAllBytesAsync(path, env.Token));\n\n    /// <summary>\n    /// Write text to a file\n    /// </summary>\n    public IO<Unit> WriteAllText(string path, string text, Encoding encoding) =>\n        liftIO(async env =>\n               {\n                   await File.WriteAllTextAsync(path, text, encoding, env.Token).ConfigureAwait(false);\n                   return unit;\n               });\n\n    /// <summary>\n    /// Write data to a file\n    /// </summary>\n    public IO<Unit> WriteAllBytes(string path, byte[] data) =>\n        liftIO(async env =>\n               {\n                   await File.WriteAllBytesAsync(path, data, env.Token).ConfigureAwait(false);\n                   return unit;\n               });\n\n    /// <summary>\n    /// Delete a file\n    /// </summary>\n    public IO<Unit> Delete(string path) =>\n        lift(() => File.Delete(path));\n\n    /// <summary>\n    /// True if a file at the path exists\n    /// </summary>\n    public IO<bool> Exists(string path) =>\n        lift(() => File.Exists(path));\n\n    /// <summary>\n    /// Open a text file\n    /// </summary>\n    public IO<TextReader> OpenText(string path) =>\n        lift<TextReader>(() =>File.OpenText(path));\n\n    /// <summary>\n    /// Create a new text file to stream to\n    /// </summary>\n    public IO<TextWriter> CreateText(string path) =>\n        lift<TextWriter>(() =>File.CreateText(path));\n\n    /// <summary>\n    /// Return a stream to append text to\n    /// </summary>\n    public IO<TextWriter> AppendText(string path) =>\n        lift<TextWriter>(() => File.AppendText(path));\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public IO<Stream> OpenRead(string path) =>\n        lift<Stream>(() =>File.OpenRead(path));\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public IO<Stream> Open(string path, FileMode mode) =>\n        lift<Stream>(() => File.Open(path, mode));\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public IO<Stream> Open(string path, FileMode mode, FileAccess access) =>\n        lift<Stream>(() =>File.Open(path, mode, access));\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public IO<Stream> OpenWrite(string path) =>\n        lift<Stream>(() =>File.OpenWrite(path));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Implementations/TextReadIO.cs",
    "content": "using System;\nusing System.IO;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Live.Implementations;\n\npublic record TextReadIO : Sys.Traits.TextReadIO\n{\n    public static readonly Sys.Traits.TextReadIO Default =\n        new TextReadIO();\n\n    /// <summary>\n    /// Read a line of text from the stream\n    /// </summary>\n    public IO<Option<string>> ReadLine(TextReader reader) =>\n        liftIO(async env =>\n               {\n                   var str = await reader.ReadLineAsync(env.Token).ConfigureAwait(false);\n                   return str == null\n                              ? None\n                              : Some(str);\n               });\n\n    /// <summary>\n    /// Read the rest of the text in the stream\n    /// </summary>\n    public IO<string> ReadToEnd(TextReader reader) =>\n        liftIO(env => reader.ReadToEndAsync(env.Token));\n\n    /// <summary>\n    /// Read chars from the stream into the buffer\n    /// Returns the number of chars read\n    /// </summary>\n    public IO<int> Read(TextReader reader, Memory<char> buffer) =>\n        liftIO(async env => await reader.ReadAsync(buffer, env.Token));\n\n    /// <summary>\n    /// Close the reader\n    /// </summary>\n    public IO<Unit> Close(TextReader reader) =>\n        lift(() =>\n             {\n                 reader.Close();\n                 reader.Dispose();\n                 return unit;\n             });\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Implementations/TimeIO.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Live.Implementations;\n\npublic readonly struct TimeIO : Sys.Traits.TimeIO\n{\n    public static readonly Sys.Traits.TimeIO Default =\n        new TimeIO();\n\n    /// <summary>\n    /// Current date time\n    /// </summary>\n    public IO<DateTime> Now =>\n        lift(() => DateTime.Now);\n        \n    /// <summary>\n    /// Current date time\n    /// </summary>\n    public IO<DateTime> UtcNow => \n        lift(() => DateTime.UtcNow);\n\n    /// <summary>\n    /// Today's date \n    /// </summary>\n    public IO<DateTime> Today => \n        lift(() => DateTime.Today);\n\n    /// <summary>\n    /// Pause a task until a specified time\n    /// </summary>\n    public IO<Unit> SleepUntil(DateTime dt) =>\n        from now in Now\n        from res in dt <= now\n                        ? unitIO\n                        : liftIO(async env => await Task.Delay(dt - now, env.Token).ConfigureAwait(false))\n        select res;\n\n    /// <summary>\n    /// Pause a task until for a specified length of time\n    /// </summary>\n    public IO<Unit> SleepFor(TimeSpan ts) =>\n        liftIO(async env => await Task.Delay(ts, env.Token).ConfigureAwait(false));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Live/Runtime.cs",
    "content": "using System;\nusing LanguageExt.Traits;\nusing LanguageExt.Sys.Traits;\n\nnamespace LanguageExt.Sys.Live;\n\n/// <summary>\n/// Live IO runtime\n/// </summary>\npublic record Runtime(RuntimeEnv Env) : \n    Local<Eff<Runtime>, ActivityEnv>,\n    Has<Eff<Runtime>, ActivitySourceIO>,\n    Has<Eff<Runtime>, ConsoleIO>,\n    Has<Eff<Runtime>, FileIO>,\n    Has<Eff<Runtime>, TextReadIO>,\n    Has<Eff<Runtime>, TimeIO>,\n    Has<Eff<Runtime>, EnvironmentIO>,\n    Has<Eff<Runtime>, DirectoryIO>,\n    Has<Eff<Runtime>, EncodingIO>\n{\n    /// <summary>\n    /// Constructor function\n    /// </summary>\n    public static Runtime New() =>\n        new (new RuntimeEnv(ActivityEnv.Default));\n\n    static K<Eff<Runtime>, A> asks<A>(Func<Runtime, A> f) =>\n        Readable.asks<Eff<Runtime>, Runtime, A>(f);\n\n    static K<Eff<Runtime>, A> local<A>(Func<Runtime, Runtime> f, K<Eff<Runtime>, A> ma) =>\n        Readable.local(f, ma);\n\n    static K<Eff<Runtime>, A> pure<A>(A value) =>\n        Eff<Runtime, A>.Pure(value);\n    \n    /// <summary>\n    /// Activity\n    /// </summary>\n    static K<Eff<Runtime>, ActivitySourceIO> Has<Eff<Runtime>, ActivitySourceIO>.Ask =>\n        asks<ActivitySourceIO>(rt => new Implementations.ActivitySourceIO(rt.Env.Activity));\n\n    /// <summary>\n    /// Access the console environment\n    /// </summary>\n    /// <returns>Console environment</returns>\n    static K<Eff<Runtime>, ConsoleIO> Has<Eff<Runtime>, ConsoleIO>.Ask { get; } =\n        pure(Implementations.ConsoleIO.Default);\n\n    /// <summary>\n    /// Access the file environment\n    /// </summary>\n    /// <returns>File environment</returns>\n    static K<Eff<Runtime>, FileIO> Has<Eff<Runtime>, FileIO>.Ask { get; } =\n        pure(Implementations.FileIO.Default);\n\n    /// <summary>\n    /// Access the TextReader environment\n    /// </summary>\n    /// <returns>TextReader environment</returns>\n    static K<Eff<Runtime>, TextReadIO> Has<Eff<Runtime>, TextReadIO>.Ask { get; } =\n        pure(Implementations.TextReadIO.Default);\n \n    /// <summary>\n    /// Access the time environment\n    /// </summary>\n    /// <returns>Time environment</returns>\n    static K<Eff<Runtime>, TimeIO> Has<Eff<Runtime>, TimeIO>.Ask { get; } =\n        pure(Implementations.TimeIO.Default);\n\n    /// <summary>\n    /// Access the operating-system environment\n    /// </summary>\n    /// <returns>Operating-system environment environment</returns>\n    static K<Eff<Runtime>, EnvironmentIO> Has<Eff<Runtime>, EnvironmentIO>.Ask { get; } =\n        pure(Implementations.EnvironmentIO.Default);\n\n    /// <summary>\n    /// Access the directory environment\n    /// </summary>\n    /// <returns>Directory environment</returns>\n    static K<Eff<Runtime>, DirectoryIO> Has<Eff<Runtime>, DirectoryIO>.Ask { get; } =\n        pure(Implementations.DirectoryIO.Default);\n\n    /// <summary>\n    /// Access the directory environment\n    /// </summary>\n    /// <returns>Directory environment</returns>\n    static K<Eff<Runtime>, EncodingIO> Has<Eff<Runtime>, EncodingIO>.Ask { get; } =\n        pure(Implementations.EncodingIO.Default);\n\n    /// <summary>\n    /// Run with a local ActivityEnv \n    /// </summary>\n    static K<Eff<Runtime>, A> Local<Eff<Runtime>, ActivityEnv>.With<A>(Func<ActivityEnv, ActivityEnv> f, K<Eff<Runtime>, A> ma) => \n        local(rt => rt with { Env = rt.Env with { Activity = f(rt.Env.Activity) } }, ma);\n\n    /// <summary>\n    /// Read the current ActivityEnv\n    /// </summary>\n    static K<Eff<Runtime>, ActivityEnv> Has<Eff<Runtime>, ActivityEnv>.Ask =>\n        asks(rt => rt.Env.Activity);\n}\n\npublic record RuntimeEnv(ActivityEnv Activity) : IDisposable\n{\n    public void Dispose() => \n        Activity.Dispose();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/MemoryConsole.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Collections;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Collections.Concurrent;\nusing System.Linq;\nusing LanguageExt.UnsafeValueAccess;\n\nnamespace LanguageExt.Sys\n{\n    /// <summary>\n    /// An in-memory console emulation\n    /// </summary>\n    /// <remarks>\n    /// Mostly for use in test runtimes.  This simulates the real System.IO.Console, with additional functionality\n    /// for pre-building a keyboard buffer (WriteKey, WriteKeyChar, WriteKeyString) and committing them as though\n    /// they were typed.  ReadKey and the other Read* methods will read the entries from the pre-built keyboard\n    /// buffer.\n    ///\n    /// There is no public API for this, other than the prepping of the keyboard buffer, which is outside of the\n    /// normal console system.  \n    /// </remarks>\n    public class MemoryConsole : IEnumerable<string>\n    {\n        const ConsoleColor DefaultBgColor = ConsoleColor.Black;\n        const ConsoleColor DefaultColor = ConsoleColor.White;\n\n        readonly ConcurrentQueue<ConsoleKeyInfo> KeyboardBuffer = new();\n        readonly ConcurrentStack<string> Console = new();\n\n        public MemoryConsole() =>\n            Console.Push(\"\");\n\n        /// <summary>\n        /// Write a key into the keyboard buffer\n        /// </summary>\n        /// <remarks>\n        /// Won't show in the console until Commit or Read* is called \n        /// </remarks>\n        public Unit WriteKey(ConsoleKeyInfo key)\n        {\n            KeyboardBuffer.Enqueue(key);\n            return default;\n        }\n\n        /// <summary>\n        /// Write a character into the keyboard buffer\n        /// </summary>\n        /// <remarks>\n        /// Won't show in the console until Commit or Read* is called \n        /// </remarks>\n        public Unit WriteKeyChar(char ch)\n        {\n            KeyboardBuffer.Enqueue(new ConsoleKeyInfo(ch, CharToConsoleKey(ch), false, false, false));\n            return default;\n        }\n        \n        /// <summary>\n        /// Write a character into the keyboard buffer\n        /// </summary>\n        /// <remarks>\n        /// No newline character is written\n        /// Won't show in the console until Commit or Read* is called \n        /// </remarks>\n        public Unit WriteKeyString(string str)\n        {\n            foreach (var ch in str)\n            {\n                WriteKeyChar(ch);\n            }\n            return default;\n        }\n        \n        /// <summary>\n        /// Write a series of characters into the keyboard buffer followed by a newline\n        /// </summary>\n        /// <remarks>\n        /// Won't show in the console until Commit or Read* is called \n        /// </remarks>\n        public Unit WriteKeyLine(string str)\n        {\n            WriteKeyString(str);\n            WriteKeyChar('\\n');\n            return default;\n        }\n\n        /// <summary>\n        /// Commit what's in the keyboard buffer (as though they've been typed in)\n        /// </summary>\n        /// <returns></returns>\n        public Unit Commit()\n        {\n            while(KeyboardBuffer.Count > 0)\n            {\n                ReadKey().Map(WriteKey);\n            }\n            return default;\n        }\n\n        internal Option<ConsoleKeyInfo> ReadKey() =>\n            KeyboardBuffer.TryDequeue(out var key)\n                ? key\n                : None;\n\n        internal ConsoleKey CharToConsoleKey(char ch) =>\n            Enum.TryParse<ConsoleKey>(ch.ToString(), out var ck) ? ck : default;\n        \n        internal Unit Clear()\n        {\n            Console.Clear();\n            return default;\n        }\n\n        internal Unit SetBgColor(ConsoleColor color)\n        {\n            BgColor = color;\n            return default;\n        }\n\n        internal Unit SetColor(ConsoleColor color)\n        {\n            Color = color;\n            return default;\n        }\n\n        internal Unit ResetColor()\n        {\n            BgColor = DefaultBgColor;\n            Color = DefaultColor;\n            return default;\n        }\n\n        internal ConsoleColor BgColor { get; private set; } = DefaultBgColor;\n        internal ConsoleColor Color { get; private set; } = DefaultColor;\n\n        internal Option<int> Read()\n        {\n            var ok = ReadKey();\n            if (ok.IsNone) return None;\n            var kc = ok.ValueUnsafe().KeyChar;\n            var ch = Convert.ToChar(kc);\n            if (ch == '\\n')\n            {\n                Console.Push(\"\");\n            }\n            else\n            {\n                lock (Console)\n                {\n                    if (Console.TryPop(out var line))\n                    {\n                        Console.Push(line + Convert.ToChar(kc));\n                    }\n                }\n            }\n\n            return kc;\n        }\n\n        internal Option<string> ReadLine()\n        {\n            List<char> chs = new();\n            while (true)\n            {\n                var ok = ReadKey();\n                if (ok.IsNone) return None;\n                var ch = ok.ValueUnsafe().KeyChar;\n                if (ch.ToString() == Environment.NewLine || ch == '\\n'|| ch == '\\r') return new string(chs.ToArray());\n                chs.Add(ch);\n            }\n        }\n        \n        internal Unit WriteLine()\n        {\n            Console.Push(\"\");\n            return unit;\n        }\n\n        internal Unit WriteLine(string value)\n        {\n            Console.Push(value);\n            return unit;\n        }\n\n        internal Unit Write(string value)\n        {\n            lock (Console)\n            {\n                if (Console.TryPop(out var line))\n                {\n                    Console.Push(line + value);\n                }\n            }\n            return unit;\n        }\n\n        public IEnumerator<string> GetEnumerator() =>\n            Console.Reverse().Skip(1).GetEnumerator();\n\n        IEnumerator IEnumerable.GetEnumerator() =>\n            Console.Reverse().Skip(1).GetEnumerator();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Sys/MemorySystemEnvironment.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Concurrent;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys;\n\n/// <summary>\n/// In-memory representation of the System.Environment \n/// </summary>\n/// <remarks>\n/// Use: MemorySystemEnvironment.InitFromSystem(), to initialise from the real System.Environment and then tweak\n///      for use in unit-tests using the With(...) method. \n/// </remarks>\npublic class MemorySystemEnvironment\n{\n    public MemorySystemEnvironment(\n        ConcurrentDictionary<string, Option<string>> processEnvironmentVariables, \n        ConcurrentDictionary<string, Option<string>> userEnvironmentVariables, \n        ConcurrentDictionary<string, Option<string>> systemEnvironmentVariables, \n        int exitCode, \n        string commandLine, \n        int currentManagedThreadId, \n        Seq<string> commandLineArgs, \n        Seq<string> logicalDrives, \n        string newLine, \n        bool hasShutdownStarted,\n        bool is64BitOperatingSystem, \n        bool is64BitProcess, \n        string machineName, \n        OperatingSystem osVersion, \n        int processorCount, \n        string stackTrace, \n        string systemDirectory, \n        int systemPageSize, \n        long tickCount, \n        string userDomainName, \n        bool userInteractive, \n        string userName, \n        Version version, \n        long workingSet, \n        Func<Environment.SpecialFolder, Environment.SpecialFolderOption, string> getFolderPath)\n    {\n        ProcessEnvironmentVariables = processEnvironmentVariables;\n        UserEnvironmentVariables    = userEnvironmentVariables;\n        SystemEnvironmentVariables  = systemEnvironmentVariables;\n        ExitCode                    = exitCode;\n        CommandLine                 = commandLine;\n        CurrentManagedThreadId      = currentManagedThreadId;\n        CommandLineArgs             = commandLineArgs;\n        LogicalDrives               = logicalDrives;\n        NewLine                     = newLine;\n        HasShutdownStarted          = hasShutdownStarted;\n        Is64BitOperatingSystem      = is64BitOperatingSystem;\n        Is64BitProcess              = is64BitProcess;\n        MachineName                 = machineName;\n        OSVersion                   = osVersion;\n        ProcessorCount              = processorCount;\n        StackTrace                  = stackTrace;\n        SystemDirectory             = systemDirectory;\n        SystemPageSize              = systemPageSize;\n        TickCount                   = tickCount;\n        UserDomainName              = userDomainName;\n        UserInteractive             = userInteractive;\n        UserName                    = userName;\n        Version                     = version;\n        WorkingSet                  = workingSet;\n        GetFolderPath               = getFolderPath;\n    }\n\n    // Mutable\n    public ConcurrentDictionary<string, Option<string>> ProcessEnvironmentVariables;\n    public ConcurrentDictionary<string, Option<string>> UserEnvironmentVariables;\n    public ConcurrentDictionary<string, Option<string>> SystemEnvironmentVariables;\n    public int ExitCode;\n    public bool HasShutdownStarted;\n        \n    // Immutable\n    public readonly string CommandLine;\n    public readonly int CurrentManagedThreadId;\n    public readonly Seq<string> CommandLineArgs;\n    public readonly Seq<string> LogicalDrives;\n    public readonly string NewLine;\n    public readonly bool Is64BitOperatingSystem;\n    public readonly bool Is64BitProcess;\n    public readonly string MachineName;\n    public readonly OperatingSystem OSVersion;\n    public readonly int ProcessorCount;\n    public readonly string StackTrace;\n    public readonly string SystemDirectory;\n    public readonly int SystemPageSize;\n    public readonly long TickCount;\n    public readonly string UserDomainName;\n    public readonly bool UserInteractive;\n    public readonly string UserName;\n    public readonly Version Version;\n    public readonly long WorkingSet;\n\n    // Injectable \n    public readonly Func<Environment.SpecialFolder, Environment.SpecialFolderOption, string> GetFolderPath;\n        \n    public MemorySystemEnvironment With(\n        ConcurrentDictionary<string, Option<string>>? ProcessEnvironmentVariables = null, \n        ConcurrentDictionary<string, Option<string>>? UserEnvironmentVariables = null, \n        ConcurrentDictionary<string, Option<string>>? SystemEnvironmentVariables = null, \n        int? ExitCode = null, \n        string? CommandLine = null, \n        int? CurrentManagedThreadId = null, \n        Seq<string>? CommandLineArgs = null, \n        Seq<string>? LogicalDrives = null, \n        string? NewLine = null, \n        bool? HasShutdownStarted = null,\n        bool? Is64BitOperatingSystem = null, \n        bool? Is64BitProcess = null, \n        string? MachineName = null, \n        OperatingSystem? OSVersion = null, \n        int? ProcessorCount = null, \n        string? StackTrace = null, \n        string? SystemDirectory = null, \n        int? SystemPageSize = null, \n        long? TickCount = null, \n        string? UserDomainName = null, \n        bool? UserInteractive = null, \n        string? UserName = null, \n        Version? Version = null, \n        long? WorkingSet = null, \n        Func<Environment.SpecialFolder, Environment.SpecialFolderOption, string>? GetFolderPath = null) =>\n        new MemorySystemEnvironment(\n            ProcessEnvironmentVariables ?? this.ProcessEnvironmentVariables,\n            UserEnvironmentVariables    ?? this.UserEnvironmentVariables,\n            SystemEnvironmentVariables  ?? this.SystemEnvironmentVariables,\n            ExitCode                    ?? this.ExitCode,\n            CommandLine                 ?? this.CommandLine,\n            CurrentManagedThreadId      ?? this.CurrentManagedThreadId,\n            CommandLineArgs             ?? this.CommandLineArgs,\n            LogicalDrives               ?? this.LogicalDrives,\n            NewLine                     ?? this.NewLine,\n            HasShutdownStarted          ?? this.HasShutdownStarted,\n            Is64BitOperatingSystem      ?? this.Is64BitOperatingSystem,\n            Is64BitProcess              ?? this.Is64BitProcess,\n            MachineName                 ?? this.MachineName,\n            OSVersion                   ?? this.OSVersion,\n            ProcessorCount              ?? this.ProcessorCount,\n            StackTrace                  ?? this.StackTrace,\n            SystemDirectory             ?? this.SystemDirectory,\n            SystemPageSize              ?? this.SystemPageSize,\n            TickCount                   ?? this.TickCount,\n            UserDomainName              ?? this.UserDomainName,\n            UserInteractive             ?? this.UserInteractive,\n            UserName                    ?? this.UserName,\n            Version                     ?? this.Version,\n            WorkingSet                  ?? this.WorkingSet,\n            GetFolderPath               ?? this.GetFolderPath\n        );\n\n    public static MemorySystemEnvironment InitFromSystem() =>\n        new MemorySystemEnvironment(\n            processEnvironmentVariables: GetEnvs(EnvironmentVariableTarget.Process),\n            userEnvironmentVariables: GetEnvs(EnvironmentVariableTarget.User),\n            systemEnvironmentVariables: GetEnvs(EnvironmentVariableTarget.Machine),\n            exitCode: Environment.ExitCode,\n            commandLine: Environment.CommandLine,\n            currentManagedThreadId: Environment.CurrentManagedThreadId,\n            commandLineArgs: Environment.GetCommandLineArgs().AsIterable().ToSeq().Strict(),\n            logicalDrives: Environment.GetLogicalDrives().AsIterable().ToSeq().Strict(),\n            newLine: Environment.NewLine,\n            hasShutdownStarted: Environment.HasShutdownStarted,\n            is64BitOperatingSystem: Environment.Is64BitOperatingSystem,\n            is64BitProcess: Environment.Is64BitProcess,\n            machineName: Environment.MachineName,\n            osVersion: Environment.OSVersion,\n            processorCount: Environment.ProcessorCount,\n            stackTrace: Environment.StackTrace,\n            systemDirectory: Environment.SystemDirectory,\n            systemPageSize: Environment.SystemPageSize,\n            tickCount: Environment.TickCount,\n            userDomainName: Environment.UserDomainName,\n            userInteractive: Environment.UserInteractive,\n            userName: Environment.UserName,\n            version: Environment.Version,\n            workingSet: Environment.WorkingSet,\n            getFolderPath: Environment.GetFolderPath\n        );\n\n    static ConcurrentDictionary<string, Option<string>> GetEnvs(EnvironmentVariableTarget target)\n    {\n        var dict = new ConcurrentDictionary<string, Option<string>>();\n        foreach (DictionaryEntry de in Environment.GetEnvironmentVariables(target))\n        {\n            if (de.Key.ToString() is {} key)\n            {\n                dict.TryAdd(key, Optional(de.Value).Bind(v => Optional(v.ToString())));\n            }\n        }\n        return dict;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Sys/README.nuget.md",
    "content": "# LanguageExt.Sys\n\n`LanguageExt.Sys` is the a wrapper around the `System` namespace IO functions and is part of the [language-ext functional programming framework](https://github.com/louthy/language-ext).\n\nThe framework uses and abuses the features of C# to provide a pure functional-programming \n'Base Class Library' that, if you squint, can look like extensions to the language itself. \nThe desire here is to make programming in C# much more robust by helping the engineer's \ninertia flow in the direction of declarative and pure functional code rather than imperative. \n\nUsing these techniques for large code-bases can bring tangible benefits to long-term maintenance \nby removing hidden complexity and by easing the engineer's cognitive load.\n\n## Features\n\n### [Functional effects and IO](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/index.html)\n\n| Location | Feature      | Description                                                                                                                                                                                              |\n|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `IO<A>`      | [A synchronous and asynchronous side-effect: an IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/IO/index.html)                                                                  |\n| `Core`   | `Eff<A>`     | [A synchronous and asynchronous side-effect with error handling](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20no%20runtime/index.html)                                       |\n| `Core`   | `Eff<RT, A>` | [Same as `Eff<A>` but with an injectable runtime for dependency-injection: a unit testable IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20with%20runtime/index.html) |\n| `Core`   | Pipes        | [A clean and powerful stream processing system that lets you build and connect reusable streaming components](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Pipes/index.html)           |\n| `Core`   | StreamT      | [less powerful (than Pipes), but easier to use streaming effects transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/StreamT/index.html)                                         |\n\n### [Atomic concurrency and collections](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/index.html)\n\n| Location | Feature                            | Description                                                                                                                                            |\n|----------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Atom<A>`                          | [A lock-free atomically mutable reference for working with shared state](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/Atom)      |\n| `Core`   | `Ref<A>`                           | [An atomic reference to be used in the transactional memory system](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/STM)            |\n| `Core`   | `AtomHashMap<K, V>`                | [An immutable `HashMap` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomHashMap) |\n| `Core`   | `AtomSeq<A>`                       | [An immutable `Seq` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomSeq)         |\n| `Core`   | `VectorClock<A>`                   | [Understand distributed causality](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VectorClock)                                     |\n| `Core`   | `VersionVector<A>`                 | [A vector clock with some versioned data](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionVector)                            |\n| `Core`   | `VersionHashMap <ConflictV, K, V>` | [Distrubuted atomic versioning of keys in a hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionHashMap)               |\n\n### [Immutable collections](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/index.html)\n\n| Location | Feature              | Description                                                                                                                                                                                                             |\n|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Arr<A>`             | [Immutable array](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Arr/index.html)                                                                                                        |\n| `Core`   | `Seq<A>`             | [Lazy immutable list, evaluate at-most-once](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Seq/index.html) - very, very fast!                                                          |\n| `Core`   | `Iterable<A>`        | [Wrapper around `IEnumerable` with support for traits](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Iterable/index.html) - enables the higher-kinded traits to work with enumerables. |\n| `Core`   | `Lst<A>`             | [Immutable list](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/List/index.html) - use `Seq` over `Lst` unless you need `InsertAt`                                                      |\n| `Core`   | `Map<K, V>`          | [Immutable map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                                                          |\n| `Core`   | `Map<OrdK, K, V>`    | [Immutable map with Ord constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                               |\n| `Core`   | `HashMap<K, V>`      | [Immutable hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                                                 |\n| `Core`   | `HashMap<EqK, K, V>` | [Immutable hash-map with Eq constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                       |\n| `Core`   | `Set<A>`             | [Immutable set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                                                          |\n| `Core`   | `Set<OrdA, A>`       | [Immutable set with Ord constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                               |\n| `Core`   | `HashSet<A>`         | [Immutable hash-set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                                                 |\n| `Core`   | `HashSet<EqA, A>`    | [Immutable hash-set with Eq constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                       |\n| `Core`   | `Que<A>`             | [Immutable queue](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Queue/index.html)                                                                                                      |\n| `Core`   | `Stck<A>`            | [Immutable stack](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Stack/index.html)                                                                                                      |\n\n### [Optional and alternative value monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/index.html)\n\n| Location | Feature                         | Description                                                                                                                                                                                              |\n|----------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Option<A>`                     | [Option monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Option/index.html)                                                                                     |\n| `Core`   | `OptionT<M, A>`                 | [Option monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/OptionT/index.html)                                                                        |\n| `Core`   | `Either<L,R>`                   | [Right/Left choice monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Either/index.html)                                                                          |\n| `Core`   | `EitherT<L, M, R>`              | [Right/Left choice monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/EitherT/index.html)                                                             |\n| `Core`   | `Fin<A>`                        | [`Error` handling monad, like `Either<Error, A>`](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Fin/index.html)                                                     |\n| `Core`   | `FinT<M, A>`                    | [`Error` handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/FinT/index.html)                                                                 |\n| `Core`   | `Try<A>`                        | [Exception handling monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Try/index.html)                                                                            |\n| `Core`   | `TryT<M, A>`                    | [Exception handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/TryT/index.html)                                                               |\n| `Core`   | `Validation<FAIL ,SUCCESS>`     | [Validation applicative and monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Validation/index.html) for collecting multiple errors before aborting an operation |\n| `Core`   | `ValidationT<FAIL, M, SUCCESS>` | [Validation applicative and monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/ValidationT/index.html)                                                |\n\n### [State managing monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/index.html)\n\n| Location | Feature            | Description                                                                                                                                                                             |\n|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Reader<E, A>`     | [Reader monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/Reader/index.html)                                               |\n| `Core`   | `ReaderT<E, M, A>` | [Reader monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/ReaderT/index.html)                                  |\n| `Core`   | `Writer<W, A>`     | [Writer monad that logs to a `W` constrained to be a Monoid](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/Writer/index.html) |\n| `Core`   | `WriterT<W, M, A>` | [Writer monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/WriterT/index.html)                                  |\n| `Core`   | `State<S, A>`      | [State monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/State/index.html)                                                  |\n| `Core`   | `StateT<S, M, A>`  | [State monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/StateT/index.html)                                     |\n\n### [Parser combinators](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)\n\n| Location | Feature        | Description                                                                                                                    |\n|----------|----------------|--------------------------------------------------------------------------------------------------------------------------------|\n| `Parsec` | `Parser<A>`    | [String parser monad and full parser combinators library](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html) |\n| `Parsec` | `Parser<I, O>` | [Parser monad that can work with any input stream type](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)   |\n\n### [Pretty](https://louthy.github.io/language-ext/LanguageExt.Core/Pretty/index.html)\n\n| Location | Feature  | Description                                      |\n|----------|----------|--------------------------------------------------|\n| `Core`   | `Doc<A>` | Produce nicely formatted text with smart layouts |\n\n### [Differencing](https://louthy.github.io/language-ext/LanguageExt.Core/DataTypes/Patch/index.html)\n\n| Location | Feature         | Description                                                                                                                                                                                                                          |\n|----------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Patch<EqA, A>` | Uses patch-theory to efficiently calculate the difference (`Patch.diff(list1, list2)`) between two collections of `A` and build a patch which can be applied (`Patch.apply(patch, list)`) to one to make the other (think git diff). |\n\n### [Traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/index.html)\n\nThe traits are major feature of `v5`+ language-ext that makes generic programming with higher-kinds a reality.  Check out Paul's [series on Higher Kinds](https://paullouth.com/higher-kinds-in-c-with-language-ext/) to get a deeper insight.\n\n| Location | Feature                                | Description                                                                                                                                                            |\n|----------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `MonoidK<F>`                       | [A monoid on applicative functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Alternative/index.html)                                               |\n| `Core`   | `Applicative<F>`                       | [Applicative functor](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Applicative/index.html)                                                            |\n| `Core`   | `Eq<A>`                                | [Ad-hoc equality trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Eq/index.html)                                                                   |\n| `Core`   | `Fallible<F>`                          | [Trait that describes types that can fail](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Fallible/index.html)                                          |\n| `Core`   | `Foldable<T>`                          | [Aggregation over a structure](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Foldable/index.html)                                                      |\n| `Core`   | `Functor<F>`                           | [Functor `Map`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Functor/index.html)                                                                      |\n| `Core`   | `Has<M, TRAIT>`                        | [Used in runtimes to enable DI-like capabilities](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Has/index.html)                                        |\n| `Core`   | `Hashable<A>`                          | [Ad-hoc has-a-hash-code trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Hashable/index.html)                                                      |\n| `Core`   | `Local<M, E>`                          | [Creates a local environment to run a computation ](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Local/index.html)                                    |\n| `Core`   | `Monad<M>`                             | [Monad trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/Monad/index.html)                                                                   |\n| `Core`   | `MonadT<M, N>`                         | [Monad transformer trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/MonadT/index.html)                                                      |\n| `Core`   | `Monoid<A>`                            | [A monoid is a type with an identity `Empty` and an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monoid/index.html) |\n| `Core`   | `MonoidK<M>`                           | [Equivalent of monoids for working on higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/MonoidK/index.html)                           |\n| `Core`   | `Mutates<M, OUTER_STATE, INNER_STATE>` | [Used in runtimes to enable stateful operations](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Mutates/index.html)                                     |\n| `Core`   | `Ord<A>`                               | [Ad-hoc ordering / comparisons](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Ord/index.html)                                                          |\n| `Core`   | `Range<SELF, NumOrdA, A>`              | [Abstraction of a range of values](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Range/index.html)                                                     |\n| `Core`   | `Readable<M, Env>`                     | [Generalised Reader monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Readable/index.html)                                              |\n| `Core`   | `SemigroupK<F>`                   | [A semigroup on functors](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                                                    |\n| `Core`   | `Semigroup<A>`                         | [Provides an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Semigroup/index.html)                                     |\n| `Core`   | `SemigroupK<M>`                        | [Equivalent of semigroups for working with higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                   |\n| `Core`   | `Stateful<M, S>`                       | [Generalised State monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Stateful/index.html)                                               |\n| `Core`   | `Traversable<T>`                       | [Traversable structures support element-wise sequencing of Applicative effects](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Traversable/index.html)  |\n| `Core`   | `Writable<M, W>`                       | [Generalised Writer monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Writable/index.html)                                              |\n\n### [Value traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Domain/index.html)\n\nThese work a little like `NewType` but they impart semantic meaning and some common operators for the underlying value.\n\n| Location | Feature                              | Description                                                                                                                                                                                                                                       |\n|----------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `DomainType<SELF, REPR>`             | Provides a mapping from `SELF` to an underlying representation: `REPR`                                                                                                                                                                            |\n| `Core`   | `Identifier <SELF>`                  | Identifiers (like IDs in databases: `PersonId` for example), they are equivalent to `DomaintType` with equality.                                                                                                                                  |\n| `Core`   | `VectorSpace<SELF, SCALAR>`          | Scalable values; can add and subtract self, but can only multiply and divide by a scalar. Can also negate.                                                                                                                                        |\n| `Core`   | `Amount <SELF, SCALAR>`              | Quantities, such as the amount of money in USD on a bank account or a file size in bytes. Derives `VectorSpace`, `IdentifierLike`, `DomainType`, and is orderable (comparable).                                                                   |\n| `Core`   | `LocusLike <SELF, SCALAR, DISTANCE>` | Works with space-like structures. Spaces have absolute and relative distances. Has an origin/zero point and derives `DomainType`, `IdentifierLike`, `AmountLike` and `VectorSpace`.  `DISTANCE` must also be an `AmountLike<SELF, REPR, SCALAR>`. |\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Console.Eff.cs",
    "content": "﻿using System;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing LanguageExt.Sys.Traits;\n\nnamespace LanguageExt.Sys;\n\n/// <summary>\n/// Time IO \n/// </summary>\npublic static class Console<RT>\n    where RT : \n        Has<Eff<RT>, ConsoleIO>\n{\n    /// <summary>\n    /// Read a key from the console\n    /// </summary>\n    public static Eff<RT, ConsoleKeyInfo> readKey =>\n        Console<Eff<RT>, RT>.readKey.As();\n\n    /// <summary>\n    /// Read keys from the console and push them downstream \n    /// </summary>\n    public static Producer<RT, ConsoleKeyInfo, Unit> readKeys =>\n        Console<Eff<RT>, RT>.readKeys;\n\n    /// <summary>\n    /// Clear the console\n    /// </summary>\n    public static Eff<RT, Unit> clear =>\n        Console<Eff<RT>, RT>.clear.As();\n\n    /// <summary>\n    /// Read from the console\n    /// </summary>\n    public static Eff<RT, int> read =>\n        Console<Eff<RT>, RT>.read.As();\n\n    /// <summary>\n    /// Read chars from the console and push them downstream \n    /// </summary>\n    public static Producer<RT, int, Unit> reads =>\n        Console<Eff<RT>, RT>.reads;\n\n    /// <summary>\n    /// Read from the console\n    /// </summary>\n    public static Eff<RT, string> readLine =>\n        Console<Eff<RT>, RT>.readLine.As();\n\n    /// <summary>\n    /// Read lines from the console and push them downstream \n    /// </summary>\n    public static Producer<RT, string, Unit> readLines =>\n        Console<Eff<RT>, RT>.readLines;\n\n    /// <summary>\n    /// Write an empty line to the console\n    /// </summary>\n    public static Eff<RT, Unit> writeEmptyLine =>\n        Console<Eff<RT>, RT>.writeEmptyLine.As();\n\n    /// <summary>\n    /// Write a line to the console (returning unit)\n    /// </summary>\n    public static Eff<RT, Unit> writeLine(string line) =>\n        Console<Eff<RT>, RT>.writeLine(line).As();\n\n    /// <summary>\n    /// Write a line to the console (returning the original line)\n    /// </summary>\n    public static Eff<RT, string> writeLine2(string line) =>\n        Console<Eff<RT>, RT>.writeLine2(line).As();\n\n    /// <summary>\n    /// Write a string to the console\n    /// </summary>\n    public static Eff<RT, Unit> write(string line) =>\n        Console<Eff<RT>, RT>.write(line).As();\n\n    /// <summary>\n    /// Write a string to the console\n    /// </summary>\n    public static Eff<RT, Unit> write(char line) =>\n        Console<Eff<RT>, RT>.write(line).As();\n\n    public static Eff<RT, Unit> setBgColour(ConsoleColor colour) =>\n        Console<Eff<RT>, RT>.setBgColour(colour).As();\n\n    public static Eff<RT, Unit> setColour(ConsoleColor colour) =>\n        Console<Eff<RT>, RT>.setColour(colour).As();\n\n    public static Eff<RT, Unit> resetColour =>\n        Console<Eff<RT>, RT>.resetColour().As();\n\n    public static Eff<RT, ConsoleColor> bgColour =>\n        Console<Eff<RT>, RT>.bgColour.As();\n\n    public static Eff<RT, ConsoleColor> color =>\n        Console<Eff<RT>, RT>.colour.As();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Console.cs",
    "content": "﻿using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\nusing LanguageExt.Pipes;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys;\n\n/// <summary>\n/// Time IO \n/// </summary>\npublic static class Console<M, RT>\n    where M : \n        MonadIO<M>, \n        Fallible<Error, M>\n    where RT : \n        Has<M, ConsoleIO>\n{\n    static K<M, ConsoleIO> consoleIO =>\n        Has<M, RT, ConsoleIO>.ask;\n\n    /// <summary>\n    /// Read a key from the console\n    /// </summary>\n    public static K<M, ConsoleKeyInfo> readKey =>\n        from t in consoleIO\n        from k in t.ReadKey()\n        from r in k.Match(Some: M.Pure,\n                          None: M.Fail<ConsoleKeyInfo>(Errors.EndOfStream))\n        select r;                                         \n\n    /// <summary>\n    /// Read keys from the console and push them downstream \n    /// </summary>\n    public static ProducerT<ConsoleKeyInfo, M, Unit> readKeys =>\n        from ln in readKey\n        from __ in ProducerT.yield<M, ConsoleKeyInfo>(ln)\n        select unit;\n\n    /// <summary>\n    /// Clear the console\n    /// </summary>\n    public static K<M, Unit> clear =>\n        consoleIO.Bind(e => e.Clear());\n\n    /// <summary>\n    /// Read from the console\n    /// </summary>\n    public static K<M, int> read =>\n        from t in consoleIO\n        from k in t.Read()\n        from r in k.Match(Some: M.Pure,\n                          None: M.Fail<int>(Errors.EndOfStream))\n        select r;                                         \n\n    /// <summary>\n    /// Read chars from the console and push them downstream \n    /// </summary>\n    public static ProducerT<int, M, Unit> reads =>\n        from ln in read\n        from __ in ProducerT.yield<M, int>(ln)\n        select unit;\n\n    /// <summary>\n    /// Read from the console\n    /// </summary>\n    public static K<M, string> readLine =>\n        from t in consoleIO\n        from k in t.ReadLine()\n        from r in k.Match(Some: M.Pure,\n                          None: M.Fail<string>(Errors.EndOfStream))\n        select r;                                         \n\n    /// <summary>\n    /// Read lines from the console and push them downstream \n    /// </summary>\n    public static ProducerT<string, M, Unit> readLines =>\n        from ln in readLine\n        from _  in ProducerT.yield<M, string>(ln)\n        select unit;\n\n    /// <summary>\n    /// Write an empty line to the console\n    /// </summary>\n    public static K<M, Unit> writeEmptyLine =>\n        consoleIO.Bind(e => e.WriteLine());\n\n    /// <summary>\n    /// Write a line to the console (returning unit)\n    /// </summary>\n    public static K<M, Unit> writeLine(string line) =>\n        consoleIO.Bind(e => e.WriteLine(line));\n\n    /// <summary>\n    /// Write a line to the console (returning the original line)\n    /// </summary>\n    public static K<M, string> writeLine2(string line) =>\n        consoleIO.Bind(e => e.WriteLine(line)).Map(_ => line);\n\n    /// <summary>\n    /// Write a string to the console\n    /// </summary>\n    public static K<M, Unit> write(string line) =>\n        consoleIO.Bind(e => e.Write(line));\n\n    /// <summary>\n    /// Write a string to the console\n    /// </summary>\n    public static K<M, Unit> write(char line) =>\n        consoleIO.Bind(e => e.Write(line.ToString()));\n\n    public static K<M, Unit> setBgColour(ConsoleColor col) =>\n        consoleIO.Bind(e => e.SetBgColor(col));\n\n    public static K<M, Unit> setColour(ConsoleColor col) =>\n        consoleIO.Bind(e => e.SetColor(col));\n\n    public static K<M, Unit> resetColour() =>\n        consoleIO.Bind(e => e.ResetColor());\n\n    public static K<M, ConsoleColor> bgColour =>\n        consoleIO.Bind(e => e.BgColor);\n\n    public static K<M, ConsoleColor> colour =>\n        consoleIO.Bind(e => e.Color);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Diag/Activity.Eff.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Diag;\n\n/// <summary>\n/// An `Activity` has an operation name, an ID, a start time and duration, tags, and baggage.\n/// \n/// Activities should be created by calling the `span` functions, configured as necessary.  Each `span` function\n/// takes an `Eff` or `Aff` operation to run (which is the activity).  The runtime system will maintain the parent/\n/// child relationships for the activities, and maintains the 'current' activity.\n/// </summary>\n/// <typeparam name=\"RT\">Runtime</typeparam>\npublic class Activity<RT>\n    where RT :\n        Has<Eff<RT>, ActivitySourceIO>,\n        Local<Eff<RT>, ActivityEnv>\n{\n    static Eff<RT, ActivityEnv> env =>\n        Has<Eff<RT>, RT, ActivityEnv>.ask.As();\n\n    static Eff<RT, Activity?> currentActivity =>\n        env.Map(e => e.Activity);\n\n    public static Eff<RT, Activity> startActivity(\n        string name,\n        ActivityKind activityKind,\n        HashMap<string, object> activityTags,\n        Seq<ActivityLink> activityLinks,\n        DateTimeOffset startTime,\n        ActivityContext? parentContext = default) =>\n        Activity<Eff<RT>, RT>.startActivity(\n            name, \n            activityKind, \n            activityTags, \n            activityLinks, \n            startTime, \n            parentContext).As();\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static Eff<RT, A> span<A>(string name, K<Eff<RT>, A> operation) =>\n        Activity<Eff<RT>, RT>.span(name, operation).As();\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"activityKind\">The activity kind.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static Eff<RT, A> span<A>(\n        string name,\n        ActivityKind activityKind,\n        K<Eff<RT>, A> operation) =>\n        Activity<Eff<RT>, RT>.span(name, activityKind, operation).As();\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"activityKind\">The activity kind.</param>\n    /// <param name=\"activityTags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static Eff<RT, A> span<A>(\n        string name,\n        ActivityKind activityKind,\n        HashMap<string, object> activityTags,\n        K<Eff<RT>, A> operation) =>\n        Activity<Eff<RT>, RT>.span(name, activityKind, activityTags, operation).As();\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"activityKind\">The activity kind.</param>\n    /// <param name=\"activityTags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"activityLinks\">The optional `ActivityLink` list to initialise the created activity object with.</param>\n    /// <param name=\"startTime\">The optional start timestamp to set on the created activity object.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static Eff<RT, TA> span<TA>(\n        string name,\n        ActivityKind activityKind,\n        HashMap<string, object> activityTags,\n        Seq<ActivityLink> activityLinks,\n        DateTimeOffset startTime,\n        K<Eff<RT>, TA> operation) =>\n        Activity<Eff<RT>, RT>.span(name, activityKind, activityTags, activityLinks, startTime, operation).As();\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"activityKind\">The activity kind.</param>\n    /// <param name=\"parentContext\">The parent `ActivityContext` object to initialize the created activity object\n    /// with</param>\n    /// <param name=\"activityTags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"activityLinks\">The optional `ActivityLink` list to initialise the created activity object with.</param>\n    /// <param name=\"startTime\">The optional start timestamp to set on the created activity object.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static Eff<RT, A> span<A>(\n        string name,\n        ActivityKind activityKind,\n        ActivityContext parentContext,\n        HashMap<string, object> activityTags,\n        Seq<ActivityLink> activityLinks,\n        DateTimeOffset startTime,\n        K<Eff<RT>, A> operation) =>\n        Activity<Eff<RT>, RT>.span(\n            name, \n            activityKind, \n            parentContext, \n            activityTags, \n            activityLinks, \n            startTime, \n            operation).As();\n\n    /// <summary>\n    /// Set the state trace string\n    /// </summary>\n    /// <param name=\"traceStateString\">Trace state string</param>\n    /// <returns>Unit effect</returns>\n    public static Eff<RT, Unit> setTraceState(string traceStateString) =>\n        Activity<Eff<RT>, RT>.setTraceState(traceStateString).As();\n\n    /// <summary>\n    /// Read the trace-state string of the current activity\n    /// </summary>\n    public static Eff<RT, Option<string>> traceState =>\n        Activity<Eff<RT>, RT>.traceState.As();\n\n    /// <summary>\n    /// Read the trace ID of the current activity\n    /// </summary>\n    public static Eff<RT, Option<ActivityTraceId>> traceId =>\n        Activity<Eff<RT>, RT>.traceId.As();\n\n    /// <summary>\n    /// Add baggage to the current activity\n    /// </summary>\n    /// <param name=\"key\">Baggage key</param>\n    /// <param name=\"value\">Baggage value</param>\n    /// <returns>Unit effect</returns>\n    public static Eff<RT, Unit> addBaggage(string key, string? value) =>\n        Activity<Eff<RT>, RT>.addBaggage(key, value).As();\n\n    /// <summary>\n    /// Read the baggage of the current activity\n    /// </summary>\n    public static Eff<RT, HashMap<string, string?>> baggage =>\n        Activity<Eff<RT>, RT>.baggage.As();\n\n    /// <summary>\n    /// Add tag to the current activity\n    /// </summary>\n    /// <param name=\"name\">Tag name</param>\n    /// <param name=\"value\">Tag value</param>\n    /// <returns>Unit effect</returns>\n    public static Eff<RT, Unit> addTag(string name, string? value) =>\n        Activity<Eff<RT>, RT>.addTag(name, value).As();\n\n    /// <summary>\n    /// Add tag to the current activity\n    /// </summary>\n    /// <param name=\"name\">Tag name</param>\n    /// <param name=\"value\">Tag value</param>\n    public static Eff<RT, Unit> addTag(string name, object? value) =>\n        Activity<Eff<RT>, RT>.addTag(name, value).As();\n\n    /// <summary>\n    /// Read the tags of the current activity\n    /// </summary>\n    public static Eff<RT, HashMap<string, string?>> tags =>\n        Activity<Eff<RT>, RT>.tags.As();\n\n    /// <summary>\n    /// Read the tags of the current activity\n    /// </summary>\n    public static Eff<RT, HashMap<string, object?>> tagObjects =>\n        Activity<Eff<RT>, RT>.tagObjects.As();\n\n    /// <summary>\n    /// Read the context of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<ActivityContext>> context =>\n        Activity<Eff<RT>, RT>.context.As();\n\n    /// <summary>\n    /// Read the duration of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<TimeSpan>> duration =>\n        Activity<Eff<RT>, RT>.duration.As();\n\n    /// <summary>\n    /// Add an event to the current activity\n    /// </summary>\n    /// <param name=\"event\">Event</param>\n    public static Eff<RT, Unit> addEvent(ActivityEvent @event) =>\n        Activity<Eff<RT>, RT>.addEvent(@event).As();\n\n    /// <summary>\n    /// Read the events of the current activity\n    /// </summary>\n    public static Eff<RT, Seq<ActivityEvent>> events =>\n        Activity<Eff<RT>, RT>.events.As();\n\n    /// <summary>\n    /// Read the ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<string>> id =>\n        Activity<Eff<RT>, RT>.id.As();\n\n    /// <summary>\n    /// Read the kind of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<ActivityKind>> kind =>\n        Activity<Eff<RT>, RT>.kind.As();\n\n    /// <summary>\n    /// Read the links of the current activity\n    /// </summary>\n    public static Eff<RT, Seq<ActivityLink>> links =>\n        Activity<Eff<RT>, RT>.links.As();\n\n    /// <summary>\n    /// Read the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<Activity>> current =>\n        Activity<Eff<RT>, RT>.current.As();\n\n    /// <summary>\n    /// Read the parent ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<string>> parentId =>\n        Activity<Eff<RT>, RT>.parentId.As();\n\n    /// <summary>\n    /// Read the parent span ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<ActivitySpanId>> parentSpanId =>\n        Activity<Eff<RT>, RT>.parentSpanId.As();\n\n    /// <summary>\n    /// Read the recorded flag of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<bool>> recorded =>\n        Activity<Eff<RT>, RT>.recorded.As();\n\n    /// <summary>\n    /// Read the display-name of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<string>> displayName =>\n        Activity<Eff<RT>, RT>.displayName.As();\n\n    /// <summary>\n    /// Read the operation-name of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<string>> operationName =>\n        Activity<Eff<RT>, RT>.operationName.As();\n\n    /// <summary>\n    /// Read the root ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<string>> rootId =>\n        Activity<Eff<RT>, RT>.rootId.As();\n\n    /// <summary>\n    /// Read the span ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<ActivitySpanId>> spanId =>\n        Activity<Eff<RT>, RT>.spanId.As();\n\n    /// <summary>\n    /// Read the start-time of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static Eff<RT, Option<DateTime>> startTimeUTC =>\n        Activity<Eff<RT>, RT>.startTimeUTC.As();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Diag/Activity.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Diag;\n\n/// <summary>\n/// An `Activity` has an operation name, an ID, a start time and duration, tags, and baggage.\n/// \n/// Activities should be created by calling the `span` functions, configured as necessary.  Each `span` function\n/// takes an `Eff` or `Aff` operation to run (which is the activity).  The runtime system will maintain the parent/\n/// child relationships for the activities, and maintains the 'current' activity.\n/// </summary>\n/// <typeparam name=\"M\">Monad trait</typeparam>\n/// <typeparam name=\"RT\">Runtime</typeparam>\npublic class Activity<M, RT>\n    where M : \n        MonadIO<M>\n    where RT :\n        Has<M, ActivitySourceIO>,\n        Local<M, ActivityEnv>\n{\n    static K<M, ActivitySourceIO> activityIO =>\n        Has<M, RT, ActivitySourceIO>.ask;\n\n    static K<M, ActivityEnv> env =>\n        Has<M, RT, ActivityEnv>.ask;\n\n    public static K<M, Activity?> currentActivity =>\n        env.Map(e => e.Activity);\n\n    public static K<M, Activity> startActivity(\n        string name,\n        ActivityKind activityKind,\n        HashMap<string, object> activityTags,\n        Seq<ActivityLink> activityLinks,\n        DateTimeOffset startTime,\n        ActivityContext? parentContext = null) =>\n        from src in activityIO\n        from cur in currentActivity\n        from act in use(src.StartActivity(\n                            name,\n                            activityKind,\n                            cur is null\n                                ? default\n                                : parentContext ?? cur.Context,\n                            activityTags,\n                            activityLinks,\n                            startTime).Map(a => a ?? throw new NullReferenceException(\"Activity is null\")))\n        select act;\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static K<M, A> span<A>(string name, K<M, A> operation) =>\n        span(name, ActivityKind.Internal, default, default, DateTimeOffset.Now, operation);\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"activityKind\">The activity kind.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static K<M, A> span<A>(\n        string name,\n        ActivityKind activityKind,\n        K<M, A> operation) =>\n        span(name, activityKind, default, default, DateTimeOffset.Now, operation);\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"activityKind\">The activity kind.</param>\n    /// <param name=\"activityTags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static K<M, A> span<A>(\n        string name,\n        ActivityKind activityKind,\n        HashMap<string, object> activityTags,\n        K<M, A> operation) =>\n        span(name, activityKind, activityTags, default, DateTimeOffset.Now, operation);\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"activityKind\">The activity kind.</param>\n    /// <param name=\"activityTags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"activityLinks\">The optional `ActivityLink` list to initialise the created activity object with.</param>\n    /// <param name=\"startTime\">The optional start timestamp to set on the created activity object.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static K<M, TA> span<TA>(\n        string name,\n        ActivityKind activityKind,\n        HashMap<string, object> activityTags,\n        Seq<ActivityLink> activityLinks,\n        DateTimeOffset startTime,\n        K<M, TA> operation) =>\n        from a in startActivity(name, activityKind, activityTags, activityLinks, startTime)\n        from r in Local.with<M, RT, ActivityEnv, TA>(e => e with { Activity = a }, operation)\n        select r;\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"activityKind\">The activity kind.</param>\n    /// <param name=\"parentContext\">The parent `ActivityContext` object to initialize the created activity object\n    /// with</param>\n    /// <param name=\"activityTags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"activityLinks\">The optional `ActivityLink` list to initialise the created activity object with.</param>\n    /// <param name=\"startTime\">The optional start timestamp to set on the created activity object.</param>\n    /// <param name=\"operation\">The operation to whose activity will be traced</param>\n    /// <returns>The result of the `operation`</returns>\n    public static K<M, A> span<A>(\n        string name,\n        ActivityKind activityKind,\n        ActivityContext parentContext,\n        HashMap<string, object> activityTags,\n        Seq<ActivityLink> activityLinks,\n        DateTimeOffset startTime,\n        K<M, A> operation) =>\n        from a in startActivity(\n            name,\n            activityKind,\n            activityTags,\n            activityLinks,\n            startTime,\n            parentContext)\n        from r in Local.with<M, RT, ActivityEnv, A>(e => e with { Activity = a }, operation)\n        select r;\n\n    /// <summary>\n    /// Set the state trace string\n    /// </summary>\n    /// <param name=\"traceStateString\">Trace state string</param>\n    /// <returns>Unit effect</returns>\n    public static K<M, Unit> setTraceState(string traceStateString) =>\n        currentActivity.Map(\n            a =>\n            {\n                if (a is not null) a.TraceStateString = traceStateString;\n                return unit;\n            });\n\n    /// <summary>\n    /// Read the trace-state string of the current activity\n    /// </summary>\n    public static K<M, Option<string>> traceState =>\n        currentActivity.Map(a => Optional(a?.TraceStateString));\n\n    /// <summary>\n    /// Read the trace ID of the current activity\n    /// </summary>\n    public static K<M, Option<ActivityTraceId>> traceId =>\n        currentActivity.Map(a => Optional(a?.TraceId));\n\n    /// <summary>\n    /// Add baggage to the current activity\n    /// </summary>\n    /// <param name=\"key\">Baggage key</param>\n    /// <param name=\"value\">Baggage value</param>\n    /// <returns>Unit effect</returns>\n    public static K<M, Unit> addBaggage(string key, string? value) =>\n        currentActivity.Map(\n            a =>\n            {\n                a?.AddBaggage(key, value);\n                return unit;\n            });\n\n    /// <summary>\n    /// Read the baggage of the current activity\n    /// </summary>\n    public static K<M, HashMap<string, string?>> baggage =>\n        currentActivity.Map(\n            a => a is not null\n                     ? a.Baggage.AsIterable().Map(kv => (kv.Key, kv.Value)).ToHashMap()\n                     : HashMap<string, string?>());\n\n    /// <summary>\n    /// Add tag to the current activity\n    /// </summary>\n    /// <param name=\"name\">Tag name</param>\n    /// <param name=\"value\">Tag value</param>\n    /// <returns>Unit effect</returns>\n    public static K<M, Unit> addTag(string name, string? value) =>\n        currentActivity.Map(\n            a =>\n            {\n                a?.AddTag(name, value);\n                return unit;\n            });\n\n    /// <summary>\n    /// Add tag to the current activity\n    /// </summary>\n    /// <param name=\"name\">Tag name</param>\n    /// <param name=\"value\">Tag value</param>\n    public static K<M, Unit> addTag(string name, object? value) =>\n        currentActivity.Map(\n            a =>\n            {\n                a?.AddTag(name, value);\n                return unit;\n            });\n\n    /// <summary>\n    /// Read the tags of the current activity\n    /// </summary>\n    public static K<M, HashMap<string, string?>> tags =>\n        currentActivity.Map(\n            a => a is not null\n                     ? a.Tags.AsIterable().Map(kv => (kv.Key, kv.Value)).ToHashMap()\n                     : HashMap<string, string?>());\n\n    /// <summary>\n    /// Read the tags of the current activity\n    /// </summary>\n    public static K<M, HashMap<string, object?>> tagObjects =>\n        currentActivity.Map(\n            a => a is not null\n                     ? a.TagObjects.AsIterable().Map(kv => (kv.Key, kv.Value)).ToHashMap()\n                     : HashMap<string, object?>());\n\n    /// <summary>\n    /// Read the context of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<ActivityContext>> context =>\n        currentActivity.Map(a => Optional(a?.Context));\n\n    /// <summary>\n    /// Read the duration of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<TimeSpan>> duration =>\n        currentActivity.Map(a => Optional(a?.Duration));\n\n    /// <summary>\n    /// Add an event to the current activity\n    /// </summary>\n    /// <param name=\"event\">Event</param>\n    public static K<M, Unit> addEvent(ActivityEvent @event) =>\n        currentActivity.Map(\n            a =>\n            {\n                a?.AddEvent(@event);\n                return unit;\n            });\n\n    /// <summary>\n    /// Read the events of the current activity\n    /// </summary>\n    public static K<M, Seq<ActivityEvent>> events =>\n        currentActivity.Map(\n            a => a is not null\n                     ? a.Events.AsIterable().ToSeq()\n                     : Seq<ActivityEvent>());\n\n    /// <summary>\n    /// Read the ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<string>> id =>\n        currentActivity.Map(a => Optional(a?.Id));\n\n    /// <summary>\n    /// Read the kind of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<ActivityKind>> kind =>\n        currentActivity.Map(a => Optional(a?.Kind));\n\n    /// <summary>\n    /// Read the links of the current activity\n    /// </summary>\n    public static K<M, Seq<ActivityLink>> links =>\n        currentActivity.Map(\n            a => a is not null\n                     ? a.Links.AsIterable().ToSeq()\n                     : Seq<ActivityLink>());\n\n    /// <summary>\n    /// Read the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<Activity>> current =>\n        currentActivity.Map(a => Optional(a));\n\n    /// <summary>\n    /// Read the parent ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<string>> parentId =>\n        currentActivity.Map(a => Optional(a?.ParentId));\n\n    /// <summary>\n    /// Read the parent span ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<ActivitySpanId>> parentSpanId =>\n        currentActivity.Map(a => Optional(a?.ParentSpanId));\n\n    /// <summary>\n    /// Read the recorded flag of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<bool>> recorded =>\n        currentActivity.Map(a => Optional(a?.Recorded));\n\n    /// <summary>\n    /// Read the display-name of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<string>> displayName =>\n        currentActivity.Map(a => Optional(a?.DisplayName));\n\n    /// <summary>\n    /// Read the operation-name of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<string>> operationName =>\n        currentActivity.Map(a => Optional(a?.OperationName));\n\n    /// <summary>\n    /// Read the root ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<string>> rootId =>\n        currentActivity.Map(a => Optional(a?.RootId));\n\n    /// <summary>\n    /// Read the span ID of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<ActivitySpanId>> spanId =>\n        currentActivity.Map(a => Optional(a?.SpanId));\n\n    /// <summary>\n    /// Read the start-time of the current activity\n    /// </summary>\n    /// <remarks>None if there is no current activity</remarks>\n    public static K<M, Option<DateTime>> startTimeUTC =>\n        currentActivity.Map(a => Optional(a?.StartTimeUtc));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Encoding.Eff.cs",
    "content": "using LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys;\n\npublic static class Enc<RT>\n    where RT : \n        Has<Eff<RT>, EncodingIO>\n{\n    /// <summary>\n    /// Encoding\n    /// </summary>\n    public static Eff<RT, System.Text.Encoding> encoding =>\n        Enc<Eff<RT>, RT>.encoding.As();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Encoding.cs",
    "content": "using LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys;\n\npublic static class Enc<M, RT>\n    where M : \n        MonadIO<M>\n    where RT : \n        Has<M, EncodingIO>\n{\n    static readonly K<M, EncodingIO> encIO =\n        Has<M, RT, EncodingIO>.ask;\n\n    /// <summary>\n    /// Encoding\n    /// </summary>\n    public static K<M, System.Text.Encoding> encoding =>\n        encIO.Bind(e => e.Encoding);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Environment.Eff.cs",
    "content": "using System;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys;\n\n/// <summary>\n/// Environment IO\n/// </summary>\npublic static class Environment<RT>\n    where RT : \n        Has<Eff<RT>, EnvironmentIO>\n{\n    /// <summary>\n    /// Gets the command line for this process.\n    /// </summary>\n    public static Eff<RT, string> commandLine =>\n        Environment<Eff<RT>, RT>.commandLine.As();\n\n    /// <summary>\n    /// Gets a unique identifier for the current managed thread.\n    /// </summary>\n    public static Eff<RT, int> currentManagedThreadId =>\n        Environment<Eff<RT>, RT>.currentManagedThreadId.As();\n\n    /// <summary>\n    /// Terminates this process and returns an exit code to the operating system.\n    /// </summary>\n    public static Eff<RT, Unit> exit(int exitCode) =>\n        Environment<Eff<RT>, RT>.exit(exitCode).As();\n\n    /// <summary>\n    /// Gets the exit code of the process.\n    /// </summary>\n    public static Eff<RT, int> exitCode =>\n        Environment<Eff<RT>, RT>.exitCode.As();\n\n    /// <summary>\n    /// Sets the exit code of the process.\n    /// </summary>\n    /// <param name=\"exitCode\">exit code of the process</param>\n    public static Eff<RT, Unit> setExitCode(int exitCode) =>\n        Environment<Eff<RT>, RT>.setExitCode(exitCode).As();\n\n    /// <summary>\n    /// Replaces the name of each environment variable embedded in the specified string with the string equivalent of the value of the variable, then returns the resulting string.\n    /// </summary>\n    /// <param name=\"name\">A string containing the names of zero or more environment variables. Each environment variable is quoted with the percent sign character (%).</param>\n    public static Eff<RT, string> expandEnvironmentVariables(string name) =>\n        Environment<Eff<RT>, RT>.expandEnvironmentVariables(name).As();\n\n    /// <summary>\n    /// Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message in error reporting to Microsoft.\n    /// </summary>\n    /// <param name=\"message\">A message that explains why the process was terminated, or null if no explanation is provided.</param>\n    public static Eff<RT, Unit> failFast(Option<string> message) =>\n        Environment<Eff<RT>, RT>.failFast(message).As();\n\n    /// <summary>\n    /// Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message and exception information in error reporting to Microsoft.\n    /// </summary>\n    /// <param name=\"message\">A message that explains why the process was terminated, or null if no explanation is provided.</param>\n    /// <param name=\"exception\">An exception that represents the error that caused the termination. This is typically the exception in a catch block.</param>\n    public static Eff<RT, Unit> failFast(Option<string> message, Option<Exception> exception) =>\n        Environment<Eff<RT>, RT>.failFast(message, exception).As();\n\n    /// <summary>\n    /// Returns a string array containing the command-line arguments for the current process.\n    /// </summary>\n    public static Eff<RT, Seq<string>> commandLineArgs =>\n        Environment<Eff<RT>, RT>.commandLineArgs.As();\n\n    /// <summary>\n    /// Retrieves the value of an environment variable from the current process.\n    /// </summary>\n    /// <param name=\"variable\">The name of an environment variable.</param>\n    public static Eff<RT, Option<string>> getEnvironmentVariable(string variable) =>\n        Environment<Eff<RT>, RT>.getEnvironmentVariable(variable).As();\n\n    /// <summary>\n    /// Retrieves the value of an environment variable from the current process or from the Windows operating system registry key for the current user or local machine.\n    /// </summary>\n    /// <param name=\"variable\">The name of an environment variable.</param>\n    /// <param name=\"target\">Target</param>\n    public static Eff<RT, Option<string>> getEnvironmentVariable(string variable, EnvironmentVariableTarget target) =>\n        Environment<Eff<RT>, RT>.getEnvironmentVariable(variable, target).As();\n\n    /// <summary>\n    /// Retrieves all environment variable names and their values from the current process.\n    /// </summary>\n    public static Eff<RT, HashMap<string, Option<string>>> environmentVariables =>\n        Environment<Eff<RT>, RT>.environmentVariables.As();\n\n    /// <summary>\n    /// Retrieves all environment variable names and their values from the current process, or from the Windows operating system registry key for the current user or local machine.\n    /// </summary>\n    /// <param name=\"target\">One of the System.EnvironmentVariableTarget values. Only System.EnvironmentVariableTarget.Process is supported on .NET Core running on Unix-based systems.</param>\n    public static Eff<RT, HashMap<string, Option<string>>> getEnvironmentVariables(EnvironmentVariableTarget target) =>\n        Environment<Eff<RT>, RT>.getEnvironmentVariables(target).As();\n\n    /// <summary>\n    /// Gets the path to the system special folder that is identified by the specified enumeration.\n    /// </summary>\n    /// <param name=\"folder\">One of enumeration values that identifies a system special folder.</param>\n    public static Eff<RT, string> getFolderPath(Environment.SpecialFolder folder) =>\n        Environment<Eff<RT>, RT>.getFolderPath(folder).As();\n\n    /// <summary>\n    /// Gets the path to the system special folder that is identified by the specified enumeration, and uses a specified option for accessing special folders.\n    /// </summary>\n    /// <param name=\"folder\">One of the enumeration values that identifies a system special folder.</param>\n    /// <param name=\"option\">One of the enumeration values that specifies options to use for accessing a special folder.</param>\n    public static Eff<RT, string> getFolderPath(Environment.SpecialFolder folder, Environment.SpecialFolderOption option) =>\n        Environment<Eff<RT>, RT>.getFolderPath(folder, option).As();\n\n    /// <summary>\n    /// Returns an array of string containing the names of the logical drives on the current computer.\n    /// </summary>\n    public static Eff<RT, Seq<string>> logicalDrives =>\n        Environment<Eff<RT>, RT>.logicalDrives.As();\n\n    /// <summary>\n    /// Gets a value that indicates whether the current application domain is being unloaded or the common language runtime (CLR) is shutting down.\n    /// </summary>\n    public static Eff<RT, bool> hasShutdownStarted =>\n        Environment<Eff<RT>, RT>.hasShutdownStarted.As();\n\n    /// <summary>\n    /// Determines whether the current operating system is a 64-bit operating system.\n    /// </summary>\n    public static Eff<RT, bool> is64BitOperatingSystem =>\n        Environment<Eff<RT>, RT>.is64BitOperatingSystem.As();\n\n    /// <summary>\n    /// Determines whether the current process is a 64-bit process.\n    /// </summary>\n    public static Eff<RT, bool> is64BitProcess =>\n        Environment<Eff<RT>, RT>.is64BitProcess.As();\n\n    /// <summary>\n    /// Gets the NetBIOS name of this local computer.\n    /// </summary>\n    public static Eff<RT, string> machineName =>\n        Environment<Eff<RT>, RT>.machineName.As();\n\n    /// <summary>\n    /// Gets the newline string defined for this environment.\n    /// </summary>\n    public static Eff<RT, string> newLine =>\n        Environment<Eff<RT>, RT>.newLine.As();\n\n    /// <summary>\n    /// Gets an OperatingSystem object that contains the current platform identifier and version number.\n    /// </summary>\n    public static Eff<RT, OperatingSystem> osVersion =>\n        Environment<Eff<RT>, RT>.osVersion.As();\n\n    /// <summary>\n    /// Gets the number of processors on the current machine.\n    /// </summary>\n    public static Eff<RT, int> processorCount =>\n        Environment<Eff<RT>, RT>.processorCount.As();\n\n    /// <summary>\n    /// Creates, modifies, or deletes an environment variable stored in the current process.\n    /// </summary>\n    /// <param name=\"variable\">The name of an environment variable.</param>\n    /// <param name=\"value\">A value to assign to variable .</param>\n    public static Eff<RT, Unit> setEnvironmentVariable(string variable, Option<string> value) =>\n        Environment<Eff<RT>, RT>.setEnvironmentVariable(variable, value).As();\n\n    /// <summary>\n    /// Creates, modifies, or deletes an environment variable stored in the current process or in the Windows operating system registry key reserved for the current user or local machine.\n    /// </summary>\n    /// <param name=\"variable\">The name of an environment variable.</param>\n    /// <param name=\"value\">A value to assign to variable.</param>\n    /// <param name=\"target\">One of the enumeration values that specifies the location of the environment variable.</param>\n    public static Eff<RT, Unit> setEnvironmentVariable(string variable, Option<string> value, EnvironmentVariableTarget target) =>\n        Environment<Eff<RT>, RT>.setEnvironmentVariable(variable, value, target).As();\n\n    /// <summary>\n    /// Gets current stack trace information.\n    /// </summary>\n    public static Eff<RT, string> stackTrace =>\n        Environment<Eff<RT>, RT>.stackTrace.As();\n\n    /// <summary>\n    /// Gets the fully qualified path of the system directory.\n    /// </summary>\n    public static Eff<RT, string> systemDirectory =>\n        Environment<Eff<RT>, RT>.systemDirectory.As();\n\n    /// <summary>\n    /// Gets the number of bytes in the operating system's memory page.\n    /// </summary>\n    public static Eff<RT, int> systemPageSize =>\n        Environment<Eff<RT>, RT>.systemPageSize.As();\n\n    /// <summary>\n    /// Gets the number of milliseconds elapsed since the system started.\n    /// </summary>\n    public static Eff<RT, long> tickCount =>\n        Environment<Eff<RT>, RT>.tickCount.As();\n\n    /// <summary>\n    /// Gets the network domain name associated with the current user.\n    /// </summary>\n    public static Eff<RT, string> userDomainName =>\n        Environment<Eff<RT>, RT>.userDomainName.As();\n\n    /// <summary>\n    /// Gets a value indicating whether the current process is running in user interactive mode.\n    /// </summary>\n    public static Eff<RT, bool> userInteractive =>\n        Environment<Eff<RT>, RT>.userInteractive.As();\n\n    /// <summary>\n    /// Gets the user name of the person who is currently logged on to the operating system.\n    /// </summary>\n    public static Eff<RT, string> userName =>\n        Environment<Eff<RT>, RT>.userName.As();\n\n    /// <summary>\n    /// Gets a Version object that describes the major, minor, build, and revision numbers of the common language runtime.\n    /// </summary>\n    public static Eff<RT, Version> version =>\n        Environment<Eff<RT>, RT>.version.As();\n\n    /// <summary>\n    /// Gets the amount of physical memory mapped to the process context.\n    /// </summary>\n    public static Eff<RT, long> workingSet =>\n        Environment<Eff<RT>, RT>.workingSet.As();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Environment.cs",
    "content": "using System;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys;\n\n/// <summary>\n/// Environment IO\n/// </summary>\npublic static class Environment<M, RT>\n    where M : \n        MonadIO<M>\n    where RT : \n        Has<M, EnvironmentIO>\n{\n    static readonly K<M, EnvironmentIO> envIO =\n        Has<M, RT, EnvironmentIO>.ask;\n    \n    /// <summary>\n    /// Gets the command line for this process.\n    /// </summary>\n    public static K<M, string> commandLine =>\n        envIO.Bind(e => e.CommandLine());\n\n    /// <summary>\n    /// Gets a unique identifier for the current managed thread.\n    /// </summary>\n    public static K<M, int> currentManagedThreadId =>\n        envIO.Bind(e => e.CurrentManagedThreadId());\n\n    /// <summary>\n    /// Terminates this process and returns an exit code to the operating system.\n    /// </summary>\n    public static K<M, Unit> exit(int exitCode) =>\n        envIO.Bind(e => e.Exit(exitCode));\n\n    /// <summary>\n    /// Gets the exit code of the process.\n    /// </summary>\n    public static K<M, int> exitCode =>\n        envIO.Bind(e => e.ExitCode());\n\n    /// <summary>\n    /// Sets the exit code of the process.\n    /// </summary>\n    /// <param name=\"exitCode\">exit code of the process</param>\n    public static K<M, Unit> setExitCode(int exitCode) =>\n        envIO.Bind(e => e.SetExitCode(exitCode));\n\n    /// <summary>\n    /// Replaces the name of each environment variable embedded in the specified string with the string equivalent of the value of the variable, then returns the resulting string.\n    /// </summary>\n    /// <param name=\"name\">A string containing the names of zero or more environment variables. Each environment variable is quoted with the percent sign character (%).</param>\n    public static K<M, string> expandEnvironmentVariables(string name) =>\n        envIO.Bind(e => e.ExpandEnvironmentVariables(name));\n\n    /// <summary>\n    /// Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message in error reporting to Microsoft.\n    /// </summary>\n    /// <param name=\"message\">A message that explains why the process was terminated, or null if no explanation is provided.</param>\n    public static K<M, Unit> failFast(Option<string> message) =>\n        envIO.Bind(e => e.FailFast(message));\n\n    /// <summary>\n    /// Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message and exception information in error reporting to Microsoft.\n    /// </summary>\n    /// <param name=\"message\">A message that explains why the process was terminated, or null if no explanation is provided.</param>\n    /// <param name=\"exception\">An exception that represents the error that caused the termination. This is typically the exception in a catch block.</param>\n    public static K<M, Unit> failFast(Option<string> message, Option<Exception> exception) =>\n        envIO.Bind(e => e.FailFast(message, exception));\n\n    /// <summary>\n    /// Returns a string array containing the command-line arguments for the current process.\n    /// </summary>\n    public static K<M, Seq<string>> commandLineArgs =>\n        envIO.Bind(e => e.GetCommandLineArgs());\n\n    /// <summary>\n    /// Retrieves the value of an environment variable from the current process.\n    /// </summary>\n    /// <param name=\"variable\">The name of an environment variable.</param>\n    public static K<M, Option<string>> getEnvironmentVariable(string variable) =>\n        envIO.Bind(e => e.GetEnvironmentVariable(variable));\n\n    /// <summary>\n    /// Retrieves the value of an environment variable from the current process or from the Windows operating system registry key for the current user or local machine.\n    /// </summary>\n    /// <param name=\"variable\">The name of an environment variable.</param>\n    /// <param name=\"target\">Target</param>\n    public static K<M, Option<string>> getEnvironmentVariable(string variable, EnvironmentVariableTarget target) =>\n        envIO.Bind(e => e.GetEnvironmentVariable(variable, target));\n\n    /// <summary>\n    /// Retrieves all environment variable names and their values from the current process.\n    /// </summary>\n    public static K<M, HashMap<string, Option<string>>> environmentVariables =>\n        envIO.Bind(e => e.GetEnvironmentVariables());\n\n    /// <summary>\n    /// Retrieves all environment variable names and their values from the current process, or from the Windows operating system registry key for the current user or local machine.\n    /// </summary>\n    /// <param name=\"target\">One of the System.EnvironmentVariableTarget values. Only System.EnvironmentVariableTarget.Process is supported on .NET Core running on Unix-based systems.</param>\n    public static K<M, HashMap<string, Option<string>>> getEnvironmentVariables(EnvironmentVariableTarget target) =>\n        envIO.Bind(e => e.GetEnvironmentVariables(target));\n\n    /// <summary>\n    /// Gets the path to the system special folder that is identified by the specified enumeration.\n    /// </summary>\n    /// <param name=\"folder\">One of enumeration values that identifies a system special folder.</param>\n    public static K<M, string> getFolderPath(Environment.SpecialFolder folder) =>\n        envIO.Bind(e => e.GetFolderPath(folder));\n\n    /// <summary>\n    /// Gets the path to the system special folder that is identified by the specified enumeration, and uses a specified option for accessing special folders.\n    /// </summary>\n    /// <param name=\"folder\">One of the enumeration values that identifies a system special folder.</param>\n    /// <param name=\"option\">One of the enumeration values that specifies options to use for accessing a special folder.</param>\n    public static K<M, string> getFolderPath(Environment.SpecialFolder folder, Environment.SpecialFolderOption option) =>\n        envIO.Bind(e => e.GetFolderPath(folder, option));\n\n    /// <summary>\n    /// Returns an array of string containing the names of the logical drives on the current computer.\n    /// </summary>\n    public static K<M, Seq<string>> logicalDrives =>\n        envIO.Bind(e => e.GetLogicalDrives());\n\n    /// <summary>\n    /// Gets a value that indicates whether the current application domain is being unloaded or the common language runtime (CLR) is shutting down.\n    /// </summary>\n    public static K<M, bool> hasShutdownStarted =>\n        envIO.Bind(e => e.HasShutdownStarted());\n\n    /// <summary>\n    /// Determines whether the current operating system is a 64-bit operating system.\n    /// </summary>\n    public static K<M, bool> is64BitOperatingSystem =>\n        envIO.Bind(e => e.Is64BitOperatingSystem());\n\n    /// <summary>\n    /// Determines whether the current process is a 64-bit process.\n    /// </summary>\n    public static K<M, bool> is64BitProcess =>\n        envIO.Bind(e => e.Is64BitProcess());\n\n    /// <summary>\n    /// Gets the NetBIOS name of this local computer.\n    /// </summary>\n    public static K<M, string> machineName =>\n        envIO.Bind(e => e.MachineName());\n\n    /// <summary>\n    /// Gets the newline string defined for this environment.\n    /// </summary>\n    public static K<M, string> newLine =>\n        envIO.Bind(e => e.NewLine());\n\n    /// <summary>\n    /// Gets an OperatingSystem object that contains the current platform identifier and version number.\n    /// </summary>\n    public static K<M, OperatingSystem> osVersion =>\n        envIO.Bind(e => e.OSVersion());\n\n    /// <summary>\n    /// Gets the number of processors on the current machine.\n    /// </summary>\n    public static K<M, int> processorCount =>\n        envIO.Bind(e => e.ProcessorCount());\n\n    /// <summary>\n    /// Creates, modifies, or deletes an environment variable stored in the current process.\n    /// </summary>\n    /// <param name=\"variable\">The name of an environment variable.</param>\n    /// <param name=\"value\">A value to assign to variable .</param>\n    public static K<M, Unit> setEnvironmentVariable(string variable, Option<string> value) =>\n        envIO.Bind(e => e.SetEnvironmentVariable(variable, value));\n\n    /// <summary>\n    /// Creates, modifies, or deletes an environment variable stored in the current process or in the Windows operating system registry key reserved for the current user or local machine.\n    /// </summary>\n    /// <param name=\"variable\">The name of an environment variable.</param>\n    /// <param name=\"value\">A value to assign to variable.</param>\n    /// <param name=\"target\">One of the enumeration values that specifies the location of the environment variable.</param>\n    public static K<M, Unit> setEnvironmentVariable(string variable, Option<string> value, EnvironmentVariableTarget target) =>\n        envIO.Bind(e => e.SetEnvironmentVariable(variable, value, target));\n\n    /// <summary>\n    /// Gets current stack trace information.\n    /// </summary>\n    public static K<M, string> stackTrace =>\n        envIO.Bind(e => e.StackTrace());\n\n    /// <summary>\n    /// Gets the fully qualified path of the system directory.\n    /// </summary>\n    public static K<M, string> systemDirectory =>\n        envIO.Bind(e => e.SystemDirectory());\n\n    /// <summary>\n    /// Gets the number of bytes in the operating system's memory page.\n    /// </summary>\n    public static K<M, int> systemPageSize =>\n        envIO.Bind(e => e.SystemPageSize());\n\n    /// <summary>\n    /// Gets the number of milliseconds elapsed since the system started.\n    /// </summary>\n    public static K<M, long> tickCount =>\n        envIO.Bind(e => e.TickCount());\n\n    /// <summary>\n    /// Gets the network domain name associated with the current user.\n    /// </summary>\n    public static K<M, string> userDomainName =>\n        envIO.Bind(e => e.UserDomainName());\n\n    /// <summary>\n    /// Gets a value indicating whether the current process is running in user interactive mode.\n    /// </summary>\n    public static K<M, bool> userInteractive =>\n        envIO.Bind(e => e.UserInteractive());\n\n    /// <summary>\n    /// Gets the user name of the person who is currently logged on to the operating system.\n    /// </summary>\n    public static K<M, string> userName =>\n        envIO.Bind(e => e.UserName());\n\n    /// <summary>\n    /// Gets a Version object that describes the major, minor, build, and revision numbers of the common language runtime.\n    /// </summary>\n    public static K<M, Version> version =>\n        envIO.Bind(e => e.Version());\n\n    /// <summary>\n    /// Gets the amount of physical memory mapped to the process context.\n    /// </summary>\n    public static K<M, long> workingSet =>\n        envIO.Bind(e => e.WorkingSet());\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/IO/Directory.Eff.cs",
    "content": "using System;\nusing System.IO;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys.IO;\n\npublic class Directory<RT>\n    where RT : \n        Has<Eff<RT>, DirectoryIO>\n{\n    /// <summary>\n    /// Create a directory\n    /// </summary>\n    public static Eff<RT, DirectoryInfo> create(string path) =>\n        Directory<Eff<RT>, RT>.create(path).As();\n\n    /// <summary>\n    /// Delete a directory\n    /// </summary>\n    public static Eff<RT, Unit> delete(string path, bool recursive = true) =>\n        Directory<Eff<RT>, RT>.delete(path, recursive).As();\n        \n    /// <summary>\n    /// Get parent directory\n    /// </summary>\n    public static Eff<RT, Option<DirectoryInfo>> getParent(string path) =>\n        Directory<Eff<RT>, RT>.getParent(path).As();\n\n    /// <summary>\n    /// Check if directory exists\n    /// </summary>\n    public static Eff<RT, bool> exists(string path) =>\n        Directory<Eff<RT>, RT>.exists(path).As();\n     \n    /// <summary>\n    /// Set the directory creation time\n    /// </summary>\n    public static Eff<RT, Unit> setCreationTime(string path, DateTime creationTime) =>\n        Directory<Eff<RT>, RT>.setCreationTime(path, creationTime).As();\n\n    /// <summary>\n    /// Set the directory creation time\n    /// </summary>\n    public static Eff<RT, Unit> setCreationTimeUtc(string path, DateTime creationTimeUtc) =>\n        Directory<Eff<RT>, RT>.setCreationTimeUtc(path, creationTimeUtc).As();\n\n    /// <summary>\n    /// Get the directory creation time\n    /// </summary>\n    public static Eff<RT, DateTime> getCreationTime(string path) =>\n        Directory<Eff<RT>, RT>.getCreationTime(path).As();\n\n    /// <summary>\n    /// Get the directory creation time\n    /// </summary>\n    public static Eff<RT, DateTime> getCreationTimeUtc(string path) =>\n        Directory<Eff<RT>, RT>.getCreationTimeUtc(path).As();\n\n    /// <summary>\n    /// Set the directory last write time\n    /// </summary>\n    public static Eff<RT, Unit> setLastWriteTime(string path, DateTime lastWriteTime) =>\n        Directory<Eff<RT>, RT>.setLastWriteTime(path, lastWriteTime).As();\n\n    /// <summary>\n    /// Set the directory last write time\n    /// </summary>\n    public static Eff<RT, Unit> setLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc) =>\n        Directory<Eff<RT>, RT>.setLastWriteTimeUtc(path, lastWriteTimeUtc).As();\n\n    /// <summary>\n    /// Get the directory last write time\n    /// </summary>\n    public static Eff<RT, DateTime> getLastWriteTime(string path) =>\n        Directory<Eff<RT>, RT>.getLastWriteTime(path).As();\n\n    /// <summary>\n    /// Get the directory last write time\n    /// </summary>\n    public static Eff<RT, DateTime> getLastWriteTimeUtc(string path) =>\n        Directory<Eff<RT>, RT>.getLastWriteTimeUtc(path).As();\n\n    /// <summary>\n    /// Set the directory last access time\n    /// </summary>\n    public static Eff<RT, Unit> setLastAccessTime(string path, DateTime lastAccessTime) =>\n        Directory<Eff<RT>, RT>.setLastAccessTime(path, lastAccessTime).As();\n\n    /// <summary>\n    /// Set the directory last access time\n    /// </summary>\n    public static Eff<RT, Unit> setLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc) =>\n        Directory<Eff<RT>, RT>.setLastAccessTimeUtc(path, lastAccessTimeUtc).As();\n        \n    /// <summary>\n    /// Get the directory last access time\n    /// </summary>\n    public static Eff<RT, DateTime> getLastAccessTime(string path) =>\n        Directory<Eff<RT>, RT>.getLastAccessTime(path).As();\n        \n    /// <summary>\n    /// Get the directory last access time\n    /// </summary>\n    public static Eff<RT, DateTime> getLastAccessTimeUtc(string path) =>\n        Directory<Eff<RT>, RT>.getLastAccessTimeUtc(path).As();\n\n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateDirectories(string path) =>\n        Directory<Eff<RT>, RT>.enumerateDirectories(path).As();\n        \n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateDirectories(string path, string searchPattern) =>\n        Directory<Eff<RT>, RT>.enumerateDirectories(path, searchPattern).As();\n        \n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateDirectories(string path, string searchPattern, SearchOption searchOption) =>\n        Directory<Eff<RT>, RT>.enumerateDirectories(path, searchPattern, searchOption).As();\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateFiles(string path) =>\n        Directory<Eff<RT>, RT>.enumerateFiles(path).As();\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateFiles(string path, string searchPattern) =>\n        Directory<Eff<RT>, RT>.enumerateFiles(path, searchPattern).As();\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateFiles(string path, string searchPattern, SearchOption searchOption) =>\n        Directory<Eff<RT>, RT>.enumerateFiles(path, searchPattern, searchOption).As();\n        \n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateFileSystemEntries(string path) =>\n        Directory<Eff<RT>, RT>.enumerateFileSystemEntries(path).As();\n\n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateFileSystemEntries(string path, string searchPattern) =>\n        Directory<Eff<RT>, RT>.enumerateFileSystemEntries(path, searchPattern).As();\n\n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    public static Eff<RT, Seq<string>> enumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption) =>\n        Directory<Eff<RT>, RT>.enumerateFileSystemEntries(path, searchPattern, searchOption).As();\n\n    /// <summary>\n    /// Get the root of the path provided\n    /// </summary>\n    public static Eff<RT, string> getRoot(string path) =>\n        Directory<Eff<RT>, RT>.getRoot(path).As();\n\n    /// <summary>\n    /// Get the current directory\n    /// </summary>\n    public static Eff<RT, string> current =>\n        Directory<Eff<RT>, RT>.current.As();\n\n    /// <summary>\n    /// Set the current directory\n    /// </summary>\n    /// <param name=\"path\"></param>\n    public static Eff<RT, Unit> setCurrent(string path) =>\n        Directory<Eff<RT>, RT>.setCurrent(path).As();\n\n    /// <summary>\n    /// Move a directory\n    /// </summary>\n    public static Eff<RT, Unit> move(string sourceDirName, string destDirName) =>\n        Directory<Eff<RT>, RT>.move(sourceDirName, destDirName).As();\n\n    /// <summary>\n    /// Get the logical drives\n    /// </summary>\n    public static Eff<RT, Seq<string>> logicalDrives =>\n        Directory<Eff<RT>, RT>.logicalDrives.As();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/IO/Directory.cs",
    "content": "using System;\nusing System.IO;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys.IO;\n\npublic class Directory<M, RT>\n    where M : \n        MonadIO<M>  \n    where RT : \n        Has<M, DirectoryIO>\n{\n    static K<M, DirectoryIO> directoryIO => \n        Has<M, RT, DirectoryIO>.ask;\n    \n    /// <summary>\n    /// Create a directory\n    /// </summary>\n    public static K<M, DirectoryInfo> create(string path) =>\n        directoryIO.Bind(rt => rt.Create(path));\n\n    /// <summary>\n    /// Delete a directory\n    /// </summary>\n    public static K<M, Unit> delete(string path, bool recursive = true) =>\n        directoryIO.Bind(rt => rt.Delete(path, recursive));\n        \n    /// <summary>\n    /// Get parent directory\n    /// </summary>\n    public static K<M, Option<DirectoryInfo>> getParent(string path) =>\n        directoryIO.Bind(rt => rt.GetParent(path));\n\n    /// <summary>\n    /// Check if directory exists\n    /// </summary>\n    public static K<M, bool> exists(string path) =>\n        directoryIO.Bind(rt => rt.Exists(path));\n     \n    /// <summary>\n    /// Set the directory creation time\n    /// </summary>\n    public static K<M, Unit> setCreationTime(string path, DateTime creationTime) =>\n        directoryIO.Bind(rt => rt.SetCreationTime(path, creationTime));\n\n    /// <summary>\n    /// Set the directory creation time\n    /// </summary>\n    public static K<M, Unit> setCreationTimeUtc(string path, DateTime creationTimeUtc) =>\n        directoryIO.Bind(rt => rt.SetCreationTimeUtc(path, creationTimeUtc));\n\n    /// <summary>\n    /// Get the directory creation time\n    /// </summary>\n    public static K<M, DateTime> getCreationTime(string path) =>\n        directoryIO.Bind(rt => rt.GetCreationTime(path));\n\n    /// <summary>\n    /// Get the directory creation time\n    /// </summary>\n    public static K<M, DateTime> getCreationTimeUtc(string path) =>\n        directoryIO.Bind(rt => rt.GetCreationTimeUtc(path));\n\n    /// <summary>\n    /// Set the directory last write time\n    /// </summary>\n    public static K<M, Unit> setLastWriteTime(string path, DateTime lastWriteTime) =>\n        directoryIO.Bind(rt => rt.SetLastWriteTime(path, lastWriteTime));\n\n    /// <summary>\n    /// Set the directory last write time\n    /// </summary>\n    public static K<M, Unit> setLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc) =>\n        directoryIO.Bind(rt => rt.SetLastWriteTimeUtc(path, lastWriteTimeUtc));\n\n    /// <summary>\n    /// Get the directory last write time\n    /// </summary>\n    public static K<M, DateTime> getLastWriteTime(string path) =>\n        directoryIO.Bind(rt => rt.GetLastWriteTime(path));\n\n    /// <summary>\n    /// Get the directory last write time\n    /// </summary>\n    public static K<M, DateTime> getLastWriteTimeUtc(string path) =>\n        directoryIO.Bind(rt => rt.GetLastWriteTimeUtc(path));\n\n    /// <summary>\n    /// Set the directory last access time\n    /// </summary>\n    public static K<M, Unit> setLastAccessTime(string path, DateTime lastAccessTime) =>\n        directoryIO.Bind(rt => rt.SetLastAccessTime(path, lastAccessTime));\n\n    /// <summary>\n    /// Set the directory last access time\n    /// </summary>\n    public static K<M, Unit> setLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc) =>\n        directoryIO.Bind(rt => rt.SetLastAccessTimeUtc(path, lastAccessTimeUtc));\n        \n    /// <summary>\n    /// Get the directory last access time\n    /// </summary>\n    public static K<M, DateTime> getLastAccessTime(string path) =>\n        directoryIO.Bind(rt => rt.GetLastAccessTime(path));\n        \n    /// <summary>\n    /// Get the directory last access time\n    /// </summary>\n    public static K<M, DateTime> getLastAccessTimeUtc(string path) =>\n        directoryIO.Bind(rt => rt.GetLastAccessTimeUtc(path));\n\n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    public static K<M, Seq<string>> enumerateDirectories(string path) =>\n        directoryIO.Bind(rt => rt.EnumerateDirectories(path));\n        \n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    public static K<M, Seq<string>> enumerateDirectories(string path, string searchPattern) =>\n        directoryIO.Bind(rt => rt.EnumerateDirectories(path, searchPattern));\n        \n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    public static K<M, Seq<string>> enumerateDirectories(string path, string searchPattern, SearchOption searchOption) =>\n        directoryIO.Bind(rt => rt.EnumerateDirectories(path, searchPattern, searchOption));\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    public static K<M, Seq<string>> enumerateFiles(string path) =>\n        directoryIO.Bind(rt => rt.EnumerateFiles(path));\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    public static K<M, Seq<string>> enumerateFiles(string path, string searchPattern) =>\n        directoryIO.Bind(rt => rt.EnumerateFiles(path, searchPattern));\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    public static K<M, Seq<string>> enumerateFiles(string path, string searchPattern, SearchOption searchOption) =>\n        directoryIO.Bind(rt => rt.EnumerateFiles(path, searchPattern, searchOption));\n        \n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    public static K<M, Seq<string>> enumerateFileSystemEntries(string path) =>\n        directoryIO.Bind(rt => rt.EnumerateFileSystemEntries(path));\n\n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    public static K<M, Seq<string>> enumerateFileSystemEntries(string path, string searchPattern) =>\n        directoryIO.Bind(rt => rt.EnumerateFileSystemEntries(path, searchPattern));\n\n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    public static K<M, Seq<string>> enumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption) =>\n        directoryIO.Bind(rt => rt.EnumerateFileSystemEntries(path, searchPattern, searchOption));\n\n    /// <summary>\n    /// Get the root of the path provided\n    /// </summary>\n    public static K<M, string> getRoot(string path) =>\n        directoryIO.Bind(rt => rt.GetDirectoryRoot(path));\n\n    /// <summary>\n    /// Get the current directory\n    /// </summary>\n    public static K<M, string> current =>\n        directoryIO.Bind(rt => rt.GetCurrentDirectory());\n\n    /// <summary>\n    /// Set the current directory\n    /// </summary>\n    /// <param name=\"path\"></param>\n    public static K<M, Unit> setCurrent(string path) =>\n        directoryIO.Bind(rt => rt.SetCurrentDirectory(path));\n\n    /// <summary>\n    /// Move a directory\n    /// </summary>\n    public static K<M, Unit> move(string sourceDirName, string destDirName) =>\n        directoryIO.Bind(rt => rt.Move(sourceDirName, destDirName));\n\n    /// <summary>\n    /// Get the logical drives\n    /// </summary>\n    public static K<M, Seq<string>> logicalDrives =>\n        directoryIO.Bind(rt => rt.GetLogicalDrives());\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/IO/File.Eff.cs",
    "content": "﻿using System.IO;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing LanguageExt.Sys.Traits;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.Sys.IO;\n\n/// <summary>\n/// File IO \n/// </summary>\npublic class File<RT>\n    where RT : \n        Has<Eff<RT>, FileIO>, \n        Has<Eff<RT>, EncodingIO>\n{\n    /// <summary>\n    /// Copy file \n    /// </summary>\n    /// <param name=\"fromPath\">Source path</param>\n    /// <param name=\"toPath\">Destination path</param>\n    /// <param name=\"overwrite\">Overwrite if the file already exists at the destination</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <returns>Unit</returns>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> copy(string fromPath, string toPath, bool overwrite = false) =>\n        File<Eff<RT>, RT>.copy(fromPath, toPath, overwrite).As();\n\n    /// <summary>\n    /// Append lines to the end of the file provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> appendAllLines(string path, IEnumerable<string> contents) =>\n        File<Eff<RT>, RT>.appendAllLines(path, contents).As();\n\n    /// <summary>\n    /// Read all of the lines from the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Seq<string>> readAllLines(string path) =>\n        File<Eff<RT>, RT>.readAllLines(path).As();\n\n    /// <summary>\n    /// Write all of the lines to the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> writeAllLines(string path, Seq<string> lines) =>\n        File<Eff<RT>, RT>.writeAllLines(path, lines).As();\n\n    /// <summary>\n    /// Read all of the text from the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, string> readAllText(string path) =>\n        File<Eff<RT>, RT>.readAllText(path).As();\n\n    /// <summary>\n    /// Read all of the data from the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, byte[]> readAllBytes(string path) =>\n        File<Eff<RT>, RT>.readAllBytes(path).As();\n\n    /// <summary>\n    /// Write all of the text to the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> writeAllText(string path, string text) =>\n        File<Eff<RT>, RT>.writeAllText(path, text).As();\n\n    /// <summary>\n    /// Write all of the data to the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> writeAllBytes(string path, byte[] data) =>\n        File<Eff<RT>, RT>.writeAllBytes(path, data).As();\n\n    /// <summary>\n    /// Delete the file provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> delete(string path) =>\n        File<Eff<RT>, RT>.delete(path).As();\n\n    /// <summary>\n    /// True if a file exists at the path\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, bool> exists(string path) =>\n        File<Eff<RT>, RT>.exists(path).As();\n\n    /// <summary>\n    /// Open a text file\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Producer<RT, TextReader, Unit> openText(string path) => \n        File<Eff<RT>, RT>.openText(path);\n\n    /// <summary>\n    /// Create a new text file to stream to\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, TextWriter> createText(string path) =>\n        File<Eff<RT>, RT>.createText(path).As();\n\n    /// <summary>\n    /// Return a stream to append text to\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, TextWriter> appendText(string path) =>\n        File<Eff<RT>, RT>.appendText(path).As();\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public static Producer<RT, Stream, Unit> openRead(string path) =>\n        File<Eff<RT>, RT>.openRead(path);\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Producer<RT, Stream, Unit> open(string path, FileMode mode) =>\n        File<Eff<RT>, RT>.open(path, mode);\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Producer<RT, Stream, Unit> open(string path, FileMode mode, FileAccess access) =>\n        File<Eff<RT>, RT>.open(path, mode, access);\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Producer<RT, Stream, Unit> openWrite(string path) =>\n        File<Eff<RT>, RT>.openWrite(path);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/IO/File.cs",
    "content": "﻿using System.IO;\nusing LanguageExt.Pipes;\nusing LanguageExt.Sys.Traits;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys.IO;\n\n/// <summary>\n/// File IO \n/// </summary>\npublic class File<M, RT>\n    where M : \n        MonadIO<M>\n    where RT : \n        Has<M, FileIO>, \n        Has<M, EncodingIO>\n{\n    static K<M, FileIO> fileIO => \n        Has<M, RT, FileIO>.ask;\n    \n    /// <summary>\n    /// Copy file \n    /// </summary>\n    /// <param name=\"fromPath\">Source path</param>\n    /// <param name=\"toPath\">Destination path</param>\n    /// <param name=\"overwrite\">Overwrite if the file already exists at the destination</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <returns>Unit</returns>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> copy(string fromPath, string toPath, bool overwrite = false) =>\n        fileIO.Bind(e => e.Copy(fromPath, toPath, overwrite));\n    \n    /// <summary>\n    /// Move file \n    /// </summary>\n    /// <param name=\"fromPath\">Source path</param>\n    /// <param name=\"toPath\">Destination path</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <returns>Unit</returns>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> move(string fromPath, string toPath) =>\n        fileIO.Bind(e => e.Move(fromPath, toPath));\n    \n    /// <summary>\n    /// Move file \n    /// </summary>\n    /// <param name=\"fromPath\">Source path</param>\n    /// <param name=\"toPath\">Destination path</param>\n    /// <param name=\"overwrite\">Overwrite if the file already exists at the destination</param>\n    /// <typeparam name=\"RT\">Runtime</typeparam>\n    /// <returns>Unit</returns>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> move(string fromPath, string toPath, bool overwrite) =>\n        fileIO.Bind(e => e.Move(fromPath, toPath, overwrite));\n\n    /// <summary>\n    /// Append lines to the end of the file provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> appendAllLines(string path, IEnumerable<string> contents) =>\n        from en in Enc<M, RT>.encoding\n        from rs in fileIO.Bind(e => e.AppendAllLines(path, contents, en))\n        select rs;\n\n    /// <summary>\n    /// Read all of the lines from the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Seq<string>> readAllLines(string path) =>\n        from en in Enc<M, RT>.encoding\n        from rs in fileIO.Bind(e => e.ReadAllLines(path, en))\n        select rs;\n\n    /// <summary>\n    /// Write all of the lines to the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> writeAllLines(string path, Seq<string> lines) =>\n        from en in Enc<M, RT>.encoding\n        from rs in fileIO.Bind(e => e.WriteAllLines(path, lines, en))\n        select rs;\n\n    /// <summary>\n    /// Read all of the text from the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, string> readAllText(string path) =>\n        from en in Enc<M, RT>.encoding\n        from rs in fileIO.Bind(e => e.ReadAllText(path, en))\n        select rs;\n\n    /// <summary>\n    /// Read all of the data from the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, byte[]> readAllBytes(string path) =>\n        fileIO.Bind(e => e.ReadAllBytes(path));\n\n    /// <summary>\n    /// Write all of the text to the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> writeAllText(string path, string text) =>\n        from en in Enc<M, RT>.encoding\n        from rs in fileIO.Bind(e => e.WriteAllText(path, text, en))\n        select rs;\n\n    /// <summary>\n    /// Write all of the data to the path provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> writeAllBytes(string path, byte[] data) =>\n        fileIO.Bind(e => e.WriteAllBytes(path, data));\n\n    /// <summary>\n    /// Delete the file provided\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> delete(string path) =>\n        fileIO.Bind(e => e.Delete(path));\n\n    /// <summary>\n    /// True if a file exists at the path\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, bool> exists(string path) =>\n        fileIO.Bind(e => e.Exists(path));\n\n    /// <summary>\n    /// Open a text file\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static ProducerT<TextReader, M, Unit> openText(string path) => \n        from t in openTextInternal(path)\n        from _ in ProducerT.yield<M, TextReader>(t)\n        select unit;\n\n    /// <summary>\n    /// Create a new text file to stream to\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, TextWriter> createText(string path) =>\n        fileIO.Bind(e => e.CreateText(path));\n\n    /// <summary>\n    /// Return a stream to append text to\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, TextWriter> appendText(string path) =>\n        fileIO.Bind(e => e.AppendText(path));\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public static ProducerT<Stream, M, Unit> openRead(string path) =>\n        from s in openReadInternal(path)\n        from _ in ProducerT.yield<M, Stream>(s)\n        select unit;\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static ProducerT<Stream, M, Unit> open(string path, FileMode mode) =>\n        from s in openInternal(path, mode)\n        from _ in ProducerT.yield<M, Stream>(s)\n        select unit;\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static ProducerT<Stream, M, Unit> open(string path, FileMode mode, FileAccess access) =>\n        from s in openInternal(path, mode, access)\n        from _ in ProducerT.yield<M, Stream>(s)\n        select unit;\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static ProducerT<Stream, M, Unit> openWrite(string path) =>\n        from s in openWriteInternal(path)\n        from _ in ProducerT.yield<M, Stream>(s)\n        select unit;\n\n    // -- Internal ------------------------------------------------------------------------------------------------- \n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    static K<M, Stream> openReadInternal(string path) =>\n        from io in fileIO.Map(e => e.OpenRead(path))\n        from rs in use(io)\n        select rs;\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    static K<M, Stream> openInternal(string path, FileMode mode) =>\n        from io in fileIO.Map(e => e.Open(path, mode))\n        from rs in use(io)\n        select rs;\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    static K<M, Stream> openInternal(string path, FileMode mode, FileAccess access) =>\n        from io in fileIO.Map(e => e.Open(path, mode, access))\n        from rs in use(io)\n        select rs;\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    static K<M, Stream> openWriteInternal(string path) =>\n        from io in fileIO.Map(e => e.OpenWrite(path))\n        from rs in use(io)\n        select rs;\n\n    /// <summary>\n    /// Open a text file\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    static K<M, TextReader> openTextInternal(string path) =>\n        from io in fileIO.Map(e => e.OpenText(path))\n        from rs in use(io)\n        select rs;\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/IO/Stream.cs",
    "content": "using System.IO;\nusing System.Buffers;\nusing LanguageExt.Pipes;\nusing System.Collections.Generic;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing LanguageExt.UnsafeValueAccess;\n\nnamespace LanguageExt.Sys.IO;\n\npublic static class Stream<M> where M : MonadIO<M>\n{\n    /// <summary>\n    /// Get a pipe of chunks from a Stream\n    /// </summary>\n    public static PipeT<Stream, SeqLoan<byte>, M, Unit> read(int chunkSize)\n    {\n        return from fs in PipeT.awaiting<M, Stream, SeqLoan<byte>>()\n               from _  in PipeT.yieldAll<M, Stream, SeqLoan<byte>>(chunks(fs, chunkSize))\n               select unit;\n\n        static async IAsyncEnumerable<SeqLoan<byte>> chunks(Stream fs, int chunkSize)\n        {\n            var pool = ArrayPool<byte>.Shared;\n            while (true)\n            {\n                var buffer = pool.Rent(chunkSize);\n                var count  = await fs.ReadAsync(buffer, 0, chunkSize).ConfigureAwait(false);\n                if (count < 1)\n                {\n                    pool.Return(buffer);\n                    yield break;\n                }\n                yield return buffer.ToSeqLoanUnsafe(count, pool); \n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/IO/TextRead.Eff.cs",
    "content": "using System.IO;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing LanguageExt.Sys.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.Sys.IO;\n\npublic static class TextRead<RT>\n    where RT : \n        Has<Eff<RT>, TextReadIO>\n{\n    /// <summary>\n    /// Open a text file and streams the lines through the pipe\n    /// </summary>\n    [Pure]\n    public static Pipe<RT, TextReader, string, Unit> readLine =>\n        TextRead<Eff<RT>, RT>.readLine;\n        \n    /// <summary>\n    /// Open a text file and streams the chars through the pipe\n    /// </summary>\n    [Pure]\n    public static Pipe<RT, TextReader, char, Unit> readChar =>\n        TextRead<Eff<RT>, RT>.readChar;\n        \n    /// <summary>\n    /// Read the rest of the text in the stream\n    /// </summary>\n    [Pure]\n    public static Pipe<RT, TextReader, string, Unit> readToEnd =>\n        TextRead<Eff<RT>, RT>.readToEnd;\n\n    /// <summary>\n    /// Repeatedly read a number of chars from the stream\n    /// </summary>\n    [Pure]\n    public static Pipe<RT, TextReader, SeqLoan<char>, Unit> readChars(int charCount) =>\n        TextRead<Eff<RT>, RT>.readChars(charCount).As();\n\n    /// <summary>\n    /// Read a number of chars from the stream\n    /// </summary>\n    [Pure]\n    public static Pipe<RT, TextReader, string, Unit> read(int charCount) =>\n        TextRead<Eff<RT>, RT>.read(charCount).As();\n\n    /// <summary>\n    /// Close the reader\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> close(TextReader reader) =>\n        TextRead<Eff<RT>, RT>.close(reader).As();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/IO/TextRead.cs",
    "content": "using System.Buffers;\nusing System.IO;\nusing LanguageExt.Pipes;\nusing LanguageExt.Sys.Traits;\nusing static LanguageExt.Prelude;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.UnsafeValueAccess;\nusing System.Runtime.CompilerServices;\nusing LanguageExt.Traits;\nusing static LanguageExt.Pipes.PipeT;\n\nnamespace LanguageExt.Sys.IO;\n\npublic static class TextRead<M, RT>\n    where RT : \n        Has<M, TextReadIO>\n    where M : \n        MonadIO<M>\n{\n    static K<M, TextReadIO> textReadIO => \n        Has<M, RT, TextReadIO>.ask;\n    \n    /// <summary>\n    /// Open a text file and streams the lines through the pipe\n    /// </summary>\n    [Pure]\n    public static PipeT<TextReader, string, M, Unit> readLine\n    {\n        get\n        {\n            return from tr in awaiting<M, TextReader, string>()\n                   from _  in yieldAll<M, TextReader, string>(go(tr))\n                   select unit;\n\n            static async IAsyncEnumerable<string> go(TextReader reader)\n            {\n                while (true)\n                {\n                    var line = await reader.ReadLineAsync().ConfigureAwait(false);\n                    if(line == null) yield break;\n                    yield return line;\n                }\n            }\n        }\n    } \n        \n    /// <summary>\n    /// Open a text file and streams the chars through the pipe\n    /// </summary>\n    [Pure]\n    public static PipeT<TextReader, char, M, Unit> readChar\n    {\n        get\n        {\n            return from tr in awaiting<M, TextReader, char>()\n                   from _  in yieldAll<M, TextReader, char>(go(tr))\n                   select unit;\n\n            static async IAsyncEnumerable<char> go(TextReader reader)\n            {\n                var buffer = new char[1];\n                while (true)\n                {\n                    var nread = await reader.ReadAsync(buffer, 0, 1).ConfigureAwait(false);\n                    if(nread < 1) yield break;\n                    yield return buffer[0];\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Read the rest of the text in the stream\n    /// </summary>\n    [Pure]\n    public static PipeT<TextReader, string, M, Unit> readToEnd =>\n        from tr in awaiting<M, TextReader, string>()\n        from tx in LanguageExt.IO.liftAsync(async e => await tr.ReadToEndAsync(e.Token))\n        from __ in yield<M, TextReader, string>(tx)\n        select unit;\n\n    /// <summary>\n    /// Repeatedly read a number of chars from the stream\n    /// </summary>\n    [Pure]\n    public static PipeT<TextReader, SeqLoan<char>, M, Unit> readChars(int charCount)\n    {\n        return from tr in awaiting<M, TextReader, SeqLoan<char>>()\n               from _  in yieldAll<M, TextReader, SeqLoan<char>>(go(tr, charCount))\n               select unit;\n\n        static async IAsyncEnumerable<SeqLoan<char>> go(TextReader reader, int count)\n        {\n            var pool = ArrayPool<char>.Shared;\n            while (true)\n            {\n                var buffer = pool.Rent(count);\n                var nread  = await reader.ReadAsync(buffer, 0, count).ConfigureAwait(false);\n                if(nread < 0) yield break;\n                yield return buffer.ToSeqLoanUnsafe(nread, pool);\n            }\n        }\n    }\n\n    /// <summary>\n    /// Read a number of chars from the stream\n    /// </summary>\n    [Pure]\n    public static PipeT<TextReader, string, M, Unit> read(int charCount)\n    {\n        return from tr in awaiting<M, TextReader, string>()\n               from _  in yieldAll<M, TextReader, string>(go(tr, charCount))\n               select unit;\n\n        static async IAsyncEnumerable<string> go(TextReader reader, int count)\n        {\n            var pool   = ArrayPool<char>.Shared;\n            var buffer = pool.Rent(count);\n            try\n            {\n                while (true)\n                {\n                    var nread = await reader.ReadAsync(buffer, 0, count).ConfigureAwait(false);\n                    if (nread < 0) yield break;\n                    yield return new string(buffer);\n                }\n            }\n            finally\n            {\n                pool.Return(buffer);\n            }\n        }\n    }\n\n    /// <summary>\n    /// Close the reader\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> close(TextReader reader) =>\n        textReadIO.Bind(e => e.Close(reader));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Time.Eff.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing LanguageExt.Sys.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.Sys;\n\n/// <summary>\n/// DateTime IO \n/// </summary>\npublic static class Time<RT>\n    where RT : \n        Has<Eff<RT>, TimeIO>\n{\n    /// <summary>\n    /// Current local date time\n    /// </summary>\n    public static Eff<RT, DateTime> now =>\n        Time<Eff<RT>, RT>.now.As();\n\n    /// <summary>\n    /// Current universal date time\n    /// </summary>\n    public static Eff<RT, DateTime> nowUTC =>\n        Time<Eff<RT>, RT>.nowUTC.As();\n\n    /// <summary>\n    /// Today's date \n    /// </summary>\n    public static Eff<RT, DateTime> today =>\n        Time<Eff<RT>, RT>.today.As();\n\n    /// <summary>\n    /// Pause a task until a specified time\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> sleepUntil(DateTime dt) =>\n        Time<Eff<RT>, RT>.sleepUntil(dt).As();\n\n    /// <summary>\n    /// Pause a task until for a specified length of time\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static Eff<RT, Unit> sleepFor(TimeSpan ts) =>\n        Time<Eff<RT>, RT>.sleepFor(ts).As();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Sys/Time.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing LanguageExt.Sys.Traits;\nusing System.Diagnostics.Contracts;\nusing System.Runtime.CompilerServices;\n\nnamespace LanguageExt.Sys;\n\n/// <summary>\n/// DateTime IO \n/// </summary>\npublic static class Time<M, RT>\n    where M : \n        MonadIO<M>\n    where RT : \n        Has<M, TimeIO>\n{\n    static readonly K<M, TimeIO> timeIO =\n        Has<M, RT, TimeIO>.ask;\n\n    /// <summary>\n    /// Current local date time\n    /// </summary>\n    public static K<M, DateTime> now =>\n        timeIO.Bind(e => e.Now);\n\n    /// <summary>\n    /// Current universal date time\n    /// </summary>\n    public static K<M, DateTime> nowUTC =>\n        timeIO.Bind(e => e.UtcNow);\n\n    /// <summary>\n    /// Today's date \n    /// </summary>\n    public static K<M, DateTime> today =>\n        timeIO.Bind(e => e.Today);\n\n    /// <summary>\n    /// Pause a task until a specified time\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> sleepUntil(DateTime dt) =>\n        timeIO.Bind(e => e.SleepUntil(dt));\n\n    /// <summary>\n    /// Pause a task until for a specified length of time\n    /// </summary>\n    [Pure, MethodImpl(EffOpt.mops)]\n    public static K<M, Unit> sleepFor(TimeSpan ts) =>\n        timeIO.Bind(e => e.SleepFor(ts));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Test/Implementations/ConsoleIO.cs",
    "content": "using System;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Test.Implementations;\n\n/// <summary>\n/// Encapsulated in-memory console\n/// No public API exists for this.  Use Sys.IO.Console.* to interact with the console\n/// </summary>\n/// <remarks>\n/// Primarily used for testing (for use with TestRuntime or your own testing runtime)\n/// </remarks>\npublic record ConsoleIO(MemoryConsole mem) : Sys.Traits.ConsoleIO\n{\n    public IO<Option<ConsoleKeyInfo>> ReadKey() =>\n        lift(() => mem.ReadKey());\n\n    public IO<Unit> Clear() =>\n        lift(() => mem.Clear());\n\n    public IO<Unit> SetBgColor(ConsoleColor color) =>\n        lift(() => mem.SetBgColor(color));\n\n    public IO<Unit> SetColor(ConsoleColor color) =>\n        lift(() => mem.SetColor(color));\n\n    public IO<Unit> ResetColor() =>\n        lift(() => mem.ResetColor());\n\n    public IO<ConsoleColor> BgColor => \n        lift(() => mem.BgColor);\n        \n    public IO<ConsoleColor> Color => \n        lift(() => mem.Color);\n        \n    public IO<Option<int>> Read() =>\n        lift(() => mem.Read());\n        \n    public IO<Option<string>> ReadLine() =>\n        lift(() => mem.ReadLine());\n\n    public IO<Unit> WriteLine() =>\n        lift(() => mem.WriteLine());\n\n    public IO<Unit> WriteLine(string value) =>\n        lift(() => mem.WriteLine(value));\n\n    public IO<Unit> Write(string value) =>\n        lift(() => mem.Write(value));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Test/Implementations/DirectoryIO.cs",
    "content": "using System;\nusing System.IO;\n\nnamespace LanguageExt.Sys.Test.Implementations;\n\npublic record DirectoryIO(string root) : Traits.DirectoryIO\n{\n    string FixPath(string path) =>\n        Path.Combine(root, path.Replace(\":\", \"_drive\"));\n    \n    public IO<DirectoryInfo> Create(string path) =>\n        Live.Implementations.DirectoryIO.Default.Create(FixPath(path));\n\n    public IO<Unit> Delete(string path, bool recursive = true) =>\n        Live.Implementations.DirectoryIO.Default.Delete(FixPath(path), recursive);\n\n    public IO<Option<DirectoryInfo>> GetParent(string path) =>\n        Live.Implementations.DirectoryIO.Default.GetParent(FixPath(path));\n\n    public IO<bool> Exists(string path) =>\n        Live.Implementations.DirectoryIO.Default.Exists(FixPath(path));\n\n    public IO<Unit> SetCreationTime(string path, DateTime creationTime) =>\n        Live.Implementations.DirectoryIO.Default.SetCreationTime(FixPath(path), creationTime);\n\n    public IO<Unit> SetCreationTimeUtc(string path, DateTime creationTimeUtc) =>\n        Live.Implementations.DirectoryIO.Default.SetCreationTimeUtc(FixPath(path), creationTimeUtc);\n\n    public IO<DateTime> GetCreationTime(string path) =>\n        Live.Implementations.DirectoryIO.Default.GetCreationTime(FixPath(path));\n\n    public IO<DateTime> GetCreationTimeUtc(string path) =>\n        Live.Implementations.DirectoryIO.Default.GetCreationTimeUtc(FixPath(path));\n\n    public IO<Unit> SetLastWriteTime(string path, DateTime lastWriteTime) =>\n        Live.Implementations.DirectoryIO.Default.SetLastWriteTime(FixPath(path), lastWriteTime);\n\n    public IO<Unit> SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc) =>\n        Live.Implementations.DirectoryIO.Default.SetLastWriteTimeUtc(FixPath(path), lastWriteTimeUtc);\n\n    public IO<DateTime> GetLastWriteTime(string path) =>\n        Live.Implementations.DirectoryIO.Default.GetLastWriteTime(FixPath(path));\n\n    public IO<DateTime> GetLastWriteTimeUtc(string path) =>\n        Live.Implementations.DirectoryIO.Default.GetLastWriteTimeUtc(FixPath(path));\n\n    public IO<Unit> SetLastAccessTime(string path, DateTime lastAccessTime) =>\n        Live.Implementations.DirectoryIO.Default.SetLastAccessTime(FixPath(path), lastAccessTime);\n\n    public IO<Unit> SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc) =>\n        Live.Implementations.DirectoryIO.Default.SetLastAccessTimeUtc(FixPath(path), lastAccessTimeUtc);\n\n    public IO<DateTime> GetLastAccessTime(string path) =>\n        Live.Implementations.DirectoryIO.Default.GetLastAccessTime(FixPath(path));\n\n    public IO<DateTime> GetLastAccessTimeUtc(string path) =>\n        Live.Implementations.DirectoryIO.Default.GetLastAccessTimeUtc(FixPath(path));\n\n    public IO<Seq<string>> EnumerateDirectories(string path) =>\n        Live.Implementations.DirectoryIO.Default.EnumerateDirectories(FixPath(path));\n\n    public IO<Seq<string>> EnumerateDirectories(string path, string searchPattern) =>\n        Live.Implementations.DirectoryIO.Default.EnumerateDirectories(FixPath(path), searchPattern);\n\n    public IO<Seq<string>> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption) =>\n        Live.Implementations.DirectoryIO.Default.EnumerateDirectories(FixPath(path), searchPattern, searchOption);\n\n    public IO<Seq<string>> EnumerateFiles(string path) =>\n        Live.Implementations.DirectoryIO.Default.EnumerateFiles(FixPath(path));\n\n    public IO<Seq<string>> EnumerateFiles(string path, string searchPattern) =>\n        Live.Implementations.DirectoryIO.Default.EnumerateFiles(FixPath(path), searchPattern);\n\n    public IO<Seq<string>> EnumerateFiles(string path, string searchPattern, SearchOption searchOption) =>\n        Live.Implementations.DirectoryIO.Default.EnumerateFiles(FixPath(path), searchPattern, searchOption);\n\n    public IO<Seq<string>> EnumerateFileSystemEntries(string path) =>\n        Live.Implementations.DirectoryIO.Default.EnumerateFileSystemEntries(FixPath(path));\n\n    public IO<Seq<string>> EnumerateFileSystemEntries(string path, string searchPattern) =>\n        Live.Implementations.DirectoryIO.Default.EnumerateFileSystemEntries(FixPath(path), searchPattern);\n\n    public IO<Seq<string>> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption)  =>\n        Live.Implementations.DirectoryIO.Default.EnumerateFileSystemEntries(FixPath(path), searchPattern, searchOption);\n\n    public IO<string> GetDirectoryRoot(string path) =>\n        Live.Implementations.DirectoryIO.Default.GetDirectoryRoot(FixPath(path));\n\n    public IO<string> GetCurrentDirectory()  =>\n        Live.Implementations.DirectoryIO.Default.GetCurrentDirectory();\n\n    public IO<Unit> SetCurrentDirectory(string path) =>\n        Live.Implementations.DirectoryIO.Default.SetCurrentDirectory(FixPath(path));\n\n    public IO<Unit> Move(string sourceDirName, string destDirName) =>\n        Live.Implementations.DirectoryIO.Default.Move(FixPath(sourceDirName), FixPath(destDirName));\n\n    public IO<Seq<string>> GetLogicalDrives() =>\n        Live.Implementations.DirectoryIO.Default.GetLogicalDrives();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Test/Implementations/EnvironmentIO.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Test.Implementations;\n\npublic record EnvironmentIO(MemorySystemEnvironment env) : Sys.Traits.EnvironmentIO\n{\n    /// <summary>\n    /// Gets the command line for this process.\n    /// </summary>\n    public IO<string> CommandLine() =>\n        lift(() => env.CommandLine);\n\n    /// <summary>\n    /// Gets a unique identifier for the current managed thread.\n    /// </summary>\n    public IO<int> CurrentManagedThreadId() =>\n        lift(() => env.CurrentManagedThreadId);\n\n    /// <summary>\n    /// Terminates this process and returns an exit code to the operating system.\n    /// </summary>\n    public IO<Unit> Exit(int exitCode) =>\n        lift(() =>\n             {\n                 Environment.Exit(exitCode);\n                 return unit;\n             });\n\n    /// <summary>\n    /// Gets the exit code of the process.\n    /// </summary>\n    public IO<int> ExitCode() =>\n        lift(() => env.ExitCode);\n\n    /// <summary>\n    /// Sets the exit code of the process.\n    /// </summary>\n    // exitCode: exit code of the process\n    public IO<Unit> SetExitCode(int exitCode) =>\n        lift(() =>\n             {\n                 env.ExitCode = exitCode;\n                 return unit;\n             });\n\n    /// <summary>\n    /// Replaces the name of each environment variable embedded in the specified string with the string equivalent of the value of the variable, then returns the resulting string.\n    /// </summary>\n    /// name: A string containing the names of zero or more environment variables. Each environment variable is quoted with the percent sign character (%).\n    public IO<string> ExpandEnvironmentVariables(string name) =>\n        lift<string>(() => throw new NotImplementedException());\n\n    /// <summary>\n    /// Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message in error reporting to Microsoft.\n    /// </summary>\n    /// message: A message that explains why the process was terminated, or null if no explanation is provided.\n    public IO<Unit> FailFast(Option<string> message) =>\n        lift(() =>\n             {\n                 Environment.FailFast(message.IfNone(\"\"));\n                 return unit;\n             });\n\n    /// <summary>\n    /// Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message and exception information in error reporting to Microsoft.\n    /// </summary>\n    /// message: A message that explains why the process was terminated, or null if no explanation is provided.\n    /// exception: An exception that represents the error that caused the termination. This is typically the exception in a catch block.\n    public IO<Unit> FailFast(Option<string> message, Option<Exception> exception) =>\n        lift(() =>\n             {\n                 Environment.FailFast(message.IfNone(\"\"), exception.IfNone(BottomException.Default));\n                 return unit;\n             });\n\n    /// <summary>\n    /// Returns a string array containing the command-line arguments for the current process.\n    /// </summary>\n    public IO<Seq<string>> GetCommandLineArgs() =>\n        lift(() => env.CommandLineArgs);\n\n    /// <summary>\n    /// Retrieves the value of an environment variable from the current process.\n    /// </summary>\n    /// variable: The name of an environment variable.\n    public IO<Option<string>> GetEnvironmentVariable(string variable) =>\n        lift(() =>\n             {\n                 if (env.ProcessEnvironmentVariables.TryGetValue(variable, out var processEnvironmentVariable))\n                 {\n                     return processEnvironmentVariable;\n                 }\n                 else if (env.UserEnvironmentVariables.TryGetValue(variable, out var userEnvironmentVariable))\n                 {\n                     return userEnvironmentVariable;\n                 }\n                 else if (env.SystemEnvironmentVariables.TryGetValue(variable, out var environmentVariable))\n                 {\n                     return environmentVariable;\n                 }\n                 else\n                 {\n                     return None;\n                 }\n             });\n\n    /// <summary>\n    /// Retrieves the value of an environment variable from the current process or from the Windows operating system registry key for the current user or local machine.\n    /// </summary>\n    /// variable: The name of an environment variable.\n    public IO<Option<string>> GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) =>\n        lift(() =>\n             {\n                 if (target == EnvironmentVariableTarget.Process &&\n                     env.ProcessEnvironmentVariables.TryGetValue(variable, out var processEnvironmentVariable))\n                 {\n                     return processEnvironmentVariable;\n                 }\n                 else if (target == EnvironmentVariableTarget.User &&\n                          env.UserEnvironmentVariables.TryGetValue(variable, out var userEnvironmentVariable))\n                 {\n                     return userEnvironmentVariable;\n                 }\n                 else if (target == EnvironmentVariableTarget.Machine &&\n                          env.SystemEnvironmentVariables.TryGetValue(variable, out var environmentVariable))\n                 {\n                     return environmentVariable;\n                 }\n                 else\n                 {\n                     return default;\n                 }\n             });\n\n    /// <summary>\n    /// Retrieves all environment variable names and their values from the current process.\n    /// </summary>\n    public IO<HashMap<string, Option<string>>> GetEnvironmentVariables() =>\n        lift(() => env.ProcessEnvironmentVariables.ToHashMap() +\n                   env.UserEnvironmentVariables.ToHashMap()    +\n                   env.SystemEnvironmentVariables.ToHashMap());\n\n    /// <summary>\n    /// Retrieves all environment variable names and their values from the current process, or from the Windows operating system registry key for the current user or local machine.\n    /// </summary>\n    /// target: One of the System.EnvironmentVariableTarget values. Only System.EnvironmentVariableTarget.Process is supported on .NET Core running on Unix-based systems.\n    public IO<HashMap<string, Option<string>>> GetEnvironmentVariables(EnvironmentVariableTarget target) =>\n        lift(() => target switch\n                   {\n                       EnvironmentVariableTarget.Process => env.ProcessEnvironmentVariables.ToHashMap(),\n                       EnvironmentVariableTarget.User    => env.UserEnvironmentVariables.ToHashMap(),\n                       EnvironmentVariableTarget.Machine => env.SystemEnvironmentVariables.ToHashMap(),\n                       _                                 => default\n                   });\n\n    /// <summary>\n    /// Gets the path to the system special folder that is identified by the specified enumeration.\n    /// </summary>\n    /// folder: One of enumeration values that identifies a system special folder.\n    public IO<string> GetFolderPath(Environment.SpecialFolder folder) =>\n        lift(() => env.GetFolderPath(folder, Environment.SpecialFolderOption.None));\n\n    /// <summary>\n    /// Gets the path to the system special folder that is identified by the specified enumeration, and uses a specified option for accessing special folders.\n    /// </summary>\n    /// folder: One of the enumeration values that identifies a system special folder.\n    /// option: One of the enumeration values that specifies options to use for accessing a special folder.\n    public IO<string> GetFolderPath(Environment.SpecialFolder folder, Environment.SpecialFolderOption option) =>\n        lift(() => env.GetFolderPath(folder, option));\n\n    /// <summary>\n    /// Returns an array of string containing the names of the logical drives on the current computer.\n    /// </summary>\n    /// string[] Environment.GetLogicalDrives()\n    public IO<Seq<string>> GetLogicalDrives() =>\n        lift(() => env.LogicalDrives);\n\n    /// <summary>\n    /// Gets a value that indicates whether the current application domain is being unloaded or the common language runtime (CLR) is shutting down.\n    /// </summary>\n    public IO<bool> HasShutdownStarted() =>\n        lift(() => env.HasShutdownStarted);\n\n    /// <summary>\n    /// Determines whether the current operating system is a 64-bit operating system.\n    /// </summary>\n    public IO<bool> Is64BitOperatingSystem() =>\n        lift(() => env.Is64BitOperatingSystem);\n\n    /// <summary>\n    /// Determines whether the current process is a 64-bit process.\n    /// </summary>\n    public IO<bool> Is64BitProcess() =>\n        lift(() => env.Is64BitProcess);\n\n    /// <summary>\n    /// Gets the NetBIOS name of this local computer.\n    /// </summary>\n    public IO<string> MachineName() =>\n        lift(() => env.MachineName);\n\n    /// <summary>\n    /// Gets the newline string defined for this environment.\n    /// </summary>\n    public IO<string> NewLine() =>\n        lift(() => env.NewLine);\n\n    /// <summary>\n    /// Gets an OperatingSystem object that contains the current platform identifier and version number.\n    /// </summary>\n    public IO<OperatingSystem> OSVersion() =>\n        lift(() => env.OSVersion);\n\n    /// <summary>\n    /// Gets the number of processors on the current machine.\n    /// </summary>\n    public IO<int> ProcessorCount() =>\n        lift(() => env.ProcessorCount);\n\n    /// <summary>\n    /// Creates, modifies, or deletes an environment variable stored in the current process.\n    /// </summary>\n    /// variable: The name of an environment variable.\n    /// value: A value to assign to variable .\n    public IO<Unit> SetEnvironmentVariable(string variable, Option<string> value) =>\n        lift(() =>\n             {\n                 if (value.IsSome)\n                 {\n                     env.ProcessEnvironmentVariables.AddOrUpdate(variable, (string)value, (_, _) => (string)value);\n                 }\n                 else\n                 {\n                     env.ProcessEnvironmentVariables.TryRemove(variable, out _);\n                 }\n                 return unit;\n             });\n\n    /// <summary>\n    /// Creates, modifies, or deletes an environment variable stored in the current process or in the Windows operating system registry key reserved for the current user or local machine.\n    /// </summary>\n    /// variable: The name of an environment variable.\n    /// value: A value to assign to variable.\n    /// target: One of the enumeration values that specifies the location of the environment variable.\n    public IO<Unit> SetEnvironmentVariable(string variable, Option<string> value, EnvironmentVariableTarget target) =>\n        lift(() =>\n             {\n                 switch (target)\n                 {\n                     case EnvironmentVariableTarget.Process:\n                         if (value.IsSome)\n                         {\n                             env.ProcessEnvironmentVariables.AddOrUpdate(\n                                 variable, (string)value, (_, _) => (string)value);\n                         }\n                         else\n                         {\n                             env.ProcessEnvironmentVariables.TryRemove(variable, out var _);\n                         }\n\n                         break;\n\n                     case EnvironmentVariableTarget.User:\n                         if (value.IsSome)\n                         {\n                             env.UserEnvironmentVariables.AddOrUpdate(variable, (string)value, (_, _) => (string)value);\n                         }\n                         else\n                         {\n                             env.UserEnvironmentVariables.TryRemove(variable, out _);\n                         }\n\n                         break;\n\n                     case EnvironmentVariableTarget.Machine:\n                         if (value.IsSome)\n                         {\n                             env.SystemEnvironmentVariables.AddOrUpdate(\n                                 variable, (string)value, (_, _) => (string)value);\n                         }\n                         else\n                         {\n                             env.SystemEnvironmentVariables.TryRemove(variable, out _);\n                         }\n\n                         break;\n                 }\n                 return unit;\n             });\n\n    /// <summary>\n    /// Gets current stack trace information.\n    /// </summary>\n    public IO<string> StackTrace() =>\n        lift(() => env.StackTrace);\n\n    /// <summary>\n    /// Gets the fully qualified path of the system directory.\n    /// </summary>\n    public IO<string> SystemDirectory() =>\n        lift(() => env.SystemDirectory);\n\n    /// <summary>\n    /// Gets the number of bytes in the operating system's memory page.\n    /// </summary>\n    public IO<int> SystemPageSize() =>\n        lift(() => env.SystemPageSize);\n\n    /// <summary>\n    /// Gets the number of milliseconds elapsed since the system started.\n    /// </summary>\n    public IO<long> TickCount() =>\n        lift(() => env.TickCount);\n\n    // NOTE: This seems to be a newer interface, but I'm not sure how to handle it\n    // Gets the number of milliseconds elapsed since the system started.\n    // public IO<long TickCount64() =>\n    //     Environment.TickCount64);\n\n    /// <summary>\n    /// Gets the network domain name associated with the current user.\n    /// </summary>\n    public IO<string> UserDomainName() =>\n        lift(() => env.UserDomainName);\n\n    /// <summary>\n    /// Gets a value indicating whether the current process is running in user interactive mode.\n    /// </summary>\n    public IO<bool> UserInteractive() =>\n        lift(() => env.UserInteractive);\n\n    /// <summary>\n    /// Gets the user name of the person who is currently logged on to the operating system.\n    /// </summary>\n    public IO<string> UserName() =>\n        lift(() => env.UserName);\n\n    /// <summary>\n    /// Gets a Version object that describes the major, minor, build, and revision numbers of the common language runtime.\n    /// </summary>\n    public IO<Version> Version() =>\n        lift(() => env.Version);\n\n    /// <summary>\n    /// Gets the amount of physical memory mapped to the process context.\n    /// </summary>\n    public IO<long> WorkingSet() =>\n        lift(() => env.WorkingSet);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Test/Implementations/FileIO.cs",
    "content": "using System.IO;\nusing System.Text;\nusing System.Collections.Generic;\n\nnamespace LanguageExt.Sys.Test.Implementations;\n\n/// <summary>\n/// Test world interaction with the file-system\n/// </summary>\n/// <remarks>\n/// Primarily used for testing (for use with TestRuntime or your own testing runtime)\n/// </remarks>\npublic record FileIO(string root) : Sys.Traits.FileIO\n{\n    string FixPath(string path) =>\n        Path.Combine(root, path.Replace(\":\", \"_drive\"));\n    \n    /// <summary>\n    /// Copy file from one place to another\n    /// </summary>\n    public IO<Unit> Copy(string fromPath, string toPath, bool overwrite = false) =>\n        Live.Implementations.FileIO.Default.Copy(FixPath(fromPath), FixPath(toPath), overwrite);\n\n    /// <summary>\n    /// Move file from one place to another\n    /// </summary>\n    public IO<Unit> Move(string fromPath, string toPath) =>\n        Live.Implementations.FileIO.Default.Move(fromPath, toPath);\n\n    /// <summary>\n    /// Move file from one place to another\n    /// </summary>\n    public IO<Unit> Move(string fromPath, string toPath, bool overwrite) =>\n        Live.Implementations.FileIO.Default.Move(fromPath, toPath, overwrite);\n\n    /// <summary>\n    /// Append lines to the end of a file\n    /// </summary>\n    public IO<Unit> AppendAllLines(string path, IEnumerable<string> lines, Encoding encoding) =>\n        Live.Implementations.FileIO.Default.AppendAllLines(FixPath(path), lines, encoding);\n        \n    /// <summary>\n    /// Read all lines from a file\n    /// </summary>\n    public IO<Seq<string>> ReadAllLines(string path, Encoding encoding) => \n        Live.Implementations.FileIO.Default.ReadAllLines(FixPath(path), encoding);\n        \n    /// <summary>\n    /// Read all lines from a file\n    /// </summary>\n    public IO<byte[]> ReadAllBytes(string path) => \n        Live.Implementations.FileIO.Default.ReadAllBytes(FixPath(path));\n\n    /// <summary>\n    /// Write all lines to a file\n    /// </summary>\n    public IO<Unit> WriteAllLines(string path, IEnumerable<string> lines, Encoding encoding) =>\n        Live.Implementations.FileIO.Default.WriteAllLines(FixPath(path), lines, encoding);\n\n    /// <summary>\n    /// Write all lines to a file\n    /// </summary>\n    public IO<Unit> WriteAllBytes(string path, byte[] data) =>\n        Live.Implementations.FileIO.Default.WriteAllBytes(FixPath(path), data);\n\n    /// <summary>\n    /// Read text from a file\n    /// </summary>\n    public IO<string> ReadAllText(string path, Encoding encoding) =>\n        Live.Implementations.FileIO.Default.ReadAllText(FixPath(path), encoding);\n        \n    /// <summary>\n    /// Write text to a file\n    /// </summary>\n    public IO<Unit> WriteAllText(string path, string text, Encoding encoding) =>\n        Live.Implementations.FileIO.Default.WriteAllText(FixPath(path), text, encoding);\n\n    /// <summary>\n    /// Delete a file\n    /// </summary>\n    public IO<Unit> Delete(string path) =>\n        Live.Implementations.FileIO.Default.Delete(FixPath(path));\n\n    /// <summary>\n    /// True if a file at the path exists\n    /// </summary>\n    public IO<bool> Exists(string path) =>\n        Live.Implementations.FileIO.Default.Exists(FixPath(path));\n\n    /// <summary>\n    /// Open a text file\n    /// </summary>\n    public IO<TextReader> OpenText(string path) =>\n        Live.Implementations.FileIO.Default.OpenText(FixPath(path));\n\n    /// <summary>\n    /// Create a new text file to stream to\n    /// </summary>\n    public IO<TextWriter> CreateText(string path) =>\n        Live.Implementations.FileIO.Default.CreateText(FixPath(path));\n\n    /// <summary>\n    /// Return a stream to append text to\n    /// </summary>\n    public IO<TextWriter> AppendText(string path) =>\n        Live.Implementations.FileIO.Default.AppendText(FixPath(path));\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public IO<Stream> OpenRead(string path) =>\n        Live.Implementations.FileIO.Default.OpenRead(FixPath(path));\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public IO<Stream> Open(string path, FileMode mode) =>\n        Live.Implementations.FileIO.Default.Open(FixPath(path), mode);\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public IO<Stream> Open(string path, FileMode mode, FileAccess access) =>\n        Live.Implementations.FileIO.Default.Open(FixPath(path), mode, access);\n        \n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    public IO<Stream> OpenWrite(string path) =>\n        Live.Implementations.FileIO.Default.OpenWrite(FixPath(path));\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Test/Implementations/TestTimeSpec.cs",
    "content": "using System;\n\nnamespace LanguageExt.Sys.Test.Implementations;\n\npublic record TestTimeSpec(Schedule Schedule, DateTime Start)\n{\n    /// <summary>\n    /// Time never passes, it has a constant value of `start`\n    /// </summary>\n    public static TestTimeSpec FixedFromSpecified(DateTime start) =>\n        new (Schedule.Forever, start);\n\n    /// <summary>\n    /// Time never passes, it has a constant value of `DateTime.Now` (as it was set when you call this method)\n    /// </summary>\n    public static TestTimeSpec FixedFromNow(DateTime start) =>\n        FixedFromSpecified(DateTime.UtcNow);\n    \n    /// <summary>\n    /// Time passes at 1 millisecond per tick starting from `start`\n    /// </summary>\n    public static TestTimeSpec RunningFromSpecified(DateTime start) =>\n        new (Schedule.spaced(1), start);\n\n    /// <summary>\n    /// Time passes at 1 millisecond per tick starting from `DateTime.Now`\n    /// </summary>\n    public static TestTimeSpec RunningFromNow() =>\n        RunningFromSpecified(DateTime.UtcNow);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Test/Implementations/TextReadIO.cs",
    "content": "using System;\nusing System.IO;\n\nnamespace LanguageExt.Sys.Test.Implementations;\n\npublic struct TextReadIO : Sys.Traits.TextReadIO\n{\n    public static Sys.Traits.TextReadIO Default =\n        new TextReadIO();\n \n    /// <summary>\n    /// Read a line of text from the stream\n    /// </summary>\n    public IO<Option<string>> ReadLine(TextReader reader) =>\n        Live.Implementations.TextReadIO.Default.ReadLine(reader);\n\n    /// <summary>\n    /// Read the rest of the text in the stream\n    /// </summary>\n    public IO<string> ReadToEnd(TextReader reader) =>\n        Live.Implementations.TextReadIO.Default.ReadToEnd(reader);\n\n    /// <summary>\n    /// Read chars from the stream into the buffer\n    /// Returns the number of chars read\n    /// </summary>\n    public IO<int> Read(TextReader reader, Memory<char> buffer) =>\n        Live.Implementations.TextReadIO.Default.Read(reader, buffer);\n\n    /// <summary>\n    /// Close the reader\n    /// </summary>\n    public IO<Unit> Close(TextReader reader) =>\n        Live.Implementations.TextReadIO.Default.Close(reader);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Test/Implementations/TimeIO.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Sys.Test.Implementations;\n\npublic class TimeIO : Sys.Traits.TimeIO, IDisposable\n{\n    readonly Atom<DateTime> now;\n    readonly IEnumerator<Duration> ticks;\n\n    public TimeIO(TestTimeSpec spec)\n    {\n        now = Atom(spec.Start);\n        ticks = spec.Schedule.Run().GetEnumerator();\n    }\n\n    public void Dispose() =>\n        ticks.Dispose();\n\n    void Tick() =>\n        now.Swap(n =>\n                 {\n                     if (!ticks.MoveNext()) throw new TimeoutException(\"We've reached the heat death of the universe\");\n                     return n.AddMilliseconds(ticks.Current);\n                 });\n\n    /// <summary>\n    /// Current UTC date time\n    /// </summary>\n    public IO<DateTime> UtcNow =>\n        lift(() =>\n             {\n                 Tick();\n                 return now.Value;\n             });\n\n    /// <summary>\n    /// Current local date time\n    /// </summary>\n    public IO<DateTime> Now =>\n        UtcNow.Map(t => t.ToLocalTime());\n\n    /// <summary>\n    /// Today's date \n    /// </summary>\n    public IO<DateTime> Today => \n        Now.Map(t => t.Date);\n\n    /// <summary>\n    /// Pause a task until a specified time\n    /// </summary>\n    public IO<Unit> SleepUntil(DateTime dt) =>\n        Live.Implementations.TimeIO.Default.SleepUntil(dt);\n\n    /// <summary>\n    /// Pause a task until for a specified length of time\n    /// </summary>\n    public IO<Unit> SleepFor(TimeSpan ts) =>\n        Live.Implementations.TimeIO.Default.SleepFor(ts);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Test/Runtime.cs",
    "content": "using System;\nusing System.IO;\nusing System.Text;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Sys.Test;\n\n/// <summary>\n/// Test IO runtime\n/// </summary>\npublic record Runtime(RuntimeEnv Env) : \n    Local<Eff<Runtime>, ActivityEnv>,\n    Has<Eff<Runtime>, ActivitySourceIO>,\n    Has<Eff<Runtime>, ConsoleIO>,\n    Has<Eff<Runtime>, EncodingIO>,\n    Has<Eff<Runtime>, FileIO>,\n    Has<Eff<Runtime>, TextReadIO>,\n    Has<Eff<Runtime>, TimeIO>,\n    Has<Eff<Runtime>, EnvironmentIO>,\n    Has<Eff<Runtime>, DirectoryIO>,\n    IDisposable\n{\n    /// <summary>\n    /// Constructor function\n    /// </summary>\n    public static Runtime New()\n    {\n        var tmp = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());\n        Directory.CreateDirectory(tmp);\n        return new(RuntimeEnv.New(tmp));\n    }\n\n    /// <summary>\n    /// Constructor function\n    /// </summary>\n    /// <param name=\"env\">Data environment for the runtime.  Call `RuntimeEnv.Default with { ... }` to modify</param>\n    public static Runtime New(RuntimeEnv env) =>\n        new(env);\n\n    static K<Eff<Runtime>, A> asks<A>(Func<Runtime, A> f) =>\n        Readable.asks<Eff<Runtime>, Runtime, A>(f);\n    \n    static K<Eff<Runtime>, A> local<A>(Func<Runtime, Runtime> f, K<Eff<Runtime>, A> ma) =>\n        Readable.local(f, ma);\n    \n    static K<Eff<Runtime>, A> localEnv<A>(Func<RuntimeEnv, RuntimeEnv> f, K<Eff<Runtime>, A> ma) =>\n        local(e => e with { Env = f(e.Env) }, ma);\n\n    static K<Eff<Runtime>, A> localActivity<A>(Func<ActivityEnv, ActivityEnv> f, K<Eff<Runtime>, A> ma) =>\n        local(e => e with { Env = e.Env with { Activity = f(e.Env.Activity) } }, ma);\n\n    /// <summary>\n    /// Access the console environment\n    /// </summary>\n    /// <returns>Console environment</returns>\n    static K<Eff<Runtime>, ConsoleIO> Has<Eff<Runtime>, ConsoleIO>.Ask => \n        asks<ConsoleIO>(rt => new Implementations.ConsoleIO(rt.Env.Console));\n\n    /// <summary>\n    /// Access the file environment\n    /// </summary>\n    /// <returns>File environment</returns>\n    static K<Eff<Runtime>, FileIO> Has<Eff<Runtime>, FileIO>.Ask =>\n        asks<FileIO>(rt => new Implementations.FileIO(rt.Env.RootPath));\n\n    /// <summary>\n    /// Access the TextReader environment\n    /// </summary>\n    /// <returns>TextReader environment</returns>\n    static K<Eff<Runtime>, TextReadIO> Has<Eff<Runtime>, TextReadIO>.Ask => \n        asks<TextReadIO>(_ => Implementations.TextReadIO.Default);\n\n    /// <summary>\n    /// Access the time environment\n    /// </summary>\n    /// <returns>Time environment</returns>\n    static K<Eff<Runtime>, TimeIO> Has<Eff<Runtime>, TimeIO>.Ask => \n        asks<TimeIO>(rt => new Implementations.TimeIO(rt.Env.TimeSpec));\n\n    /// <summary>\n    /// Access the operating-system environment\n    /// </summary>\n    /// <returns>Operating-system environment environment</returns>\n    static K<Eff<Runtime>, EnvironmentIO> Has<Eff<Runtime>, EnvironmentIO>.Ask => \n        asks<EnvironmentIO>(rt => new Implementations.EnvironmentIO(rt.Env.SysEnv));\n\n    /// <summary>\n    /// Access the directory environment\n    /// </summary>\n    /// <returns>Directory environment</returns>\n    static K<Eff<Runtime>, DirectoryIO> Has<Eff<Runtime>, DirectoryIO>.Ask =>\n        asks<DirectoryIO>(rt => new Implementations.DirectoryIO(rt.Env.RootPath));\n\n    static K<Eff<Runtime>, EncodingIO> Has<Eff<Runtime>, EncodingIO>.Ask =>\n        asks<EncodingIO>(_ => Live.Implementations.EncodingIO.Default);\n\n    static K<Eff<Runtime>, ActivitySourceIO> Has<Eff<Runtime>, ActivitySourceIO>.Ask => \n        asks<ActivitySourceIO>(rt => new Live.Implementations.ActivitySourceIO(rt.Env.Activity));\n\n    /// <summary>\n    /// Run with a local ActivityEnv \n    /// </summary>\n    static K<Eff<Runtime>, A> Local<Eff<Runtime>, ActivityEnv>.With<A>(Func<ActivityEnv, ActivityEnv> f, K<Eff<Runtime>, A> ma) => \n        localActivity(f, ma);\n\n    /// <summary>\n    /// Read the current ActivityEnv\n    /// </summary>\n    static K<Eff<Runtime>, ActivityEnv> Has<Eff<Runtime>, ActivityEnv>.Ask =>\n        asks(rt => rt.Env.Activity);\n\n    public override string ToString() => \n        \"Test Runtime\";\n\n    public void Dispose() => \n        Directory.Delete(Env.RootPath, recursive: true);\n}\n    \npublic record RuntimeEnv(\n    EnvIO EnvIO,\n    Encoding Encoding,\n    MemoryConsole Console,\n    string RootPath,\n    Implementations.TestTimeSpec TimeSpec,\n    MemorySystemEnvironment SysEnv,\n    ActivityEnv Activity)\n{\n    public RuntimeEnv LocalCancel =>\n        this with { EnvIO = EnvIO.LocalCancel };\n\n    public static RuntimeEnv New(string rootPath) =>\n        new(EnvIO.New(),\n            Encoding.Default,\n            new MemoryConsole(),\n            rootPath,\n            Implementations.TestTimeSpec.RunningFromNow(),\n            MemorySystemEnvironment.InitFromSystem(),\n            ActivityEnv.Default);\n\n    public override string ToString() => \n        \"Runtime Environment\";\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/ActivitySourceIO.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\n\nnamespace LanguageExt.Sys.Traits;\n\npublic interface ActivitySourceIO\n{\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name and activity kind.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"kind\">The activity kind.</param>\n    /// <returns>The created activity object, if it had active listeners, or `None` if it has no event\n    /// listeners.</returns>\n    IO<Activity?> StartActivity(string name, ActivityKind kind);\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"kind\">The activity kind.</param>\n    /// <param name=\"parentContext\">The parent `ActivityContext` object to initialize the created activity object\n    /// with</param>\n    /// <param name=\"tags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"links\">The optional `ActivityLink` list to initialise the created activity object with.</param>\n    /// <param name=\"startTime\">The optional start timestamp to set on the created activity object.</param>\n    /// <returns>The created activity object, if it had active listeners, or null if it has no event listeners.</returns>\n    IO<Activity?> StartActivity(\n        string name, \n        ActivityKind kind, \n        ActivityContext parentContext,\n        HashMap<string,object> tags = default, \n        Seq<ActivityLink> links = default, \n        DateTimeOffset startTime = default);\n\n    /// <summary>\n    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent\n    /// activity context, tags, optional activity link and optional start time.\n    /// </summary>\n    /// <param name=\"name\">The operation name of the activity.</param>\n    /// <param name=\"kind\">The activity kind.</param>\n    /// <param name=\"parentId\">The parent Id to initialize the created activity object with.</param>\n    /// <param name=\"tags\">The optional tags list to initialise the created activity object with.</param>\n    /// <param name=\"links\">The optional `ActivityLink` list to initialise the created activity object with.</param>\n    /// <param name=\"startTime\">The optional start timestamp to set on the created activity object.</param>\n    /// <returns>The created activity object, if it had active listeners, or null if it has no event listeners.</returns>\n    IO<Activity?> StartActivity(\n        string name, \n        ActivityKind kind, \n        string parentId,\n        HashMap<string,object> tags = default, \n        Seq<ActivityLink> links = default, \n        DateTimeOffset startTime = default);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/ConsoleIO.cs",
    "content": "using System;\n\nnamespace LanguageExt.Sys.Traits;\n\npublic interface ConsoleIO\n{\n    IO<Unit> Clear();\n    IO<Option<ConsoleKeyInfo>> ReadKey();\n    IO<Option<int>> Read();\n    IO<Option<string>> ReadLine();\n    IO<Unit> WriteLine();\n    IO<Unit> WriteLine(string value);\n    IO<Unit> Write(string value);\n    IO<Unit> SetBgColor(ConsoleColor color);\n    IO<Unit> SetColor(ConsoleColor color);\n\n    /// <summary>\n    /// Sets the foreground and background console colors to their defaults.\n    /// </summary>\n    IO<Unit> ResetColor();\n\n    IO<ConsoleColor> BgColor { get; }\n    IO<ConsoleColor> Color { get; }\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/DirectoryIO.cs",
    "content": "using System;\nusing System.IO;\n\nnamespace LanguageExt.Sys.Traits;\n\npublic interface DirectoryIO\n{\n    /// <summary>\n    /// Create a directory\n    /// </summary>\n    IO<DirectoryInfo> Create(string path);\n\n    /// <summary>\n    /// Delete a directory\n    /// </summary>\n    IO<Unit> Delete(string path, bool recursive = true);\n        \n    /// <summary>\n    /// Get parent directory\n    /// </summary>\n    IO<Option<DirectoryInfo>> GetParent(string path);\n\n    /// <summary>\n    /// Check if directory exists\n    /// </summary>\n    IO<bool> Exists(string path);\n        \n    /// <summary>\n    /// Set the directory creation time\n    /// </summary>\n    IO<Unit> SetCreationTime(string path, DateTime creationTime);\n\n    /// <summary>\n    /// Set the directory creation time\n    /// </summary>\n    IO<Unit> SetCreationTimeUtc(string path, DateTime creationTimeUtc);\n\n    /// <summary>\n    /// Get the directory creation time\n    /// </summary>\n    IO<DateTime> GetCreationTime(string path);\n\n    /// <summary>\n    /// Get the directory creation time\n    /// </summary>\n    IO<DateTime> GetCreationTimeUtc(string path);\n        \n    /// <summary>\n    /// Set the directory last write time\n    /// </summary>\n    IO<Unit> SetLastWriteTime(string path, DateTime lastWriteTime);\n\n    /// <summary>\n    /// Set the directory last write time\n    /// </summary>\n    IO<Unit> SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc);\n        \n    /// <summary>\n    /// Get the directory last write time\n    /// </summary>\n    IO<DateTime> GetLastWriteTime(string path);\n        \n    /// <summary>\n    /// Get the directory last write time\n    /// </summary>\n    IO<DateTime> GetLastWriteTimeUtc(string path);\n\n    /// <summary>\n    /// Set the directory last access time\n    /// </summary>\n    IO<Unit> SetLastAccessTime(string path, DateTime lastAccessTime);\n\n    /// <summary>\n    /// Set the directory last access time\n    /// </summary>\n    IO<Unit> SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc);\n        \n    /// <summary>\n    /// Get the directory last access time\n    /// </summary>\n    IO<DateTime> GetLastAccessTime(string path);\n        \n    /// <summary>\n    /// Get the directory last access time\n    /// </summary>\n    IO<DateTime> GetLastAccessTimeUtc(string path);\n\n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    IO<Seq<string>> EnumerateDirectories(string path);\n        \n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    IO<Seq<string>> EnumerateDirectories(string path, string searchPattern);\n        \n    /// <summary>\n    /// Enumerate directories\n    /// </summary>\n    IO<Seq<string>> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption);\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    IO<Seq<string>> EnumerateFiles(string path);\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    IO<Seq<string>> EnumerateFiles(string path, string searchPattern);\n        \n    /// <summary>\n    /// Enumerate files\n    /// </summary>\n    IO<Seq<string>> EnumerateFiles(string path, string searchPattern, SearchOption searchOption);\n        \n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    IO<Seq<string>> EnumerateFileSystemEntries(string path);\n        \n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    IO<Seq<string>> EnumerateFileSystemEntries(string path, string searchPattern);\n        \n    /// <summary>\n    /// Enumerate file system entries\n    /// </summary>\n    IO<Seq<string>> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption);\n        \n    /// <summary>\n    /// Get the root of the path provided\n    /// </summary>\n    IO<string> GetDirectoryRoot(string path);\n        \n    /// <summary>\n    /// Get the current directory\n    /// </summary>\n    IO<string> GetCurrentDirectory();\n\n    /// <summary>\n    /// Set the current directory\n    /// </summary>\n    /// <param name=\"path\"></param>\n    IO<Unit> SetCurrentDirectory(string path);\n        \n    /// <summary>\n    /// Move a directory\n    /// </summary>\n    IO<Unit> Move(string sourceDirName, string destDirName);\n        \n    /// <summary>\n    /// Get the logical drives\n    /// </summary>\n    IO<Seq<string>> GetLogicalDrives();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/EncodingIO.cs",
    "content": "using System.Text;\n\nnamespace LanguageExt.Sys.Traits;\n\npublic interface EncodingIO\n{\n    IO<Encoding> Encoding { get; } \n}\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/EnvironmentIO.cs",
    "content": "using System;\n\nnamespace LanguageExt.Sys.Traits;\n\npublic interface EnvironmentIO\n{\n    IO<string> CommandLine();\n    IO<int> CurrentManagedThreadId();\n    IO<Unit> Exit(int exitCode);\n    IO<int> ExitCode();\n    IO<Unit> SetExitCode(int exitCode);\n    IO<string> ExpandEnvironmentVariables(string name);\n    IO<Unit> FailFast(Option<string> message);\n    IO<Unit> FailFast(Option<string> message, Option<Exception> exception);\n    IO<Seq<string>> GetCommandLineArgs();\n    IO<Option<string>> GetEnvironmentVariable(string variable);\n    IO<Option<string>> GetEnvironmentVariable(string variable, EnvironmentVariableTarget target);\n    IO<HashMap<string, Option<string>>> GetEnvironmentVariables();\n    IO<HashMap<string, Option<string>>> GetEnvironmentVariables(EnvironmentVariableTarget target);\n    IO<string> GetFolderPath(Environment.SpecialFolder folder);\n    IO<string> GetFolderPath(Environment.SpecialFolder folder, Environment.SpecialFolderOption option);\n    IO<Seq<string>> GetLogicalDrives();\n    IO<bool> HasShutdownStarted();\n    IO<bool> Is64BitOperatingSystem();\n    IO<bool> Is64BitProcess();\n    IO<string> MachineName();\n    IO<string> NewLine();\n    IO<OperatingSystem> OSVersion();\n    IO<int> ProcessorCount();\n    IO<Unit> SetEnvironmentVariable(string variable, Option<string> value);\n    IO<Unit> SetEnvironmentVariable(string variable, Option<string> value, EnvironmentVariableTarget target);\n    IO<string> StackTrace();\n    IO<string> SystemDirectory();\n    IO<int> SystemPageSize();\n    IO<long> TickCount();\n    IO<string> UserDomainName();\n    IO<bool> UserInteractive();\n    IO<string> UserName();\n    IO<Version> Version();\n    IO<long> WorkingSet();\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/FileIO.cs",
    "content": "using System.Collections.Generic;\nusing System.IO;\nusing System.Text;\n\nnamespace LanguageExt.Sys.Traits;\n\npublic interface FileIO\n{\n    /// <summary>\n    /// Copy file from one place to another\n    /// </summary>\n    IO<Unit> Copy(string fromPath, string toPath, bool overwrite = false);\n    \n    /// <summary>\n    /// Move file from one place to another\n    /// </summary>\n    IO<Unit> Move(string fromPath, string toPath);\n    \n    /// <summary>\n    /// Move file from one place to another\n    /// </summary>\n    IO<Unit> Move(string fromPath, string toPath, bool overwrite);\n\n    /// <summary>\n    /// Append lines to the end of a file\n    /// </summary>\n    IO<Unit> AppendAllLines(string path, IEnumerable<string> lines, Encoding encoding);\n        \n    /// <summary>\n    /// Read all lines from a file\n    /// </summary>\n    IO<Seq<string>> ReadAllLines(string path, Encoding encoding);\n        \n    /// <summary>\n    /// Read text from a file\n    /// </summary>\n    IO<string> ReadAllText(string path, Encoding encoding);\n        \n    /// <summary>\n    /// Read text from a file\n    /// </summary>\n    IO<byte[]> ReadAllBytes(string path);\n\n    /// <summary>\n    /// Write text to a file\n    /// </summary>\n    IO<Unit> WriteAllText(string path, string lines, Encoding encoding);\n\n    /// <summary>\n    /// Write all lines to a file\n    /// </summary>\n    IO<Unit> WriteAllLines(string path, IEnumerable<string> lines, Encoding encoding);\n\n    /// <summary>\n    /// Write text to a file\n    /// </summary>\n    IO<Unit> WriteAllBytes(string path, byte[] data);\n        \n    /// <summary>\n    /// Delete a file\n    /// </summary>\n    IO<Unit> Delete(string path);\n        \n    /// <summary>\n    /// True if a file at the path exists\n    /// </summary>\n    IO<bool> Exists(string path);\n\n    /// <summary>\n    /// Open a text file\n    /// </summary>\n    IO<TextReader> OpenText(string path);\n\n    /// <summary>\n    /// Create a new text file to stream to\n    /// </summary>\n    IO<TextWriter> CreateText(string path);\n\n    /// <summary>\n    /// Return a stream to append text to\n    /// </summary>\n    IO<TextWriter> AppendText(string path);\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    IO<System.IO.Stream> OpenRead(string path);\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    IO<System.IO.Stream> Open(string path, FileMode mode);\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    IO<System.IO.Stream> Open(string path, FileMode mode, FileAccess access);\n\n    /// <summary>\n    /// Open a file-stream\n    /// </summary>\n    IO<System.IO.Stream> OpenWrite(string path);\n}\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/SysIO.cs",
    "content": "using LanguageExt.Traits;\n\nnamespace LanguageExt.Sys.Traits;\n\n/// <summary>\n/// Convenience trait - captures the BCL IO behaviour\n/// </summary>\n/// <typeparam name=\"M\">Monad and reader trait</typeparam>\npublic interface HasSys<in M> : \n    Has<M, ActivitySourceIO>, \n    Has<M, ConsoleIO>, \n    Has<M, FileIO>, \n    Has<M, DirectoryIO>, \n    Has<M, TextReadIO>, \n    Has<M, TimeIO>;\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/TextReadIO.cs",
    "content": "using System;\nusing System.IO;\n\nnamespace LanguageExt.Sys.Traits;\n\npublic interface TextReadIO\n{\n    /// <summary>\n    /// Read a line of text from the stream\n    /// </summary>\n    IO<Option<string>> ReadLine(TextReader reader);\n        \n    /// <summary>\n    /// Read the rest of the text in the stream\n    /// </summary>\n    IO<string> ReadToEnd(TextReader reader);        \n        \n    /// <summary>\n    /// Read chars from the stream into the buffer\n    /// Returns the number of chars read\n    /// </summary>\n    IO<int> Read(TextReader reader, Memory<char> buffer);        \n        \n    /// <summary>\n    /// Close the reader\n    /// </summary>\n    IO<Unit> Close(TextReader reader);        \n}\n"
  },
  {
    "path": "LanguageExt.Sys/Traits/TimeIO.cs",
    "content": "using System;\n\nnamespace LanguageExt.Sys.Traits;\n\npublic interface TimeIO\n{\n    /// <summary>\n    /// Current local date time\n    /// </summary>\n    IO<DateTime> Now { get; }\n        \n    /// <summary>\n    /// Current universal date time\n    /// </summary>\n    IO<DateTime> UtcNow { get; }\n        \n    /// <summary>\n    /// Today's date \n    /// </summary>\n    IO<DateTime> Today { get; }\n        \n    /// <summary>\n    /// Pause a task until a specified time\n    /// </summary>\n    IO<Unit> SleepUntil(DateTime dt);\n        \n    /// <summary>\n    /// Pause a task until for a specified length of time\n    /// </summary>\n    IO<Unit> SleepFor(TimeSpan ts);\n}\n"
  },
  {
    "path": "LanguageExt.Tests/AffTests.cs",
    "content": "using Xunit;\nusing System;\nusing LanguageExt;\nusing LanguageExt.Common;\nusing System.Threading.Tasks;\nusing static LanguageExt.Prelude;\n\nnamespace EffTests;\n\npublic class EffMapFailTests\n{\n    [Fact] // Fails\n    public void Eff_WithFailingTaskInEff_EndsWithMapFailValue()\n    {\n        // Arrange\n        var affWithException       = liftEff(async () => await FailingTask());\n        var affWithMappedFailState = affWithException.MapFail(error => Error.New(error.Message + \"MapFail Eff\"));\n\n        // Act\n        var fin    = affWithMappedFailState.Run();\n        var result = fin.Match(_ => \"Success!\", error => error.Message);\n\n        // Assert\n        Assert.True(result.IndexOf(\"MapFail Eff\", StringComparison.Ordinal) > 0); \n    }\n\n    [Fact] // Fails\n    public void Eff_WithExceptionInEff_EndsWithMapFailValue()\n    {\n        // Arrange\n        var affWithException       = lift(() => throw new Exception()).ToEff();\n        var affWithMappedFailState = affWithException.MapFail(error => Error.New(error.Message + \"MapFail Eff\"));\n\n        // Act\n        var fin    = affWithMappedFailState.Run();\n        var result = fin.Match(_ => \"Success!\", error => error.Message);\n\n        // Assert\n        Assert.True(result.IndexOf(\"MapFail Eff\", StringComparison.Ordinal) > 0); \n    }\n\n    [Fact] // Fails\n    public void Eff_FailingTaskToEff_EndsWithMapFailValue()\n    {\n        // Arrange\n        var affWithException       = liftEff(async () => await FailingTask());\n        var affWithMappedFailState = affWithException.MapFail(error => Error.New(error.Message + \"MapFail Eff\"));\n\n        // Act\n        var fin    = affWithMappedFailState.Run();\n        var result = fin.Match(_ => \"Success!\", error => error.Message);\n\n        // Assert\n        Assert.True(result.IndexOf(\"MapFail Eff\", StringComparison.Ordinal) > 0); \n    }\n\n    [Fact] // Succeeds\n    public void EffToEff_WithExceptionInEff_EndsWithMapFailValue()\n    {\n        // Arrange\n        var effWithException       = lift<Unit>(() => throw new Exception(\"Error!\")).ToEff();\n        var effWithMappedFailState = effWithException.MapFail(error => Error.New(error.Message + \"MapFail Eff\"));\n\n        // Act\n        var fin    = effWithMappedFailState.Run();\n        var result = fin.Match(_ => \"Success!\", error => error.Message);\n\n        // Assert\n        Assert.True(result.IndexOf(\"MapFail Eff\", StringComparison.Ordinal) > 0); \n    }\n\n    static async Task<Unit> FailingTask()\n    {\n        await Task.Delay(1);\n        throw new Exception(\"Error!\");\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ArrayTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing System.Linq;\nusing static LanguageExt.List;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class ArrayTests\n{\n    [Fact]\n    public void ConsTest1()\n    {\n        var test = 1.Cons(2.Cons(3.Cons(4.Cons(empty<int>()))));\n\n        var array = test.ToArray();\n\n        Assert.True(array[0] == 1);\n        Assert.True(array[1] == 2);\n        Assert.True(array[2] == 3);\n        Assert.True(array[3] == 4);\n    }\n\n    [Fact]\n    public void ListConstruct()\n    {\n        var test = Array(1, 2, 3, 4, 5);\n\n        var array = test.ToArray();\n\n        Assert.True(array[0] == 1);\n        Assert.True(array[1] == 2);\n        Assert.True(array[2] == 3);\n        Assert.True(array[3] == 4);\n        Assert.True(array[4] == 5);\n    }\n\n    [Fact]\n    public void MapTestFluent()\n    {\n        var res = Array(1, 2, 3, 4, 5)\n                 .Map(x => x * 10)\n                 .Filter(x => x > 20)\n                 .Fold(0, (x, s) => s + x);\n\n        Assert.True(res == 120);\n    }\n\n    [Fact]\n    public void ReduceTestFluent()\n    {\n        var res = Array(1, 2, 3, 4, 5)\n                 .Map(x => x * 10)\n                 .Filter(x => x > 20)\n                 .Reduce((x, s) => s + x);\n\n        Assert.True(res == 120);\n    }\n\n    [Fact]\n    public void ReverseListTest1()\n    {\n        var list = Array(1, 2, 3, 4, 5);\n        var rev  = list.Reverse();\n\n        Assert.True(rev[0] == 5);\n        Assert.True(rev[4] == 1);\n    }\n\n    [Fact]\n    public void ReverseListTest2()\n    {\n        var list = Array(1, 2, 3, 4, 5);\n        var rev  = list.Reverse();\n\n        Assert.True(rev.IndexOf(1) == 4, \"Should have been 4, actually is: \" + rev.IndexOf(1));\n        Assert.True(rev.IndexOf(5) == 0, \"Should have been 0, actually is: \" + rev.IndexOf(5));\n    }\n\n    [Fact]\n    public void ReverseListTest3()\n    {\n        var list = Array(1, 1, 2, 2, 2);\n        var rev  = list.Reverse();\n\n        Assert.True(rev.LastIndexOf(1) == 4, \"Should have been 4, actually is: \" + rev.LastIndexOf(1));\n        Assert.True(rev.LastIndexOf(2) == 2, \"Should have been 2, actually is: \" + rev.LastIndexOf(5));\n    }\n\n    [Fact]\n    public void OpEqualTest()\n    {\n        var goodOnes = Array(\n            (List(1, 2, 3), List(1, 2, 3)),\n            (Lst<int>.Empty, Lst<int>.Empty)\n        );\n        var badOnes = Array(\n            (List(1, 2, 3), List(1, 2, 4)),\n            (List(1, 2, 3), Lst<int>.Empty)\n        );\n\n        goodOnes.Iter(t => t.Iter((fst, snd) =>\n                                  {\n                                      Assert.True(fst  == snd, $\"'{fst}' == '{snd}'\");\n                                      Assert.False(fst != snd, $\"'{fst}' != '{snd}'\");\n                                  }));\n\n        badOnes.Iter(t => t.Iter((fst, snd) =>\n                                 {\n                                     Assert.True(fst  != snd, $\"'{fst}' != '{snd}'\");\n                                     Assert.False(fst == snd, $\"'{fst}' == '{snd}'\");\n                                 }));\n    }\n\n\n    [Fact]\n    public void ArrShouldNotStackOverflowOnEquals()\n    {\n        var arr = default(Arr<Arr<double>>);\n        Assert.True(arr.Equals(arr));\n    }\n\n    [Fact]\n    public void EqualsTest()\n    {\n        Assert.False(Array(1, 2, 3).Equals(Array<int>()));\n        Assert.False(Array<int>().Equals(Array(1, 2, 3)));\n        Assert.True(Array<int>().Equals(Array<int>()));\n        Assert.True(Array(1).Equals(Array(1)));\n        Assert.True(Array(1, 2).Equals(Array(1, 2)));\n        Assert.False(Array(1, 2).Equals(Array(1, 2, 3)));\n        Assert.False(Array(1, 2, 3).Equals(Array(1, 2)));\n    }\n\n\n    [Fact]\n    public void itemLensGetShouldGetExistingValue()\n    {\n        var expected = \"3\";\n        var array    = Array(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\");\n        var actual   = Arr<string>.item(3).Get(array);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void itemLensGetShouldThrowExceptionForNonExistingValue()\n    {\n        Assert.Throws<IndexOutOfRangeException>(() =>\n                                                {\n                                                    var array  = Array(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\");\n                                                    var actual = Arr<string>.item(10).Get(array);\n                                                });\n    }\n\n    [Fact]\n    public void itemOrNoneLensGetShouldGetExistingValue()\n    {\n        var expected = \"3\";\n        var array    = Array(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\");\n        var actual   = Arr<string>.itemOrNone(3).Get(array);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void itemOrNoneLensGetShouldReturnNoneForNonExistingValue()\n    {\n        var expected = Option<string>.None;\n        var array    = Array(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\");\n        var actual   = Arr<string>.itemOrNone(10).Get(array);\n\n        Assert.Equal(expected, actual);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/AtomHashMapEqTests.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing Xunit;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests;\n\npublic class AtomHashMapEqTests\n{\n    [Fact]\n    public void SwapInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Swap(m => m.Add(\"biz\", 99));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.True(HashMap<TString, string, Change<int>>((\"biz\", Change<int>.Added(99))) == state.Changes);\n    }\n\n    [Fact]\n    public void SwapKeyInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SwapKey(\"foo\", i => i + 1);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>((\"foo\", Change<int>.Mapped(3, 4))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SwapKeyOptionalInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SwapKey(\"foo\", i => None);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>((\"foo\", Change<int>.Removed(3))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FilterInPlaceInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FilterInPlace(i => i % 2 == 0);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FilterInPlaceWithKeyInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FilterInPlace((k, i) => k[0] == 'b' && i % 2 == 0);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void MapInPlaceInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.MapInPlace(i => i * 3);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Mapped(3, 9)),\n                (\"bar\", Change<int>.Mapped(42, 126)),\n                (\"biz\", Change<int>.Mapped(7, 21))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AddInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Add(\"biz\", 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TryAddInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TryAdd(\"biz\", 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(HashMap<TString, string, Change<int>>((\"biz\", Change<int>.Added(7))), state.Changes);\n    }\n\n    [Fact]\n    public void AddOrUpdateInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.AddOrUpdate(\"biz\", 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AddRangeInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.AddRange(Seq((\"biz\", 7), (\"baz\", 9)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TryAddRangeInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TryAddRange(Seq((\"biz\", 7), (\"baz\", 9)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AddOrUpdateRangeInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.AddOrUpdateRange(Seq((\"biz\", 7), (\"baz\", 9)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void RemoveInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Remove(\"bar\");\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"bar\", Change<int>.Removed(42))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void RemoveRangeInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.RemoveRange(Seq(\"bar\", \"biz\"));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"bar\", Change<int>.Removed(42)),\n                (\"biz\", Change<int>.Removed(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FindOrAddInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FindOrAdd(\"biz\", () => 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FindOrAddConstantInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FindOrAdd(\"biz\", 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FindOrMaybeAddInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FindOrMaybeAdd(\"biz\", () => Some(7));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FindOrMaybeAddConstantInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FindOrMaybeAdd(\"biz\", Some(7));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SetItemsInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SetItems(Seq((\"foo\", 80), (\"bar\", 17)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Mapped(3, 80)),\n                (\"bar\", Change<int>.Mapped(42, 17))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TrySetItemsInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TrySetItems(Seq((\"foo\", 80), (\"bar\", 17), (\"biz\", 33)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Mapped(3, 80)),\n                (\"bar\", Change<int>.Mapped(42, 17))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SetItemFuncInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SetItem(\"foo\", i => i * 2);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Mapped(3, 6))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TrySetItemInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TrySetItem(\"foo\", 80);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Mapped(3, 80))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TrySetItemFuncInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TrySetItem(\"foo\", i => i * 2);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Mapped(3, 6))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void ClearInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Clear();\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"bar\", Change<int>.Removed(42))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AppendInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var                                toAppend = HashMap<TString, string, int>((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Append(toAppend);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(initialValue.Combine(toAppend), hashMap.ToHashMap());\n        Assert.True(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7)), \n                (\"baz\", Change<int>.Added(9))) == state.Changes);\n            \n    }\n\n    [Fact]\n    public void AppendAtomInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>((\"foo\", 3), (\"bar\", 42));\n        var toAppend = AtomHashMap<TString, string, int>((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Append(toAppend);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Combine(toAppend.ToHashMap()),\n            hashMap.ToHashMap());\n        Assert.True(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7)), \n                (\"baz\", Change<int>.Added(9))) == state.Changes);\n    }\n\n    [Fact]\n    public void SubtractInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var toSubtract = HashMap<TString, string, int>(\n            (\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Subtract(toSubtract);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Subtract(toSubtract),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7)),\n                (\"baz\", Change<int>.Removed(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SubtractAtomInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var toSubtract = AtomHashMap<TString, string, int>(\n            (\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Subtract(toSubtract);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Subtract(toSubtract.ToHashMap()),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7)),\n                (\"baz\", Change<int>.Removed(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void IntersectInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var toIntersect = HashMap(\n            (\"foo\", 7), (\"biz\", 7), (\"baz\", 9), (\"bin\", 0));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Intersect(toIntersect);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Intersect(toIntersect),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"bar\", Change<int>.Removed(42))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void IntersectAtomInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var toIntersect = AtomHashMap<TString, string, int>(\n            (\"foo\", 7), (\"biz\", 7), (\"baz\", 9), (\"bin\", 0));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Intersect(toIntersect);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Intersect(toIntersect.ToHashMap()),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"bar\", Change<int>.Removed(42))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void ExceptInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var toExcept = HashMap(\n            (\"foo\", 7), (\"biz\", 7), (\"baz\", 9), (\"bin\", 0));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Except(toExcept);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Except(toExcept),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7)),\n                (\"baz\", Change<int>.Removed(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void ExceptKeysInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var                                toExcept     = Seq(\"biz\", \"baz\");\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Except(toExcept);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Except(toExcept),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Removed(7)),\n                (\"baz\", Change<int>.Removed(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SymmetricExceptInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"bar\", 42));\n        var toExcept = AtomHashMap<TString, string, int>(\n            (\"foo\", 3), (\"biz\", 7), (\"baz\", 9));\n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SymmetricExcept(toExcept);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.SymmetricExcept(toExcept),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void UnionInvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>((\"foo\", 3), (\"bar\", 42));\n        var toUnion = AtomHashMap<TString, string, int>((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n            \n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Union(toUnion);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Union(toUnion),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n        \n    [Fact]\n    public void Union_TakeRight_InvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>((\"foo\", 3), (\"bar\", 42));\n        var toUnion = AtomHashMap<TString, string, int>((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n            \n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Union(toUnion, Merge: (_, _, r) => r);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Union(toUnion, Merge: (_, _, r) => r),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"foo\", Change<int>.Mapped(3, 7)),\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n        \n    [Fact]\n    public void Union_TakeLeft_InvokesChange()\n    {\n        var hashMap = AtomHashMap<TString, string, int>((\"foo\", 3), (\"bar\", 42));\n        var toUnion = AtomHashMap<TString, string, int>((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n            \n        var                                initialValue = hashMap.ToHashMap();\n        HashMapPatch<TString, string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Union(toUnion, Merge: (_, l, _) => l);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Union(toUnion, Merge: (_, l, _) => l),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap<TString, string, Change<int>>(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/AtomHashMapTests.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class AtomHashMapTests\n{\n    [Fact]\n    public void SwapInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Swap(m => m.Add(\"biz\", 99));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap((\"biz\", Change<int>.Added(99))), state.Changes);\n    }\n\n    [Fact]\n    public void SwapKeyInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SwapKey(\"foo\", i => i + 1);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap((\"foo\", Change<int>.Mapped(3, 4))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SwapKeyOptionalInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SwapKey(\"foo\", i => None);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap((\"foo\", Change<int>.Removed(3))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FilterInPlaceInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42), (\"biz\", 7));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FilterInPlace(i => i % 2 == 0);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FilterInPlaceWithKeyInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42), (\"biz\", 7));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FilterInPlace((k, i) => k[0] == 'b' && i % 2 == 0);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void MapInPlaceInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42), (\"biz\", 7));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.MapInPlace(i => i * 3);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Mapped(3, 9)),\n                (\"bar\", Change<int>.Mapped(42, 126)),\n                (\"biz\", Change<int>.Mapped(7, 21))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AddInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Add(\"biz\", 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TryAddInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TryAdd(\"biz\", 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AddOrUpdateInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.AddOrUpdate(\"biz\", 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AddRangeInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.AddRange(Seq((\"biz\", 7), (\"baz\", 9)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TryAddRangeInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TryAddRange(Seq((\"biz\", 7), (\"baz\", 9)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AddOrUpdateRangeInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.AddOrUpdateRange(Seq((\"biz\", 7), (\"baz\", 9)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void RemoveInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Remove(\"bar\");\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"bar\", Change<int>.Removed(42))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void RemoveRangeInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42), (\"biz\", 7));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.RemoveRange(Seq(\"bar\", \"biz\"));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"bar\", Change<int>.Removed(42)),\n                (\"biz\", Change<int>.Removed(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FindOrAddInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FindOrAdd(\"biz\", () => 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FindOrAddConstantInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FindOrAdd(\"biz\", 7);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FindOrMaybeAddInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FindOrMaybeAdd(\"biz\", () => Some(7));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void FindOrMaybeAddConstantInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.FindOrMaybeAdd(\"biz\", Some(7));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SetItemsInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SetItems(Seq((\"foo\", 80), (\"bar\", 17)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Mapped(3, 80)),\n                (\"bar\", Change<int>.Mapped(42, 17))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TrySetItemsInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TrySetItems(Seq((\"foo\", 80), (\"bar\", 17), (\"biz\", 33)));\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Mapped(3, 80)),\n                (\"bar\", Change<int>.Mapped(42, 17))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SetItemFuncInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SetItem(\"foo\", i => i * 2);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Mapped(3, 6))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TrySetItemInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TrySetItem(\"foo\", 80);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Mapped(3, 80))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void TrySetItemFuncInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.TrySetItem(\"foo\", i => i * 2);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Mapped(3, 6))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void ClearInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Clear();\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"bar\", Change<int>.Removed(42))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AppendInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       toAppend     = HashMap((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Append(toAppend);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(initialValue.Combine(toAppend), hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void AppendAtomInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       toAppend     = AtomHashMap((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Append(toAppend);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Combine(toAppend.ToHashMap()),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SubtractInvokesChange()\n    {\n        var hashMap = AtomHashMap(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var                       toSubtract   = HashMap((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Subtract(toSubtract);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Subtract(toSubtract),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7)),\n                (\"baz\", Change<int>.Removed(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SubtractAtomInvokesChange()\n    {\n        var hashMap = AtomHashMap(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var                       toSubtract   = AtomHashMap((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Subtract(toSubtract);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Subtract(toSubtract.ToHashMap()),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7)),\n                (\"baz\", Change<int>.Removed(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void IntersectInvokesChange()\n    {\n        var hashMap = AtomHashMap(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var toIntersect = HashMap(\n            (\"foo\", 7), (\"biz\", 7), (\"baz\", 9), (\"bin\", 0));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Intersect(toIntersect);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Intersect(toIntersect),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"bar\", Change<int>.Removed(42))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void IntersectAtomInvokesChange()\n    {\n        var hashMap = AtomHashMap(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var toIntersect = AtomHashMap(\n            (\"foo\", 7), (\"biz\", 7), (\"baz\", 9), (\"bin\", 0));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Intersect(toIntersect);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Intersect(toIntersect.ToHashMap()),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"bar\", Change<int>.Removed(42))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void ExceptInvokesChange()\n    {\n        var hashMap = AtomHashMap(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var toExcept = HashMap(\n            (\"foo\", 7), (\"biz\", 7), (\"baz\", 9), (\"bin\", 0));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Except(toExcept);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Except(toExcept),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Removed(7)),\n                (\"baz\", Change<int>.Removed(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void ExceptKeysInvokesChange()\n    {\n        var hashMap = AtomHashMap(\n            (\"foo\", 3), (\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var                       toExcept     = Seq(\"biz\", \"baz\");\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Except(toExcept);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Except(toExcept),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Removed(7)),\n                (\"baz\", Change<int>.Removed(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void SymmetricExceptInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       toExcept     = AtomHashMap((\"foo\", 3), (\"biz\", 7), (\"baz\", 9));\n        var                       expected     = HashMap((\"bar\", 42), (\"biz\", 7), (\"baz\", 9));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.SymmetricExcept(toExcept);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), expected);\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Removed(3)),\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n\n    [Fact]\n    public void UnionInvokesChange()\n    {\n        var                       hashMap      = AtomHashMap((\"foo\", 3), (\"bar\", 42));\n        var                       toUnion      = AtomHashMap((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Union(toUnion);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Union(toUnion),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n        \n    [Fact]\n    public void Union_TakeRight_InvokesChange()\n    {\n        var hashMap = AtomHashMap<string, int>((\"foo\", 3), (\"bar\", 42));\n        var toUnion = AtomHashMap<string, int>((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n            \n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Union(toUnion, Merge: (_, _, r) => r);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Union(toUnion, Merge: (_, _, r) => r),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"foo\", Change<int>.Mapped(3, 7)),\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n        \n    [Fact]\n    public void Union_TakeLeft_InvokesChange()\n    {\n        var hashMap = AtomHashMap<string, int>((\"foo\", 3), (\"bar\", 42));\n        var toUnion = AtomHashMap<string, int>((\"foo\", 7), (\"biz\", 7), (\"baz\", 9));\n            \n        var                       initialValue = hashMap.ToHashMap();\n        HashMapPatch<string, int> state        = default;\n        hashMap.Change += v => state = v;\n\n        hashMap.Union(toUnion, Merge: (_, l, _) => l);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(\n            initialValue.Union(toUnion, Merge: (_, l, _) => l),\n            hashMap.ToHashMap());\n        Assert.Equal(\n            HashMap(\n                (\"biz\", Change<int>.Added(7)),\n                (\"baz\", Change<int>.Added(9))),\n            state.Changes);\n    }\n    \n    [Theory]\n    [InlineData(-2)]\n    [InlineData(0b10000011001)]\n    [InlineData(0b1001100111001)]\n    [InlineData(0b1001110000010)]\n    [InlineData(4114)]\n    public void AppendInvokesChangeInt(int conflictKey)\n    {\n        var                    hashMap      = AtomHashMap((conflictKey, 3), (2, 42));\n        var                    toAppend     = HashMap((conflictKey, 6), (5, 7), (25, 9));\n        var                    initialValue = hashMap.ToHashMap();\n        HashMapPatch<int, int> state        = default!;\n        hashMap.Change += v => state = v;\n\n        hashMap.Append(toAppend);\n\n        Assert.Equal(initialValue, state.From);\n        Assert.Equal(hashMap.ToHashMap(), state.To);\n        Assert.Equal(initialValue.Combine(toAppend), hashMap.ToHashMap());\n        Assert.Equal(3, hashMap[conflictKey]);\n        Assert.Equal(\n            HashMap(\n                (5, Change<int>.Added(7)),\n                (25, Change<int>.Added(9))),\n            state.Changes);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/AtomTests.cs",
    "content": "﻿using System.Linq;\nusing static LanguageExt.Prelude;\nusing Xunit;\nusing System.Diagnostics;\n\nnamespace LanguageExt.Tests;\n\npublic class AtomTests\n{\n    [Fact]\n    public void ConstructAndSwap()\n    {\n        var atom = Atom(Set(\"A\", \"B\", \"C\"));\n\n        atom.Swap(old => old.Add(\"D\"));\n        atom.Swap(old => old.Add(\"E\"));\n        atom.Swap(old => old.Add(\"F\"));\n\n        Debug.Assert(atom == Set(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"));\n    }\n    [Fact]\n    public void AtomSeqEnumeration()\n    {\n        var xs   = Seq(1,2,3,4);\n        var atom = AtomSeq(xs);\n            \n        Assert.Equal(atom.Sum(), xs.Sum());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ChoiceTests.cs",
    "content": "﻿using System;\nusing static LanguageExt.Prelude;\nusing Xunit;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests;\n\npublic class ChoiceTests\n{\n    [Fact]\n    public async Task TaskFirstChoice()\n    {\n        var ma = 123.AsTask();\n        var mb = new Exception().AsFailedTask<int>();\n        var mc = new Exception().AsFailedTask<int>();\n\n        var res = choice(ma, mb, mc);\n\n        Assert.True(await res == 123);\n    }\n\n    [Fact]\n    public async Task TaskMiddleChoice()\n    {\n        var ma = new Exception().AsFailedTask<int>();\n        var mb = 123.AsTask();\n        var mc = new Exception().AsFailedTask<int>();\n\n        var res = choice(ma, mb, mc);\n\n        Assert.True(await res == 123);\n    }\n\n    [Fact]\n    public async Task TaskLastChoice()\n    {\n        var ma = new Exception().AsFailedTask<int>();\n        var mb = new Exception().AsFailedTask<int>();\n        var mc = 123.AsTask();\n\n        var res = choice(ma, mb, mc);\n\n        Assert.True(await res == 123);\n    }\n\n    [Fact]\n    public async Task TaskNoChoice()\n    {\n        var ma = new Exception().AsFailedTask<int>();\n        var mb = new Exception().AsFailedTask<int>();\n        var mc = new Exception().AsFailedTask<int>();\n\n        var res = choice(ma, mb, mc);\n\n        await Assert.ThrowsAsync<BottomException>(async () => await res);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/CollectionOrderingTests.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class CollectionOrderingTests\n{\n    [Fact]\n    public void TestSetOrdering1()\n    {\n        var x = Set(1, 2, 3, 4, 5);\n        var y = Set(1, 2, 3, 4, 5);\n\n        Assert.True(x.CompareTo(y) == 0);\n        Assert.False(x             < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestSetOrdering2()\n    {\n        var x = Set(1, 2, 3, 4, 5);\n        var y = Set(1, 2, 3, 4, 6);\n\n        Assert.True(x.CompareTo(y) < 0);\n        Assert.True(x.CompareTo(y) <= 0);\n        Assert.True(x              < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.False(x             >= y);\n    }\n\n    [Fact]\n    public void TestSetOrdering3()\n    {\n        var x = Set(1, 2, 3, 4, 6);\n        var y = Set(1, 2, 3, 4, 5);\n\n        Assert.True(x.CompareTo(y) > 0);\n        Assert.True(x.CompareTo(y) >= 0);\n        Assert.False(x             < y);\n        Assert.False(x             <= y);\n        Assert.True(x              > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestSetOrdering4()\n    {\n        var x = Set(1, 2, 3, 4, 5);\n        var y = Set(1, 2, 3, 4);\n\n        Assert.True(x.CompareTo(y) > 0);\n        Assert.True(x.CompareTo(y) >= 0);\n        Assert.False(x             < y);\n        Assert.False(x             <= y);\n        Assert.True(x              > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestSetOrdering5()\n    {\n        var x = Set(1, 2, 3, 4);\n        var y = Set(1, 2, 3, 4, 5);\n\n        Assert.True(x.CompareTo(y) < 0);\n        Assert.True(x.CompareTo(y) <= 0);\n        Assert.True(x              < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.False(x             >= y);\n    }\n\n\n    [Fact]\n    public void TestListOrdering1()\n    {\n        var x = List(1, 2, 3, 4, 5);\n        var y = List(1, 2, 3, 4, 5);\n\n        Assert.True(x.CompareTo(y) == 0);\n        Assert.False(x             < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestListOrdering2()\n    {\n        var x = List(1, 2, 3, 4, 5);\n        var y = List(1, 2, 3, 4, 6);\n\n        Assert.True(x.CompareTo(y) < 0);\n        Assert.True(x.CompareTo(y) <= 0);\n        Assert.True(x              < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.False(x             >= y);\n    }\n\n    [Fact]\n    public void TestListOrdering3()\n    {\n        var x = List(1, 2, 3, 4, 6);\n        var y = List(1, 2, 3, 4, 5);\n\n        Assert.True(x.CompareTo(y) > 0);\n        Assert.True(x.CompareTo(y) >= 0);\n        Assert.False(x             < y);\n        Assert.False(x             <= y);\n        Assert.True(x              > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestListOrdering4()\n    {\n        var x = List(1, 2, 3, 4, 5);\n        var y = List(1, 2, 3, 4);\n\n        Assert.True(x.CompareTo(y) > 0);\n        Assert.True(x.CompareTo(y) >= 0);\n        Assert.False(x             < y);\n        Assert.False(x             <= y);\n        Assert.True(x              > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestListOrdering5()\n    {\n        var x = List(1, 2, 3, 4);\n        var y = List(1, 2, 3, 4, 5);\n\n        Assert.True(x.CompareTo(y) < 0);\n        Assert.True(x.CompareTo(y) <= 0);\n        Assert.True(x              < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.False(x             >= y);\n    }\n\n\n\n    [Fact]\n    public void TestMapOrdering1()\n    {\n        var x = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'));\n        var y = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'));\n\n        Assert.True(x.CompareTo(y) == 0);\n        Assert.False(x             < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestMapOrdering2()\n    {\n        var x = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'));\n        var y = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (6, 'a'));\n\n        Assert.True(x.CompareTo(y) < 0);\n        Assert.True(x.CompareTo(y) <= 0);\n        Assert.True(x              < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.False(x             >= y);\n    }\n\n    [Fact]\n    public void TestMapOrdering3()\n    {\n        var x = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (6, 'a'));\n        var y = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'));\n\n        Assert.True(x.CompareTo(y) > 0);\n        Assert.True(x.CompareTo(y) >= 0);\n        Assert.False(x             < y);\n        Assert.False(x             <= y);\n        Assert.True(x              > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestMapOrdering4()\n    {\n        var x = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'));\n        var y = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'));\n\n        Assert.True(x.CompareTo(y) > 0);\n        Assert.True(x.CompareTo(y) >= 0);\n        Assert.False(x             < y);\n        Assert.False(x             <= y);\n        Assert.True(x              > y);\n        Assert.True(x              >= y);\n    }\n\n    [Fact]\n    public void TestMapOrdering5()\n    {\n        var x = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'));\n        var y = Map((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'));\n\n        Assert.True(x.CompareTo(y) < 0);\n        Assert.True(x.CompareTo(y) <= 0);\n        Assert.True(x              < y);\n        Assert.True(x              <= y);\n        Assert.False(x             > y);\n        Assert.False(x             >= y);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/CollectionToStringTests.cs",
    "content": "﻿using System.Linq;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class CollectionToStringTests\n{\n    readonly static int[] zeroToFour = Range(0, 5).ToArray();\n    readonly static int[] zeroToFourtyNine = Range(0, 50).ToArray();\n    readonly static int[] zeroToFiftyNine = Range(0, 60).ToArray();\n\n    readonly static string zeroToFourString = \"[0, 1, 2, 3, 4]\";\n    readonly static string zeroToFourtyNineString = \"[0, 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]\";\n    readonly static string zeroToFiftyNineString = \"[0, 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 ... 10 more]\";\n\n    readonly static (string, int)[] zeroToFourkeyValue = new[] { (\"A\", 0), (\"B\", 1), (\"C\", 2), (\"D\", 3), (\"E\", 4) };\n    readonly static string zeroToFourKeyValueString = \"[(A: 0), (B: 1), (C: 2), (D: 3), (E: 4)]\";\n\n    [Fact]\n    public void ArrShortToString()\n    {\n        var items = toArray(zeroToFour);\n        Assert.True(items.ToString() == zeroToFourString);\n    }\n\n    [Fact]\n    public void ArrMedToString()\n    {\n        var items = toArray(zeroToFourtyNine);\n        Assert.True(items.ToString() == zeroToFourtyNineString);\n    }\n\n    [Fact]\n    public void ArrLongToString()\n    {\n        var items = toArray(zeroToFiftyNine);\n        Assert.True(items.ToString() == zeroToFiftyNineString);\n    }\n\n    [Fact]\n    public void LstShortToString()\n    {\n        var items = toList(zeroToFour);\n        Assert.True(items.ToString() == zeroToFourString);\n    }\n\n    [Fact]\n    public void LstMedToString()\n    {\n        var items = toList(zeroToFourtyNine);\n        Assert.True(items.ToString() == zeroToFourtyNineString);\n    }\n\n    [Fact]\n    public void LstLongToString()\n    {\n        var items = toList(zeroToFiftyNine);\n        Assert.True(items.ToString() == zeroToFiftyNineString);\n    }\n\n    [Fact]\n    public void SeqShortToString()\n    {\n        var items = toSeq(zeroToFour);\n        Assert.True(items.ToString() == zeroToFourString);\n    }\n\n    [Fact]\n    public void SeqMedToString()\n    {\n        var items = toSeq(zeroToFourtyNine);\n        Assert.True(items.ToString() == zeroToFourtyNineString);\n    }\n\n    [Fact]\n    public void SeqLongToString()\n    {\n        var items = toSeq(zeroToFiftyNine);\n        Assert.True(items.ToString() == zeroToFiftyNineString);\n    }\n\n    [Fact]\n    public void SetShortToString()\n    {\n        var items = toSet(zeroToFour);\n        Assert.True(items.ToString() == zeroToFourString);\n    }\n\n    [Fact]\n    public void SetMedToString()\n    {\n        var items = toSet(zeroToFourtyNine);\n        Assert.True(items.ToString() == zeroToFourtyNineString);\n    }\n\n    [Fact]\n    public void SetLongToString()\n    {\n        var items = toSet(zeroToFiftyNine);\n        Assert.True(items.ToString() == zeroToFiftyNineString);\n    }\n\n    [Fact]\n    public void MapToString()\n    {\n        var items = toMap(zeroToFourkeyValue);\n        Assert.True(items.ToString() == zeroToFourKeyValueString);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/CombinatorsTests.cs",
    "content": "﻿using Xunit;\n\nusing static LanguageExt.CombinatorsDynamic;\n\nnamespace LanguageExt.Tests;\n\npublic class CombinatorsTests\n{\n    /// <summary>\n    /// Derive the Identity combinator\n    /// </summary>\n    [Fact]\n    public void DeriveIdiotBird()\n    {\n        var I = S(K)(K);\n\n        Assert.True(I(10) == 10);\n        Assert.True(I(5)  == 5);\n    }\n\n    /// <summary>\n    /// Derive the Bind combinator\n    /// </summary>\n    [Fact]\n    public void DeriveBluebird()\n    {\n        var B = S(K(S))(K);\n    }\n\n    [Fact]\n    public void DeriveCardinalBird()\n    {\n        //C = S(BBS)(KK) = S(S(KS)K(S(KS)K)S)(KK)\n\n        var B = S(K(S))(K);\n\n        var C = S(B(B)(S))(K(K));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/CompositionTests.cs",
    "content": "﻿using System;\n\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class CompositionTests\n{\n    private readonly Func<string> f;\n    private readonly Func<string, string> g;\n    private readonly Func<string, int> h;\n\n    public CompositionTests()\n    {\n        f = () => \"Bob\";\n        g = (string name) => $\"Hello, {name}\";\n        h = (string s) => s.Length;\n    }\n\n    [Fact]\n    public void Sanity()\n    {\n        string expected = \"Hello, Bob\";\n        Assert.Equal(g(f()), expected);\n        Assert.Equal(h(g(f())), expected.Length);\n    }\n\n    [Fact]\n    public void BackComposeFuncWithNoArgFunc()\n    {\n        Assert.Equal(g.BackCompose(f)(), g(f()));\n    }\n\n    [Fact]\n    public void ComposeNoArgFuncWithFunc()\n    {\n        Assert.Equal(f.Compose(g)(), g(f()));\n    }\n\n    [Fact]\n    public void BackComposeActionWithNoArgFunc()\n    {\n        string result;\n        var    g = act((string name) => { result = this.g(name); });\n\n        result = null;\n        g.BackCompose(f)();\n        Assert.Equal(result, this.g(f()));\n    }\n\n    [Fact]\n    public void ComposeNoArgFuncWithAction()\n    {\n        string result;\n        var    g = act((string name) => { result = this.g(name); });\n\n        result = null;\n        f.Compose(g)();\n        Assert.Equal(result, this.g(f()));\n    }\n\n    [Fact]\n    public void BackComposeFuncWithFunc()\n    {\n        Assert.Equal(h.BackCompose(g)(f()), h(g(f())));\n    }\n\n    [Fact]\n    public void ComposeFuncWithFunc()\n    {\n        Assert.Equal(g.Compose(h)(f()), h(g(f())));\n    }\n\n    [Fact]\n    public void BackComposeActionWithFunc()\n    {\n        int? result;\n        var  h = act((string s) => { result = this.h(s); });\n\n        result = null;\n        h.BackCompose(g)(f());\n        Assert.Equal(result, this.h(g(f())));\n    }\n\n    [Fact]\n    public void ComposeFuncWithAction()\n    {\n        int? result;\n        var  h = act((string s) => { result = this.h(s); });\n\n        result = null;\n        g.Compose(h)(f());\n        Assert.Equal(result, this.h(g(f())));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/DefaultValueChecks/AbstractDefaultValueCheckTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.DefaultValueChecks\n{\n    public abstract class AbstractDefaultValueCheckTests\n    {\n        protected abstract bool ExpectedWhenDefaultValue { get; }\n        protected abstract bool DefaultValueCheck<T>(T value);\n\n        private bool ExpectedWhenNotDefaultValue => !ExpectedWhenDefaultValue;\n\n        [Fact]\n        public void DefaultValueCheck_DefaultValueObject_AsExpectedWhenDefaultValue()\n        {\n            object value = null;\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_DefaultConstructorObject_AsExpectedWhenNotDefaultValue()\n        {\n            object value = new object();\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenNotDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_DefaultValueString_AsExpectedWhenDefaultValue()\n        {\n            string value = null;\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_HelloString_AsExpectedWhenNotDefaultValue()\n        {\n            string value = \"hello\";\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenNotDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_DefaultValueInt_AsExpectedWhenDefaultValue()\n        {\n            int value = 0;\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_NonDefaultValueInt_AsExpectedWhenNotDefaultValue()\n        {\n            int value = 100;\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenNotDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_DefaultValueNullableByte_AsExpectedWhenDefaultValue()\n        {\n            byte? value = null;\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_ZeroNullableByte_AsExpectedWhenNotDefaultValue()\n        {\n            byte? value = 0;\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenNotDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_DefaultConstructorEnum_AsExpectedWhenDefaultValue()\n        {\n            FooEnum value = new FooEnum();\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenDefaultValue, actual);\n        }\n\n        [Fact]\n        public void DefaultValueCheck_FirstEnumOptionWithValueOne_AsExpectedWhenNotDefaultValue()\n        {\n            FooEnum value = FooEnum.FooEnumState;\n            var actual = DefaultValueCheck(value);\n            Assert.Equal(ExpectedWhenNotDefaultValue, actual);\n        }\n\n        private enum FooEnum\n        {\n            FooEnumState = 1\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/DefaultValueChecks/isDefaultPreludeTests.cs",
    "content": "﻿namespace LanguageExt.Tests.DefaultValueChecks\n{\n    public class isDefaultPreludeTests : AbstractDefaultValueCheckTests\n    {\n        protected override bool ExpectedWhenDefaultValue => true;\n        protected override bool DefaultValueCheck<T>(T value) => Prelude.isDefault(value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/DefaultValueChecks/notDefaultPreludeTests.cs",
    "content": "﻿namespace LanguageExt.Tests.DefaultValueChecks\n{\n    public class notDefaultPreludeTests : AbstractDefaultValueCheckTests\n    {\n        protected override bool ExpectedWhenDefaultValue => false;\n        protected override bool DefaultValueCheck<T>(T value) => Prelude.notDefault(value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/DelayTests.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing static LanguageExt.PreludeRx;\n\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class DelayTests\n{\n    [Fact]\n    public void DelayTest1()\n    {\n        var span = TimeSpan.FromMilliseconds(500);\n        var till = DateTime.Now.Add(span);\n        var v    = 0;\n\n        delay(() => 1, span).Subscribe(x => v = x);\n\n        while( DateTime.Now < till )\n        {\n            Assert.True(v == 0);\n            Thread.Sleep(10);\n        }\n\n        while (DateTime.Now < till.AddMilliseconds(200))\n        {\n            Thread.Sleep(10);\n        }\n\n        Assert.True(v == 1);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/DistinctTests.cs",
    "content": "using Xunit;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class DistinctTests\n{\n    [Fact]\n    void SeqDistinctIgnoreCase()\n    {\n        var items = Seq(\"Test\", \"other\", \"test\");\n            \n        Assert.Equal(items, items.Distinct());\n        Assert.Equal(items.Take(3), items.Distinct(_ => _, fun<string, string, bool>(EqStringOrdinal.Equals)));\n        Assert.Equal(items.Take(2), items.Distinct(_ => _, fun<string, string, bool>(EqStringOrdinalIgnoreCase.Equals)));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Divisible.cs",
    "content": "﻿using Xunit;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\n\nnamespace LanguageExt.Tests;\n\npublic class Divisible\n{\n    [Fact]\n    public void OptionalNumericDivide()\n    {\n        var x = Some(20);\n        var y = Some(10);\n        var z = divide<TInt, int>(x, y);\n\n        Assert.True(z == 2);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/EitherApply.cs",
    "content": "﻿using System;\nusing LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class EitherApply\n{\n    Func<int, int, int> add = (a, b) => a + b;\n\n    [Fact]\n    public void ApplyRightArgs()\n    {\n        var either = Right<string, Func<int,int,int>>(add)\n                    .Apply(Right<string, int>(3))\n                    .Apply(Right<string, int>(4));\n\n        Assert.Equal(Right<string, int>(7), either);\n    }\n\n    [Fact]\n    public void ApplyRightArgsF()\n    {\n        var either = \n            apply(\n                apply(\n                    Right<string, Func<int, int, int>>(add),\n                    Right<string, int>(3)\n                ),\n                Right<string, int>(4));\n        Assert.Equal(Right<string, int>(7), either);\n    }\n\n    [Fact]\n    public void ApplyRightArgsF2()\n    {\n        var either = map(add, Right<string, int>(3)).Apply(Right<string, int>(4));\n        \n        Assert.Equal(Right<string, int>(7), either);\n    }\n\n    [Fact]\n    public void ApplyLeftArgs()\n    {\n        var opt  = Some(add);\n        var none = Option<int>.None;\n        var four = Some(4); \n\n        var res = apply(opt, none).Apply(four);\n\n        Assert.Equal(None, res);\n\n        var either = Right<string, Func<int, int, int>>(add)\n                    .Apply(Left<string, int>(\"left\"))\n                    .Apply(Right<string, int>(4));\n\n        Assert.Equal(Left<string, int>(\"left\"), either);\n    }\n\n    [Fact]\n    public void ApplyLeftArgsF()\n    {\n        var either = apply(map(add, Left<string, int>(\"left\")), Right<string, int>(4));\n        Assert.Equal(Left<string, int>(\"left\"), either);\n    }\n\n    [Fact]\n    public void ApplyLeftArgsF2()\n    {\n        var either = map(add, Left<string, int>(\"left\")).Apply(Right<string, int>(4));\n        Assert.Equal(Left<string, int>(\"left\"), either);\n    }\n\n    [Fact]\n    public void ApplicativeLawHolds()\n    {\n        var first = Right<string, Func<int, int, int>>(add)\n                        .Apply(Right<string, int>(3))\n                        .Apply(Right<string, int>(4));\n\n        var second = add.Map(Right<string, int>(3))\n                        .Apply(Right<string, int>(4));\n\n        Assert.Equal(first, second);\n    }\n\n    [Fact]\n    public void ApplicativeLawHoldsF()\n    {\n        var first = apply(map(add, Right<string, int>(3)), Right<string, int>(4));\n        var second = add.Map(Right<string, int>(3)).Apply(Right<string, int>(4));\n\n        Assert.Equal(first, second);\n    }\n\n    [Fact]\n    public void ApplicativeLawHoldsF2()\n    {\n        var first = map(add, Right<string, int>(3)).Apply(Right<string, int>(4));\n        var second = add.Map(Right<string, int>(3)).Apply(Right<string, int >(4));\n\n        Assert.Equal(first, second);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/EitherCoalesceTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class EitherCoalesceTests\n{\n    [Fact]\n    public void EitherCoalesceTest1()\n    {\n        Either<string, int> either = 123;\n\n        var value = either || 456;\n        Assert.True(value == 123);\n    }\n\n    [Fact]\n    public void EitherCoalesceTest2()\n    {\n        Either<string, int> either = \"Hello\";\n\n        var value = either || 456;\n        Assert.True(value == 456);\n    }\n\n    [Fact]\n    public void EitherCoalesceTest3()\n    {\n        Either<string, int> either1 = \"Hello\";\n        Either<string, int> either2 = \"World\";\n\n        var value = either1 || either2 || 456;\n        Assert.True(value == 456);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/EitherTests.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class EitherTests\n{\n    [Fact] public void RightGeneratorTestsObject()\n    {\n        Either<string, int> either = Right(123);\n\n        either.Match( Right: i => Assert.True(i == 123),\n                      Left:  _ => Assert.Fail(\"Shouldn't get here\") );\n\n        int c = either.Match( Right: i  => i + 1, \n                              Left: _ => 0 );\n\n        Assert.True(c == 124);\n    }\n\n    [Fact] public void SomeGeneratorTestsFunction()\n    {\n        var either = Right<string, int>(123);\n\n        either.Match(Right: i => Assert.True(i == 123),\n                     Left: _ => Assert.Fail(\"Shouldn't get here\"));\n\n        var c = either.Match(Right: i => i + 1,\n                             Left: _ => 0);\n\n        Assert.True(c == 124);\n    }\n\n    [Fact] public void LeftGeneratorTestsObject()\n    {\n        var either = ItsLeft;\n\n        either.Match( Right: r => Assert.Fail(\"Shouldn't get here\"),\n                      Left:  l => Assert.True(l == \"Left\") );\n\n        int c = either.Match( Right: r => r + 1, \n                              Left:  l => 0 );\n\n        Assert.True(c == 0);\n    }\n\n    [Fact] public void LeftGeneratorTestsFunction()\n    {\n        var either = ItsLeft;\n\n        either.Match(Right: r => Assert.Fail(\"Shouldn't get here\"),\n                     Left:  l => Assert.True(l == \"Left\") );\n\n        var c = either.Match(Right: r => r + 1,\n                             Left:  l => 0 );\n\n        Assert.True(c == 0);\n    }\n\n    [Fact]\n    public void SomeLinqTest() =>\n        (from x in Two\n         from y in Four\n         from z in Six\n         select x + y + z)\n       .Match(\n            Right: r => Assert.True(r == 12),\n            Left:  _ => Assert.Fail(\"Shouldn't get here\"));\n\n    [Fact] public void LeftLinqTest() =>\n        (from x in Two\n         from y in Four\n         from _ in ItsLeft\n         from z in Six\n         select x + y + z)\n       .Match(\n            l => Assert.True(l == \"Left\"),\n            _ => Assert.Fail(\"Shouldn't get here\"));\n\n    [Fact] public void EitherFluentSomeNoneTest()\n    {\n        int res1 = GetValue(true)\n                  .Right(r => r + 10)\n                  .Left (l => l.Length);\n\n        int res2 = GetValue(false)\n                  .Right(r => r + 10)\n                  .Left (l => l.Length);\n\n        Assert.True(res1 == 1010);\n        Assert.True(res2 == 4);\n    }\n\n    private Either<string, int> GetValue(bool select)\n    {\n        if (select)\n        {\n            return 1000;\n        }\n        else\n        {\n            return \"Left\";\n        }\n    }\n\n    [Fact]\n    public void EitherLinqTest1() =>\n        (from x in Right(2)\n         from _ in Left(\"error\")\n         from z in Right(5)\n         select x + z)\n       .Match(Right: _ => Assert.Fail(\"Shouldn't get here\"),\n              Left: _ => Assert.True(true));\n\n    [Fact]\n    public void EitherLinqTest2() =>\n        (from x in Right(2)\n         from y in Right<string, int>(123)\n         from z in Right(5)\n         select x + y + z)\n        .Match(Right: r => Assert.True(r == 130),\n               Left: _ => Assert.True(false));\n\n    [Fact]\n    public void EitherCoalesce()\n    {\n        var x = Right<string, int>(1) || Right<string, int>(2) || Left<string, int>(\"error\");\n    }\n\n    [Fact]\n    public void EitherInfer1() => \n        AddEithers(Right(10), Left(\"error\"));\n\n    void EitherInfer2(bool v)\n    {\n        Either<string, int> x =\n            v ? Right(10)\n              : Left(\"error\");\n    }\n\n    public Either<string, int> AddEithers(Either<string, int> x, Either<string, int> y) =>\n        from a in x\n        from b in y\n        select a + b;\n\n    private Either<string, int> ImplicitConversion() => 1000;\n    private Either<string, int> ItsLeft => \"Left\";\n    private Either<string, int> Two => 2;\n    private Either<string, int> Four => 4;\n    private Either<string, int> Six => 6;\n}\n"
  },
  {
    "path": "LanguageExt.Tests/EnumerableTTests.cs",
    "content": "﻿using System.Collections;\nusing System.Linq;\nusing LanguageExt.ClassInstances;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class EnumerableTTests\n{\n    [Fact]\n    public void WrappedListTest()\n    {\n        var lst = List(List(1, 2, 3, 4, 5), List(1, 2, 3, 4, 5), List(1, 2, 3, 4, 5));\n\n        var res  = lst.KindT<Lst, Lst, Lst<int>, int>().FoldT(0, (s, v) => s + v);\n        var mlst = lst.KindT<Lst, Lst, Lst<int>, int>().MapT(x => x * 2);\n        var mres = mlst.FoldT(0, (s, v) => s + v);\n\n        Assert.True(res == 45, \"Expected 45 got \" + res);\n        Assert.True(mres == 90, \"Expected 90 got \" + res);\n        Assert.True(lst.KindT<Lst, Lst, Lst<int>, int>().CountT() == 15, \"(lst) Expected 15 got \" + lst.KindT<Lst, Lst, Lst<int>, int>().CountT());\n        Assert.True(mlst.CountT() == 15, \"(mlst) Expected 15 got \" + mlst.CountT());\n\n        lst = List<Lst<int>>();\n        res = lst.KindT<Lst, Lst, Lst<int>, int>().FoldT(0, (s, v) => s + v);\n\n        Assert.True(res                                           == 0, \"Fold results, expected 0 got \" + res);\n        Assert.True(lst.KindT<Lst, Lst, Lst<int>, int>().CountT() == 0, \"Empty count, expected 0 got \"  + res);\n    }\n\n    [Fact]\n    public void ChooseTest()\n    {\n        var input = List(\n            Some(1),\n            Some(2),\n            Some(3),\n            None,\n            Some(4),\n            None,\n            Some(5));\n\n        var actual = IterableExtensions.AsIterable(input).Choose(x => x).ToList();\n\n        var expected = List(1, 2, 3, 4, 5);\n\n        var toString = fun((IEnumerable items) => string.Join(\", \", items));\n\n        Assert.True(EqEnumerable<int>.Equals(actual, expected), $\"Expected {toString(expected)} but was {toString(actual)}\");\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/EqualityTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing System.Linq;\nusing LanguageExt.Traits;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests;\n\npublic class EqualityTests\n{\n    [Fact]\n    public void EqualityTest1()\n    {\n        var optional = Some(123);\n\n        if (optional == 123)\n        {\n            Assert.True(true);\n        }\n        else\n        {\n            Assert.False(true);\n        }\n    }\n\n    [Fact]\n    public void EqualityTest2()\n    {\n        Option<int> optional = None;\n\n        if (optional == None)\n        {\n            Assert.True(true);\n        }\n        else\n        {\n            Assert.False(true);\n        }\n    }\n\n    [Fact]\n    public void EqualityTest3()\n    {\n        var optional = Some(123);\n\n        if (optional == None)\n        {\n            Assert.False(true);\n        }\n        else\n        {\n            Assert.True(true);\n        }\n    }\n\n    [Fact]\n    public void EqualityTest4()\n    {\n        Option<int> optional = None;\n\n        if (optional == Some(123))\n        {\n            Assert.False(true);\n        }\n        else\n        {\n            Assert.True(true);\n        }\n    }\n\n    [Fact]\n    public void NonEqualityTest1()\n    {\n        var optional = Some(123);\n\n        if (optional != 123)\n        {\n            Assert.False(true);\n        }\n        else\n        {\n            Assert.True(true);\n        }\n    }\n\n    [Fact]\n    public void NonEqualityTest2()\n    {\n        Option<int> optional = None;\n\n        if (optional != None)\n        {\n            Assert.False(true);\n        }\n        else\n        {\n            Assert.True(true);\n        }\n    }\n\n    /// <summary>\n    /// Test for issue #64\n    /// It just needs to complete without throwing an exception to be tested\n    /// https://github.com/louthy/language-ext/issues/64\n    /// </summary>\n    [Fact]\n    public void EitherEqualityComparerTest()\n    {\n        var results = List<Either<Exception, int>>();\n\n        var firsterror = results.FirstOrDefault(i => i.IsLeft);\n        if (IsDefault(firsterror)) // <-- here i get exception\n        {\n        }\n    }\n\n    public static bool IsDefault<T>(T obj) =>\n        EqDefault<T>.Equals(obj, default);\n\n\n    [Fact]\n    public static void OptionMonadEqualityTests1()\n    {\n        var optionx = Some(123);\n        var optiony = Some(123);\n\n        var optionr = IsEqual<EqInt, Option, int>(optionx, optiony);\n\n        Assert.True(optionr);\n        Assert.True(optionx == optiony);\n    }\n\n    [Fact]\n    public static void OptionMonadEqualityTests2()\n    {\n        var optionx = Some(\"ABC\");\n        var optiony = Some(\"abc\");\n\n        var optionr = IsEqual<EqStringCurrentCultureIgnoreCase, Option, string>(optionx, optiony);\n\n        Assert.True(optionr);\n\n        Assert.True(optionx != optiony);\n    }\n\n    [Fact]\n    public static void EitherMonadEqualityTests1()\n    {\n        var optionx = Right<Exception, int>(123);\n        var optiony = Right<Exception, int>(123);\n\n        var optionr = IsEqual<EqInt, Either<Exception>, int>(optionx, optiony);\n        Assert.True(optionr);\n\n        Assert.True(optionx == optiony);\n    }\n\n    [Fact]\n    public static void EitherMonadEqualityTests2()\n    {\n        var optionx = Right<Exception, string>(\"ABC\");\n        var optiony = Right<Exception, string>(\"abc\");\n\n        var optionr = IsEqual<EqStringCurrentCultureIgnoreCase, Either<Exception>, string>(optionx, optiony);\n\n        Assert.True(optionr);\n        Assert.True(optionx != optiony);\n    }\n\n    public static bool IsEqual<EqA, M, A>(K<M, A> mx, K<M, A> my)\n        where EqA : Eq<A>\n        where M : Monad<M>, Foldable<M> =>\n        (from x in mx\n         from y in my\n         select EqA.Equals(x, y))\n        .ForAll(x => x);\n}\n\n\npublic class EqualityTestsWithStaticProperties\n{\n    public class Foo : Record<Foo>\n    {\n        public static Foo Default { get; } \n\n        static Foo() => \n            Default = new Foo( 10,20,List(1,2) );\n\n        public Foo(int age, int s, Lst<int> numbers)\n        {\n            Age = age;\n            String = s;\n            Numbers = numbers;\n        }\n        public int Age { get; }\n        public int String { get; }\n        public Lst<int> Numbers { get; }\n    }\n\n    [Fact]\n    public void EqualRecordsShouldBeEqual()\n    {\n\n        var a = new Foo( 10, 20, List( 0, 1, 2 ) );\n        var b = new Foo( 10, 20, List( 0, 1, 2 ) );\n\n        Assert.Equal( b, a );\n\n    }\n\n    [Fact]\n    public void NonEqualRecordsShouldBeNotEqual()\n    {\n\n        var a = new Foo( 10, 20, List( 0, 1, 2 ) );\n        var b = new Foo( 10, 20, List( 0, -1, 2 ) );\n\n        Assert.NotEqual( b, a );\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ErrorTests.cs",
    "content": "﻿using System;\nusing System.Runtime.Serialization;\nusing Xunit;\nusing LanguageExt.Common;\nusing Newtonsoft.Json;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class ErrorTests\n{\n    [Fact]\n    public void EqualityTest()\n    {\n        var ea = Error.New(100, \"Hello\");\n        var eb = Error.New(100, \"Hello\");\n        \n        Assert.True(ea == eb);\n    }\n    \n    [Fact]\n    public void NonEqualityTest()\n    {\n        var ea = Error.New(100, \"Hello\");\n        var eb = Error.New(100, \"World\");\n        \n        Assert.False(ea == eb);\n    }\n    \n    [Fact]\n    public void IsTest()\n    {\n        var ea = Error.New(100, \"Hello\");\n        var eb = Error.New(100, \"World\");\n        \n        Assert.True(ea.Is(ea));\n        Assert.True(eb.Is(eb));\n        Assert.True(ea.Is(eb));\n        Assert.True(eb.Is(ea));\n    }\n        \n    [Fact]\n    public void IsExpectedTest()\n    {\n        var ea = Error.New(100, \"Hello\");\n\n        Assert.True(ea.IsExpected);\n        Assert.True(\n            ea switch\n            {\n                var ex when ex.IsExpected => true,    \n                var ex => false    \n            });\n    }\n\n    [Fact]\n    public void ExpectedSerialisationTest()\n    {\n        var settings = new JsonSerializerSettings\n        {\n            TypeNameHandling = TypeNameHandling.Objects\n        };\n        var ea = Error.New(123, \"Err\");\n        var json = JsonConvert.SerializeObject(ea, settings);\n        var eb = JsonConvert.DeserializeObject<Error>(json, settings);\n        Assert.True(eb.IsExpected);\n        Assert.False(eb.IsExceptional);\n        Assert.True(ea == eb);\n        Assert.True(ea.Is(eb));\n        Assert.True(eb.Is(ea));\n    }\n    \n    [Fact]\n    public void ExceptionalSerialisationTest()\n    {\n        var settings = new JsonSerializerSettings\n        {\n            TypeNameHandling = TypeNameHandling.Objects\n        };\n        var ea = Error.New(new Exception(\"Hello, World\"));\n        var json = JsonConvert.SerializeObject(ea, settings);\n        var eb = JsonConvert.DeserializeObject<Error>(json, settings);\n        Assert.False(eb.IsExpected);\n        Assert.True(eb.IsExceptional);\n        Assert.True(ea.Is(eb));\n        Assert.True (eb.Is(ea));\n    }\n\n    public record BespokeError([property: DataMember] bool MyData) : \n        Expected(\"Expected something bespoke\", 100, None); \n    \n    [Fact]\n    public void BespokeExpectedSerialisationTest()\n    {\n        var settings = new JsonSerializerSettings\n        {\n            TypeNameHandling = TypeNameHandling.Objects\n        };\n        var ea = new BespokeError(true);\n        var json = JsonConvert.SerializeObject(ea, settings);\n        var eb = JsonConvert.DeserializeObject<Error>(json, settings);\n        Assert.True(eb.IsExpected);\n        Assert.False(eb.IsExceptional);\n        Assert.True(ea == eb);\n        Assert.True(ea.Is(eb));\n        Assert.True(eb.Is(ea));\n    }\n    \n    \n    [Fact]\n    public void ManyExpectedSerialisationTest()\n    {\n        var settings = new JsonSerializerSettings\n        {\n            TypeNameHandling = TypeNameHandling.Objects\n        };\n        var ea = Error.New(123, \"Err 1\");\n        var eb = Error.New(345, \"Err 2\");\n        var ec = Error.New(678, \"Err 3\");\n\n        var json = JsonConvert.SerializeObject(ea + eb + ec, settings);\n\n        var es = JsonConvert.DeserializeObject<Error>(json, settings);\n\n        Assert.False(es.IsEmpty);\n        Assert.True(es.Count == 3);\n        Assert.True(es.IsExpected);\n        Assert.False(eb.IsExceptional);\n\n        Assert.True(es == ea + eb + ec);\n        Assert.True(es.Is(ea + eb + ec));\n        Assert.True((ea + eb + ec).Is(es));\n    }\n\n    [Fact]\n    public void MonoidLawsTest()\n    {\n        var ea = Error.New(123, \"Err 1\");\n        var eb = Error.New(345, \"Err 2\");\n        var ec = Error.New(678, \"Err 3\");\n\n        Assert.True((ea + eb) + ec == ea + (eb + ec), \"Associativity\");\n        Assert.True(Error.Empty + ea == ea, \"Left Identity\");\n        Assert.True(ea + Error.Empty == ea, \"Right Identity\");\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/FSharp/FSharpTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.FSharp;\n\npublic class FSharpTests\n{\n    [Theory]\n    [InlineData(\"Error\")]\n    [InlineData(\"\")]\n    public void ErrorResult_to_Either(string error)\n    {\n        var result = Microsoft.FSharp.Core.FSharpResult<int, string>.NewError(error);\n\n        var either = LanguageExt.FSharp.fs(result);\n\n        either.Match(Right: _ => Assert.Fail(\"Shouldn't get here\"),\n                     Left: l => Assert.True(l == error));\n    }\n\n    [Fact]\n    public void OKResult_to_Either()\n    {\n        var result = Microsoft.FSharp.Core.FSharpResult<int, string>.NewOk(123);\n\n        var either = LanguageExt.FSharp.fs(result);\n\n        either.Match(Right: r => Assert.True(r == 123),\n                     Left: _ => Assert.Fail(\"Shouldn't get here\"));\n    }\n\n    [Fact]\n    public void Either_to_ErrorResult()\n    {\n        var either = Either.Left<string, int>(\"Error\");\n\n        var result = LanguageExt.FSharp.fs(either);\n\n        Assert.True(result.IsError);\n        Assert.True(result.ErrorValue == \"Error\");\n    }\n\n    [Fact]\n    public void Either_to_OkResult()\n    {\n        var either = Either.Right<string, int>(123);\n\n        var result = LanguageExt.FSharp.fs(either);\n\n        Assert.True(result.IsOk);\n        Assert.True(result.ResultValue == 123);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/FunTests.cs",
    "content": "﻿using System;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class FunTests\n{\n    [Fact] public void LambdaInferTests()\n    {\n        var fn1 = fun( () => 123 );\n        var fn2 = fun( (int a) => 123                                           + a );\n        var fn3 = fun( (int a, int b) => 123                                    + a + b );\n        var fn4 = fun( (int a, int b, int c) => 123                             + a + b + c);\n        var fn5 = fun( (int a, int b, int c, int d) => 123                      + a + b + c + d);\n        var fn6 = fun( (int a, int b, int c, int d, int e) => 123               + a + b + c + d + e);\n        var fn7 = fun( (int a, int b, int c, int d, int e, int f) => 123        + a + b + c + d + e + f);\n        var fn8 = fun( (int a, int b, int c, int d, int e, int f, int g) => 123 + a + b + c + d + e + f + g);\n\n        var fnac1 = fun( () => { } );\n        var fnac2 = fun( (int a) => Console.WriteLine(123 + a) );\n        var fnac3 = fun( (int a, int b) => Console.WriteLine(123 + a + b));\n        var fnac4 = fun( (int a, int b, int c) => Console.WriteLine(123 + a + b + c));\n        var fnac5 = fun( (int a, int b, int c, int d) => Console.WriteLine(123 + a + b + c + d));\n        var fnac6 = fun( (int a, int b, int c, int d, int e) => Console.WriteLine(123 + a + b + c + d + e));\n        var fnac7 = fun( (int a, int b, int c, int d, int e, int f) => Console.WriteLine(123 + a + b + c + d + e + f));\n        var fnac8 = fun( (int a, int b, int c, int d, int e, int f, int g) => Console.WriteLine(123 + a + b + c + d + e + f + g));\n\n        var ac1 = act(() => { });\n        var ac2 = act((int a) => Console.WriteLine(123 + a));\n        var ac3 = act((int a, int b) => Console.WriteLine(123 + a + b));\n        var ac4 = act((int a, int b, int c) => Console.WriteLine(123 + a + b + c));\n        var ac5 = act((int a, int b, int c, int d) => Console.WriteLine(123 + a + b + c + d));\n        var ac6 = act((int a, int b, int c, int d, int e) => Console.WriteLine(123 + a + b + c + d + e));\n        var ac7 = act((int a, int b, int c, int d, int e, int f) => Console.WriteLine(123 + a + b + c + d + e + f));\n        var ac8 = act((int a, int b, int c, int d, int e, int f, int g) => Console.WriteLine(123 + a + b + c + d + e + f + g));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/GlobalSuppressions.cs",
    "content": "﻿\n// This file is used by Code Analysis to maintain SuppressMessage \n// attributes that are applied to this project.\n// Project-level suppressions either have no target or are given \n// a specific target and scoped to a namespace, type, member, etc.\n\n"
  },
  {
    "path": "LanguageExt.Tests/GlobalUsings.cs",
    "content": "global using LanguageExt;\nglobal using LanguageExt.Traits;\nglobal using static LanguageExt.Prelude;\n"
  },
  {
    "path": "LanguageExt.Tests/HashMapTests.cs",
    "content": "﻿//using LanguageExt.Trans;\nusing static LanguageExt.HashMap;\nusing Xunit;\nusing System;\nusing System.Linq;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests;\n\npublic class HashMapTests\n{\n    [Fact]\n    public void HashMapGeneratorTest()\n    {\n        var m1 = HashMap<int, string>();\n        m1 = add(m1, 100, \"hello\");\n        Assert.True(m1.Count == 1 && containsKey(m1,100));\n    }\n\n    [Fact]\n    public void MapGeneratorAndMatchTest()\n    {\n        var m2 = HashMap( (1, \"a\"),\n                          (2, \"b\"),\n                          (3, \"c\") );\n\n        m2 = add(m2, 100, \"world\");\n\n        var res = match(\n            m2, 100,\n            v  => v,\n            () => \"failed\"\n        );\n\n        Assert.True(res == \"world\");\n    }\n\n    [Fact]\n    public void MapSetTest()\n    {\n        var m1 = HashMap( (1, \"a\"),\n                          (2, \"b\"),\n                          (3, \"c\") );\n\n        var m2 = setItem(m1, 1, \"x\");\n\n        match( \n            m1, 1, \n            Some: v => Assert.True(v == \"a\"), \n            None: () => Assert.False(true) \n        );\n\n        match(\n            find(m2, 1),\n            Some: v => Assert.True(v == \"x\"),\n            None: () => Assert.False(true)\n        );\n    }\n\n    [Fact]\n    public void MapAddInOrderTest()\n    {\n        var m = HashMap((1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashMap((1, 1), (2, 2));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashMap((1, 1), (2, 2), (3, 3));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashMap((1, 1), (2, 2), (3, 3), (4, 4));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashMap((1, 1), (2, 2), (3, 3), (4, 4), (5, 5));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n    [Fact]\n    public void MapAddInReverseOrderTest()\n    {\n        var m = HashMap((2, 2), (1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashMap((3, 3), (2, 2), (1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashMap((4, 4), (3, 3), (2, 2), (1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashMap((5, 5), (4, 4), (3, 3), (2, 2), (1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n    [Fact]\n    public void MapAddInMixedOrderTest()\n    {\n        var m = HashMap((5, 5), (1, 1), (3, 3), (2, 2), (4, 4));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashMap((1, 1), (3, 3), (5, 5), (2, 2), (4, 4));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n\n    [Fact]\n    public void MapRemoveTest()\n    {\n        var m = HashMap((1, \"a\"),\n                        (2, \"b\"),\n                        (3, \"c\"),\n                        (4, \"d\"),\n                        (5, \"e\"));\n\n        m.Find(1).IfNone(() => failwith<string>(\"Broken 1\"));\n        m.Find(2).IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(3).IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(4).IfNone(() => failwith<string>(\"Broken 4\"));\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        Assert.True(m.Count == 5);\n\n        m = remove(m,4);\n        Assert.True(m.Count == 4);\n        Assert.True(m.Find(4).IsNone);\n        m.Find(1).IfNone(() => failwith<string>(\"Broken 1\"));\n        m.Find(2).IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(3).IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, 1);\n        Assert.True(m.Count == 3);\n        Assert.True(m.Find(1).IsNone);\n        m.Find(2).IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(3).IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, 2);\n        Assert.True(m.Count == 2);\n        Assert.True(m.Find(2).IsNone);\n        m.Find(3).IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, 3);\n        Assert.True(m.Count == 1);\n        Assert.True(m.Find(3).IsNone);\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, 5);\n        Assert.True(m.Count == 0);\n        Assert.True(m.Find(5).IsNone);\n    }\n\n    [Fact]\n    public void MassAddRemoveTest()\n    {\n        int max = 100000;\n\n        var items = IterableExtensions.AsIterable(Range(1, max))\n                                      .Map( _ => (Key: Guid.NewGuid(), Value: Guid.NewGuid()))\n                                      .ToSeq();\n\n        var m = HashMap<Guid, Guid>().AddRange(items);\n        Assert.True(m.Count == max);\n\n        foreach (var item in items)\n        {\n            Assert.True(m.ContainsKey(item.Key));\n            m = m.Remove(item.Key);\n            Assert.False(m.ContainsKey(item.Key));\n            max--;\n            Assert.True(m.Count == max);\n        }\n    }\n\n    [Fact]\n    public void HashMapSetTest()\n    {\n        var map  = HashMap<EqStringOrdinalIgnoreCase, string, int>((\"one\", 1), (\"two\",2), (\"three\", 3));\n        var map2 = map.SetItem(\"One\", -1);\n        Assert.Equal(3, map2.Count);\n        Assert.Equal(-1, map2[\"one\"]);\n        Assert.DoesNotContain(\"one\", map2.Keys.AsEnumerable()); // make sure key got replaced, too\n        Assert.Contains(\"One\", map2.Keys.AsEnumerable());       // make sure key got replaced, too\n\n        Assert.Throws<ArgumentException>(() => map.SetItem(\"four\", identity));\n    }\n\n    [Fact]\n    public void EqualsTest()\n    {\n        Assert.True(HashMap<int, int>().Equals(HashMap<int, int>()));\n        Assert.False(HashMap((1, 2)).Equals(HashMap<int, int>()));\n        Assert.False(HashMap<int, int>().Equals(HashMap((1, 2))));\n        Assert.True(HashMap((1, 2)).Equals(HashMap((1, 2))));\n        Assert.False(HashMap((1, 2), (3, 4)).Equals(HashMap((1, 2))));\n        Assert.False(HashMap((1, 2)).Equals(HashMap((1, 2), (3, 4))));\n        Assert.True(HashMap((1, 2), (3, 4)).Equals(HashMap((1, 2), (3, 4))));\n        Assert.True(HashMap((3, 4), (1, 2)).Equals(HashMap((1, 2), (3, 4))));\n        Assert.True(HashMap((3, 4), (1, 2)).Equals(HashMap((3, 4), (1, 2))));\n    }\n        \n    [Fact]\n    public void FetchBack()\n    {\n        var init = Seq(69, 1477);\n        var rmv  = Seq(69);\n\n        var map = toHashMap(init.Zip(Enumerable.Repeat(1, int.MaxValue)));\n\n        Assert.True(map.ContainsKey(1477)); // false\n        Assert.True(map.Find(1477).IsSome); // false\n\n\n        var minus = map.RemoveRange(rmv);\n\n        Assert.True(minus.Keys.Find(i => i == 1477).IsSome); // true\n            \n        Assert.True(minus.ContainsKey(1477)); // false\n        Assert.True(minus.Find(1477).IsSome); // false\n\n        var boom = minus[1477]; // throws\n    }\n\n    [Fact]\n    public void HashMapRemoveTest()\n    {\n        var values = new[] { 1175691501, 613261927, 178639586, 745392133,\n                               1071314707, 464997766, 746033505, 2055266377,\n                               9321519, 2085595311 };\n\n        var items = toHashMap(values.Zip(values));\n\n        foreach(var value in values)\n        {\n            items = items.Remove(value);\n            Assert.True(!items.Contains(value));\n        }\n    }\n\n    [Fact]\n    public void itemLensGetShouldGetExistingValue()\n    {\n        var expected = \"3\";\n        var map      = HashMap((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n        var actual   = HashMap<int, string>.item(3).Get(map);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void itemLensGetShouldThrowExceptionForNonExistingValue()\n    {\n        Assert.Throws<ArgumentException>(() =>\n                                         {\n                                             var map    = HashMap((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n                                             var actual = HashMap<int, string>.item(10).Get(map);\n                                         });\n    }\n\n    [Fact]\n    public void itemOrNoneLensGetShouldGetExistingValue()\n    {\n        var expected = \"3\";\n        var map      = HashMap((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n        var actual   = HashMap<int, string>.itemOrNone(3).Get(map);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void itemOrNoneLensGetShouldReturnNoneForNonExistingValue()\n    {\n        var expected = Option<string>.None;\n        var map      = HashMap((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n        var actual   = HashMap<int, string>.itemOrNone(10).Get(map);\n\n        Assert.Equal(expected, actual);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/HashSetTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing Newtonsoft.Json;\nusing static LanguageExt.HashSet;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests;\n\npublic class HashSetTests\n{\n    [Fact]\n    public void HashSetHasItemsTest() => \n        Assert.False(HashSet(1, 2, 3).IsEmpty);\n\n    [Fact]\n    public void HashSetGeneratorTest()\n    {\n        var m1 = HashSet<string>();\n        m1 = add(m1, \"hello\");\n        Assert.True(m1.Count == 1 && contains(m1, \"hello\"));\n    }\n\n    [Fact]\n    public void HashSetGeneratorAndMatchTest()\n    {\n        var m2 = HashSet(\"a\", \"b\", \"c\");\n\n        m2 = add(m2, \"world\");\n\n        var res = find(m2, \"world\").Match(\n            v  => v,\n            () => \"failed\"\n        );\n\n        Assert.True(res == \"world\");\n    }\n\n    [Fact]\n    public void HashSetAddInOrderTest()\n    {\n        var m = HashSet(1);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(1, 2);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(1, 2, 3);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(1, 2, 3, 4);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(1, 2, 3, 4, 5);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n    [Fact]\n    public void HashSetAddInReverseOrderTest()\n    {\n        var m = HashSet(1);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(2, 1);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(3, 2, 1);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(4, 3, 2, 1);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(5, 4, 3, 2, 1);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n    [Fact]\n    public void HashSetAddInMixedOrderTest()\n    {\n        var m = HashSet(5, 1, 3, 2, 4);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = HashSet(1, 3, 5, 2, 4);\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n    [Fact]\n    public void HashSetRemoveTest()\n    {\n        var m = HashSet(\"a\", \"b\", \"c\", \"d\", \"e\");\n\n        m.Find(\"a\").IfNone(() => failwith<string>(\"Broken 1\"));\n        m.Find(\"b\").IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(\"c\").IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(\"d\").IfNone(() => failwith<string>(\"Broken 4\"));\n        m.Find(\"e\").IfNone(() => failwith<string>(\"Broken 5\"));\n\n        Assert.True(m.Count == 5);\n\n        m = remove(m, \"d\");\n        Assert.True(m.Count == 4);\n        Assert.True(m.Find(\"d\").IsNone);\n        m.Find(\"a\").IfNone(() => failwith<string>(\"Broken 1\"));\n        m.Find(\"b\").IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(\"c\").IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(\"e\").IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, \"a\");\n        Assert.True(m.Count == 3);\n        Assert.True(m.Find(\"a\").IsNone);\n        m.Find(\"b\").IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(\"c\").IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(\"e\").IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, \"b\");\n        Assert.True(m.Count == 2);\n        Assert.True(m.Find(\"b\").IsNone);\n        m.Find(\"c\").IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(\"e\").IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, \"c\");\n        Assert.True(m.Count == 1);\n        Assert.True(m.Find(\"c\").IsNone);\n        m.Find(\"e\").IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, \"e\");\n        Assert.True(m.Count == 0);\n        Assert.True(m.Find(\"e\").IsNone);\n    }\n\n    [Fact]\n    public void HashSetKeyTypeTests()\n    {\n        var set = HashSet<EqStringOrdinalIgnoreCase, string>(\"one\", \"two\", \"three\");\n\n        Assert.True(set.Contains(\"one\"));\n        Assert.True(set.Contains(\"ONE\"));\n\n        Assert.True(set.Contains(\"two\"));\n        Assert.True(set.Contains(\"Two\"));\n\n        Assert.True(set.Contains(\"three\"));\n        Assert.True(set.Contains(\"thREE\"));\n    }\n\n    [Fact]\n    public void HashSetSetTest()\n    {\n        var set  = HashSet<EqStringOrdinalIgnoreCase, string>(\"one\", \"two\", \"three\");\n        var set2 = set.SetItem(\"One\");\n        Assert.Equal(3, set2.Count);\n        Assert.False(set2.ToSeq().Contains(\"one\"));\n        Assert.True(set2.ToSeq().Contains(\"One\"));\n\n        Assert.Throws<ArgumentException>(() => set.SetItem(\"four\"));\n    }\n\n    [Fact]\n    public void EqualsTest()\n    {\n        Assert.False(HashSet(1, 2, 3).Equals(HashSet<int>()));\n        Assert.False(HashSet<int>().Equals(HashSet<int>(1, 2, 3)));\n        Assert.True(HashSet<int>().Equals(HashSet<int>()));\n        Assert.True(HashSet<int>(1).Equals(HashSet<int>(1)));\n        Assert.True(HashSet<int>(1, 2).Equals(HashSet<int>(1, 2)));\n        Assert.False(HashSet<int>(1, 2).Equals(HashSet<int>(1, 2, 3)));\n        Assert.False(HashSet<int>(1, 2, 3).Equals(HashSet<int>(1, 2)));\n    }\n        \n    [Fact]\n    public void HashSet_WithDefaultSettings_SerializationTest()\n    {\n        var source = HashSet(123, 456);\n        var json   = JsonConvert.SerializeObject(source);\n        var result = JsonConvert.DeserializeObject<HashSet<int>>(json);\n\n        Assert.Equal(source, result);\n    }\n\n    [Fact]\n    public void HashSet_WithEchoCustomSettings_SerializationTest()\n    {\n        var settings = new JsonSerializerSettings\n                       {\n                           TypeNameHandling               = TypeNameHandling.All,\n                           TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,\n                           MissingMemberHandling          = MissingMemberHandling.Ignore\n                       };\n\n        var source = HashSet(123, 456);\n        var json   = JsonConvert.SerializeObject(source, settings);\n        var result = JsonConvert.DeserializeObject<HashSet<int>>(json, settings);\n\n        Assert.Equal(source, result);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IOTests/ApplyTests.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.IOTests;\n\npublic class IO_ApplyTests\n{\n    [Fact]\n    public void Apply_ShouldApplyFunctionToValue()\n    {\n        // Arrange\n        var ioValue    = IO.pure(5);                // IO computation with a value of 5\n        var ioFunction = IO.pure((int x) => x * 2); // IO computation with a function (x => x * 2)\n\n        // Act\n        var appliedIO = ioFunction.Apply(ioValue); // Apply function to value\n        var result    = appliedIO.Run();           // Perform the computation to get the result\n\n        // Assert\n        Assert.Equal(10, result); // Ensure the function application happened correctly\n    }\n\n    [Fact]\n    public void Apply_ShouldBubbleUpFailure()\n    {\n        // Arrange\n        var failError  = Error.New(\"Failed IO\");\n        var failedIO   = IO.fail<int>(failError);   // Failing IO computation\n        var ioFunction = IO.pure((int x) => x * 2); // IO computation with a function\n\n        // Act & Assert\n        // Since the IO computation failed, the result must throw the expected error\n        var ex = Assert.ThrowsAny<ErrorException>(() => ioFunction.Apply(failedIO).Run());\n        Assert.Equal(failError, ex.ToError()); // Check that the bubbled-up error matches\n    }\n\n    [Fact]\n    public void Apply_ShouldNotRunFunctionIfFunctionIsFailed()\n    {\n        // Arrange\n        var failError      = Error.New(\"Failed Function\");\n        var ioValue        = IO.pure(5);\n        var failedFunction = IO.fail<Func<int, int>>(failError);\n\n        // Act & Assert\n        // The failed function should result in a failure even if the value is valid\n        var ex = Assert.ThrowsAny<ErrorException>(() => failedFunction.Apply(ioValue).Run());\n        Assert.Equal(failError, ex.ToError()); // Check the error matches the failed function's error\n    }    \n    \n    [Fact]\n    public async Task Apply_WithAsyncAndSyncTermsShouldRunInParallel()\n    {\n        var af = Atom(0);\n        var aa = Atom(0);\n        \n        // Create a task that takes longer to return than `fa`.  This relies on `fa` completing first\n        // so that aa.Value has been set.  This proves that the applicative parallel behaviour is working \n        var ff = IO.liftAsync(() => Task.Delay(100)\n                                        .ToUnit()\n                                        .Map(_ => af.Swap(x => x + aa.Value))\n                                        .Map(_ => new Func<int, int>(x => x * af.Value)));\n        \n        var fa = IO.liftAsync(() => Task.Delay(10)\n                                        .ToUnit()\n                                        .Map(_ => aa.Swap(x => x + 5)));\n        \n        var fr = ff.Apply(fa);\n        var r  = await fr.RunAsync();\n        Assert.Equal(25, r);\n    }\n    \n    [Fact]\n    public async Task Apply_WithAsyncAndSyncTermsShouldApplyFunctionToValue()\n    {\n        var af = Atom(0);\n        var aa = Atom(0);\n        \n        // Create a task that takes longer to return than `fa`.  This relies on `fa` completing first\n        // so that aa.Value has been set.  This proves that the applicative parallel behaviour is working \n        var ff = IO.liftAsync(() => Task.Delay(100)\n                                        .ToUnit()\n                                        .Map(_ => af.Swap(x => x + aa.Value))\n                                        .Map(_ => new Func<int, int>(x => x * af.Value)));\n        \n        var fa = IO.lift(() => aa.Swap(x => x + 5));\n        \n        var fr = ff.Apply(fa);\n        var r  = await fr.RunAsync();\n        Assert.Equal(25, r);\n    }\n    \n    [Fact]\n    public async Task Apply_WithSyncAndAsyncTermsShouldApplyFunctionToValue()\n    {\n        var ff = IO.liftAsync(() => Task.Delay(100)\n                                        .ToUnit()\n                                        .Map(_ => new Func<int, int>(x => x * 5)));\n        var fa = IO.pure(5);\n        var fr = ff.Apply(fa);\n        var r  = await fr.RunAsync();\n        Assert.Equal(25, r);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IOTests/FoldTests.cs",
    "content": "using System;\nusing Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.IOTests;\n\npublic class IOFoldTests\n{\n    [Fact]\n    public void Fold_AccumulatesStateAccurately()\n    {\n        // Arrange\n        var                 computation  = IO.pure(10); // Successful IO returning 10\n        var                 initialState = 0;\n        Func<int, int, int> sumFolder    = (state, value) => state + value;\n\n        // Act\n        var foldedIO = computation.Fold(Schedule.Never, initialState, sumFolder).Run();\n\n        // Assert\n        Assert.Equal(10, foldedIO);\n    }\n\n    [Fact]\n    public void Fold_InitialStateIsReturnedIfNoEffect()\n    {\n        // Arrange\n        var                 computation  = IO<int>.Empty; // No effect in the IO\n        var                 initialState = 5;\n        Func<int, int, int> sumFolder    = (state, value) => state + value;\n\n        // Assert\n        Assert.ThrowsAny<AggregateException>(() => computation.Fold(Schedule.Never, initialState, sumFolder).Run());\n    }\n\n    [Fact]\n    public void Fold_ComputationFailurePreservesState()\n    {\n        // Arrange\n        var                 computation  = IO.fail<int>(Error.New(\"Error occurred\")); // Simulating a failure\n        var                 initialState = 5;\n        Func<int, int, int> sumFolder    = (state, value) => state + value;\n\n        // Assert\n        Assert.ThrowsAny<ErrorException>(() => computation.Fold(Schedule.Never, initialState, sumFolder).Run());\n    }\n\n    [Fact]\n    public void Fold_ComplexTransformationAppliedCorrectly()\n    {\n        // Arrange\n        var                       computation  = IO.pure(7); // Successful IO\n        var                       initialState = \"Start: \";\n        Func<string, int, string> folder       = (state, value) => state + value;\n\n        // Act\n        var foldedIO = computation.Fold(Schedule.Never, initialState, folder).Run();\n\n        // Assert\n        Assert.Equal(\"Start: 7\", foldedIO); // State should reflect the transformation\n    }\n\n    [Fact]\n    public void FoldUntil_StopsOnMatchingPredicate()\n    {\n        // Arrange\n        var                 computation  = IO.pure(10); // IO succeeds with result 10\n        var                 initialState = 0;\n        Func<int, int, int> sumFolder    = (state, value) => state + value;\n        Func<int, bool>     predicate    = state => state > 5; // Stop folding if state > 5\n\n        // Act\n        var foldedIO = computation.FoldUntil(initialState, sumFolder, stateIs: predicate).Run();\n\n        // Assert\n        Assert.Equal(10, foldedIO); // Predicate stops calculation\n    }\n\n    [Fact]\n    public void FoldWhile_StatePredicatesEnforcedCorrectly()\n    {\n        // Arrange\n        var                 computation   = IO.pure(20);\n        var                 initialState  = 5;\n        Func<int, int, int> folder        = (state, value) => state + value;\n        Func<int, bool>     continueWhile = state => state < 30; // Continue only if state < 30\n\n        // Act\n        var result = computation.FoldWhile(initialState, folder, stateIs: continueWhile).Run();\n\n        // Assert\n        Assert.Equal(45, result); // Folding happens as state < 30\n    }\n\n    [Fact]\n    public void FoldWhile_StopsWhenStateConditionIsNotMet()\n    {\n        // Arrange\n        var                 computation       = IO.pure(50);\n        var                 initialState      = 10;\n        Func<int, int, int> folder            = (state, value) => state + value;\n        Func<int, bool>     continuePredicate = state => state < 30; // Stop if state >= 30\n\n        // Act\n        var foldedIO = computation.FoldWhile(initialState, folder, stateIs: continuePredicate).Run();\n\n        // Assert\n        Assert.Equal(60, foldedIO); // Predicate stops further updates\n    }\n\n    [Fact]\n    public void FoldWhile_HandlesEmptyCorrectly()\n    {\n        // Arrange\n        var                 computation       = IO.empty<int>(); // No effect occurs\n        var                 initialState      = 10;\n        Func<int, int, int> folder            = (state, value) => state + value;\n        Func<int, bool>     continuePredicate = state => state < 30;\n\n        // Assert\n        Assert.ThrowsAny<AggregateException>(() => computation.FoldWhile(initialState, folder, stateIs: continuePredicate).Run());\n    }\n\n    [Fact]\n    public void FoldUntil_CompletesOnConditionMet()\n    {\n        // Arrange\n        var                 computation   = IO.pure(10);\n        var                 initialState  = 5;\n        Func<int, int, int> folder        = (state, value) => state + value;\n        Func<int, bool>     stopCondition = state => state >= 15; // Stop if >= 15\n\n        // Act\n        var foldedResult = computation.FoldUntil(Schedule.Forever, initialState, folder, stateIs: stopCondition).Run();\n\n        // Assert\n        Assert.Equal(15, foldedResult); // Stops just as condition is met\n    }\n\n    [Fact]\n    public void FoldUntil_HandlesErrorsWithoutStateChange()\n    {\n        // Arrange\n        var                 computation   = IO.fail<int>(Error.New(\"An error\"));\n        var                 initialState  = 42;\n        Func<int, int, int> folder        = (state, value) => state - value; // Just a demonstration\n        Func<int, bool>     stopCondition = state => state < 0;\n\n        // Assert\n        Assert.ThrowsAny<ErrorException>(() => computation.FoldUntil(initialState, folder, stateIs: stopCondition).Run());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IOTests/GeneralTests.cs",
    "content": "using LanguageExt.Common;\nusing System;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace LanguageExt.Tests.IOTests;\n\npublic class IO_GeneralTests\n{\n    [Fact]\n    public void Pure_ShouldReturnCorrectValue()\n    {\n        // Arrange\n        var value = 42;\n        var io = IO.pure(value);\n\n        // Act\n        var result = io.Run();\n\n        // Assert\n        Assert.Equal(value, result);\n    }\n\n    [Fact]\n    public void Fail_ShouldThrowError()\n    {\n        // Arrange\n        var error = Error.New(\"Test error\");\n        var io = IO.fail<int>(error);\n\n        // Act & Assert\n        var ex = Assert.ThrowsAny<ExpectedException>(() => io.Run());\n        Assert.Equal(error, ex.ToError());\n    }\n\n    [Fact]\n    public void Map_ShouldTransformValue()\n    {\n        // Arrange\n        var io = IO.pure(5);\n\n        // Act\n        var result = io.Map(x => x * 2).Run();\n\n        // Assert\n        Assert.Equal(10, result);\n    }\n\n    [Fact]\n    public void Bind_ShouldChainComputations()\n    {\n        // Arrange\n        var io = IO.pure(10);\n\n        // Act\n        var result = io.Bind(x => IO.pure(x + 20)).Run();\n\n        // Assert\n        Assert.Equal(30, result);\n    }\n\n    [Fact]\n    public void Catch_ShouldHandleErrorsGracefully()\n    {\n        // Arrange\n        var io = IO.fail<int>(Error.New(\"Test error\"));\n\n        // Act\n        var result = io.IfFail(42).Run();\n\n        // Assert\n        Assert.Equal(42, result);\n    }\n\n    [Fact]\n    public void Select_ShouldMapValue_WhenUsingLINQ()\n    {\n        // Arrange\n        var io = IO.pure(4);\n\n        // Act\n        var result = from x in io select x * 2;\n\n        // Assert\n        Assert.Equal(8, result.Run());\n    }\n\n    [Fact]\n    public void SelectMany_ShouldChainOperations_WhenUsingLINQ()\n    {\n        // Arrange\n        var io1 = IO.pure(5);\n        var io2 = IO.pure(3);\n\n        // Act\n        var result = from x in io1\n                     from y in io2\n                     select x + y;\n\n        // Assert\n        Assert.Equal(8, result.Run());\n    }\n\n    [Fact]\n    public void Retry_ShouldRetryOnFailure_AndSucceedEventually()\n    {\n        // Arrange\n        var count = 0;\n        var io = IO.lift(() =>\n        {\n            if (count++ < 2) throw new Exception(\"Retry test\");\n            return 42;\n        });\n\n        // Act\n        var result = io.Retry().Run();\n\n        // Assert\n        Assert.Equal(42, result);\n        Assert.Equal(3, count); // 2 failures + 1 success\n    }\n\n    [Fact]\n    public void Repeat_ShouldRepeatUntilConditionMet()\n    {\n        // Arrange\n        var counter = 0;\n        var io = IO.lift(() => ++counter);\n\n        // Act\n        var result = io.RepeatUntil(x => x == 5).Run();\n\n        // Assert\n        Assert.Equal(5, result);\n        Assert.Equal(5, counter); // IO should repeat until the predicate is satisfied\n    }\n\n    [Fact]\n    public void Timeout_ShouldThrowException_WhenTimeLimitExceeded()\n    {\n        // Arrange\n        var io = IO.lift(() =>\n        {\n            Task.Delay(1000).Wait();\n            return 42;\n        });\n\n        // Act & Assert\n        Assert.ThrowsAny<OperationCanceledException>(() => io.Timeout(TimeSpan.FromMilliseconds(100)).Run());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IOTests/MapFailTests.cs",
    "content": "using System;\nusing Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.IOTests;\n\npublic class IO_MapFailTests\n{\n    [Fact]\n    public void MapFail_ShouldNotAlterSuccessValue()\n    {\n        // Arrange\n        var ioValue = IO.pure(10); // Successful computation\n        Func<Error, Error> errorMapper = error => Error.New(\"Mapped Error\"); // Transformation function (not used here)\n        \n        // Act\n        var result = ioValue.MapFail(errorMapper).Run(); // Run the computation\n\n        // Assert\n        Assert.Equal(10, result); // Ensure the success value is unchanged\n    }\n\n    [Fact]\n    public void MapFail_ShouldTransformFailure()\n    {\n        // Arrange\n        var initialError = Error.New(\"Initial Error\");\n        var failedIO = IO.fail<int>(initialError); // Failing computation\n\n        // Transformation function to map the error\n        Func<Error, Error> errorMapper = error => Error.New($\"{error.Message} -> Mapped Error\");\n\n        // Act & Assert\n        var ex = Assert.ThrowsAny<ErrorException>(() => failedIO.MapFail(errorMapper).Run());\n\n        // Assert\n        Assert.NotNull(ex);\n        Assert.Equal(\"Initial Error -> Mapped Error\", ex.ToError().Message); // Verify the error was transformed\n    }\n\n    [Fact]\n    public void MapFail_ShouldHandleNestedErrors()\n    {\n        // Arrange\n        var nestedError = Error.New(\"Nested Error\");\n        var failedIO    = IO.fail<int>(nestedError);\n\n        // Transformation function that appends extra context to the error\n        Func<Error, Error> errorMapper = error => Error.New($\"{error.Message}, with additional info\");\n\n        // Act & Assert\n        var ex = Assert.ThrowsAny<ErrorException>(() => failedIO.MapFail(errorMapper).Run());\n\n        // Assert\n        Assert.NotNull(ex);\n        Assert.Equal(\"Nested Error, with additional info\", ex.ToError().Message); // Verify error transformation\n    }\n    \n    [Fact]\n    public void MapFail_ShouldNotSwallowExceptionsOnMappingFailure()\n    {\n        // Arrange\n        var initialError = Error.New(\"Original Error\");\n        var failedIO     = IO.fail<int>(initialError); // Failing computation\n        \n        // Transformation function that throws an exception\n        Func<Error, Error> errorMapper = error => throw new InvalidOperationException(\"Transformation failed\");\n\n        // Act & Assert\n        var ex = Assert.Throws<InvalidOperationException>(() => failedIO.MapFail(errorMapper).Run());\n\n        // Assert\n        Assert.Equal(\"Transformation failed\", ex.Message); // Verify the exception from the mapping function\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IOTests/RepeatTests.cs",
    "content": "namespace LanguageExt.Tests.IOTests;\n\nusing Xunit;\nusing LanguageExt;\n\npublic class IO_RepeatTests\n{\n    IO<int> CreateIncrementingIO(Atom<int> callCount)\n    {\n        callCount.Swap(_ => 0);\n        return IO.lift(() => callCount.Swap(x => x + 1));\n    }\n\n    [Fact]\n    public void RepeatWhile_ShouldRepeatUntilConditionFails()\n    {\n        // Arrange\n        var callCount = Atom(0);\n        var io        = CreateIncrementingIO(callCount);\n\n        // Act\n        var repeatedIo = io.RepeatWhile(value => value < 5);\n        var result = repeatedIo.Run();\n\n        // Assert\n        Assert.Equal(5, result); // The final value when the condition `value < 5` is no longer true\n        Assert.Equal(5, callCount); // Ensure the IO ran 5 times\n    }\n\n    [Fact]\n    public void RepeatUntil_ShouldStopWhenConditionIsMet()\n    {\n        // Arrange\n        var callCount = Atom(0);\n        var io        = CreateIncrementingIO(callCount);\n\n        // Act\n        var repeatedIo = io.RepeatUntil(value => value >= 5);\n        var result = repeatedIo.Run();\n\n        // Assert\n        Assert.Equal(5, result); // The value at which the repetition stops (condition met)\n        Assert.Equal(5, callCount); // Ensure the IO ran 5 times\n    }\n\n    [Fact]\n    public void RepeatWhile_WithTimeSeriesSchedule_ShouldRepeatWhileConditionIsMet()\n    {\n        // Arrange\n        var callCount = Atom(0);\n        var io        = CreateIncrementingIO(callCount);\n        var schedule = Schedule.TimeSeries(new Duration(10), new Duration(15), new Duration(20));\n\n        // Act\n        var repeatedIo = io.RepeatWhile(schedule, value => value < 5);\n        var result = repeatedIo.Run();\n\n        // Assert\n        Assert.Equal(4, result); // The final value when the condition `value < 5` is no longer true\n        Assert.Equal(4, callCount); // Make sure the IO executed 4 times\n    }\n\n    [Fact]\n    public void RepeatUntil_WithForeverSchedule_ShouldRepeatUntilConditionIsMet()\n    {\n        // Arrange\n        var callCount = Atom(0);\n        var io        = CreateIncrementingIO(callCount);\n        var schedule  = Schedule.Forever;\n\n        // Act\n        var repeatedIo = io.RepeatUntil(schedule, value => value >= 5);\n        var result = repeatedIo.Run();\n\n        // Assert\n        Assert.Equal(5, result); // The value at which the repetitions stop\n        Assert.Equal(5, callCount); // Ensure the IO ran exactly 5 times\n    }\n\n    [Fact]\n    public void RepeatWhile_FixedIntervalSchedule_ShouldFollowScheduleDelays()\n    {\n        // Arrange\n        var callCount = Atom(0);\n        var io        = CreateIncrementingIO(callCount);\n        var schedule  = Schedule.fixedInterval(new Duration(1000));\n\n        // Act\n        var repeatedIo = io.RepeatWhile(schedule, value => value < 3);\n        var result = repeatedIo.Run();\n\n        // Assert\n        Assert.Equal(3, result); // Stops after the value reaches 3\n        Assert.Equal(3, callCount); // Ensure the IO executed 3 times\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IOTests/RetryTests.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace LanguageExt.Tests.IOTests;\n\npublic class IO_RetryTests\n{\n    [Fact]\n    public void Retry_SuccessOnFirstAttempt_ShouldReturnResultImmediately()\n    {\n        var io = IO.lift(() => 42);\n        var schedule = Schedule.Never;\n        var retryableIO = io.Retry(schedule);\n\n        var result = retryableIO.Run();\n\n        Assert.Equal(42, result);\n    }\n\n    [Fact]\n    public void Retry_FailingThenSuccess_ShouldRetryAndReturnSuccess()\n    {\n        var attempt = 0;\n        var io = IO.lift(() =>\n        {\n            attempt++;\n            if (attempt < 3) throw new Exception($\"Failure {attempt}\");\n            return 42;\n        });\n\n        var schedule = Schedule.recurs(2);\n        var retryableIO = io.Retry(schedule);\n\n        var result = retryableIO.Run();\n\n        Assert.Equal(42, result);\n        Assert.Equal(3, attempt);\n    }\n\n    [Fact]\n    public void Retry_ExceedsMaxRetry_ShouldThrowLastError()\n    {\n        var io = IO.lift<int>(() => throw new Exception(\"Persistent failure\"));\n        var schedule = Schedule.recurs(2);\n        var retryableIO = io.Retry(schedule);\n\n        Assert.ThrowsAny<Exception>(() => retryableIO.Run());\n    }\n\n    [Fact]\n    public void RetryWhile_ShouldContinueWhilePredicateIsTrue()\n    {\n        var attempt = 0;\n        var io = IO.lift<int>(() =>\n        {\n            attempt++;\n            throw new Exception($\"Failure {attempt}\");\n        });\n\n        var retryableIO = io.RetryWhile(error => error.Message.Contains(\"Failure 1\") || error.Message.Contains(\"Failure 2\"));\n\n        Assert.ThrowsAny<Exception>(() => retryableIO.Run());\n\n        Assert.Equal(3, attempt);\n    }\n\n    [Fact]\n    public void RetryUntil_ShouldStopWhenPredicateReturnsTrue()\n    {\n        var attempt = 0;\n        var io = IO.lift<int>(() =>\n        {\n            attempt++;\n            throw new Exception($\"Failure {attempt}\");\n        });\n\n        var retryableIO = io.RetryUntil(error => error.Message.Contains(\"Failure 2\"));\n\n        Assert.ThrowsAny<Exception>(() => retryableIO.Run());\n\n        Assert.Equal(2, attempt);\n    }\n\n    [Fact]\n    public void RetryWithSchedule_Spaced_ShouldRespectIntervalsAndStopAfterScheduleExpires()\n    {\n        var attempt = 0;\n        var io = IO.lift<int>(() =>\n        {\n            attempt++;\n            throw new Exception($\"Failure {attempt}\");\n        });\n\n        var schedule    = Schedule.spaced(new Duration(100)).Take(3);\n        var retryableIO = io.Retry(schedule);\n\n        Assert.ThrowsAny<Exception>(() => retryableIO.Run());\n\n        Assert.Equal(4, attempt);\n    }\n\n    [Fact]\n    public void RetryWithSchedule_ExponentialBackoff_ShouldRetryWithIncreasingIntervals()\n    {\n        var attempt = 0;\n        var io = IO.lift<int>(() =>\n        {\n            attempt++;\n            throw new Exception($\"Failure {attempt}\");\n        });\n\n        var schedule = Schedule.exponential(new Duration(100)).Take(3);\n        var retryableIO = io.Retry(schedule);\n\n        Assert.ThrowsAny<Exception>(() => retryableIO.Run());\n\n        Assert.Equal(4, attempt);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IOTests/TailRecursionTests.cs",
    "content": "using System;\nusing Xunit;\n\nnamespace LanguageExt.Tests.IOTests;\n\npublic class TailRecursionTests\n{\n    private record TestIO<A>(IO<A> io) : K<TestIO, A>\n    {\n        public A Run() => io.Run();\n    };\n    \n    private class TestIO : Deriving.MonadIO<TestIO, IO>\n    {\n        public static K<IO, A> Transform<A>(K<TestIO, A> fa) => ((TestIO<A>)fa).io;\n\n        public static K<TestIO, A> CoTransform<A>(K<IO, A> fa) => new TestIO<A>(fa.As());\n    }\n    \n    private readonly Atom<int> State = Atom(0);\n\n    [Fact]\n    public void TailRecursionInApplication_WhenPlainIO_ShouldNotThrow()\n    {\n        IO<Unit> innerLoop(int remaining) =>\n            from _1 in increment()\n            from _2 in tail(when(remaining > 0, innerLoop(remaining - 1)).As())\n            select unit;\n\n        var app =\n            from _1 in reset()\n            from _2 in innerLoop(3)\n            from result in multiply()\n            select result;\n        \n        var actual = app.Run();\n        Assert.Equal(40, actual);\n    }\n\n    private IO<int> reset() => State.SwapIO(_ => 0);\n\n    private IO<int> increment() => State.SwapIO(x => x + 1);\n    \n    private IO<int> multiply() => State.SwapIO(x => x * 10);\n\n\n    [Fact]\n    public void TailRecursionInApplication_WhenIOHKT_ShouldNotThrow()\n    {\n        IO<Unit> innerLoop(int remaining) =>\n            from _1 in increment()\n            from _2 in tail(when(remaining > 0, innerLoop(remaining - 1)).As()).Kind()\n            select unit;\n\n        var app =\n            from _1 in reset()\n            from _2 in innerLoop(3)\n            from result in multiply()\n            select result;\n        \n        var actual = app.Run();\n        Assert.Equal(40, actual);\n    }\n    \n    [Fact]\n    public void TailRecursionInApplication_WhenLiftIO_ShouldNotThrow()\n    {\n        TestIO<Unit> innerLoop(int remaining) => (TestIO<Unit>)\n            from _1 in new TestIO<int>(increment())\n            from _2 in tail(when(remaining > 0, innerLoop(remaining - 1).io).As())\n            select unit;\n\n        var app = (TestIO<int>)\n            from _1 in reset()\n            from _2 in innerLoop(3)\n            from result in multiply()\n            select result;\n        \n        var actual = app.Run();\n        Assert.Equal(40, actual);\n    }\n        \n    [Fact]\n    public void TailRecursionUsedImproperly_WhenPlainIO_ShouldThrow()\n    {\n        IO<Unit> loop(int remaining) =>\n            from _ in unitIO\n            from _1 in tail(when(remaining > 0, loop(remaining - 1)).As())\n            from _2 in unitIO\n            select unit;\n\n        Assert.Throws<NotSupportedException>(() => loop(3).Run());\n    }\n    \n    [Fact]\n    public void TailRecursionUsedImproperly_WhenIOHKT_ShouldThrow()\n    {\n        IO<Unit> loop(int remaining) =>\n            from _ in unitIO\n            from _1 in tail(when(remaining > 0, loop(remaining - 1)).As()).Kind()\n            from _2 in unitIO\n            select unit;\n\n        Assert.Throws<NotSupportedException>(() => loop(3).Run());\n    }\n    \n        \n    [Fact]\n    public void TailRecursionUsedImproperly_WhenLiftIO_ShouldThrow()\n    {\n        TestIO<Unit> loop(int remaining) => (TestIO<Unit>)\n            from _ in new TestIO<Unit>(unitIO)\n            from _1 in tail(when(remaining > 0, loop(remaining - 1).io).As())\n            from _2 in unitIO\n            select unit;\n\n        Assert.Throws<NotSupportedException>(() => loop(3).Run());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IssuesTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing System.Linq;\nusing Newtonsoft.Json;\nusing System.Threading.Tasks;\nusing System.Runtime.Serialization;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class IssuesTests\n    {\n        /// <summary>\n        /// https://github.com/louthy/language-ext/issues/207\n        /// </summary>\n        public void Issue207() =>\n            Initialization\n                .Bind(createUserMapping)\n                .Bind(addUser)\n                .Run();\n\n        public EitherT<Exception, IO, int> Issue207_2() =>\n            from us in Initialization\n            from mu in createUserMapping(us)\n            from id in addUser(mu)\n            select id;\n\n        static EitherT<Exception, IO, ADUser> Initialization =>\n            EitherT.Right<Exception, IO, ADUser>(new ADUser(\"test user\"));\n\n        static Either<Exception, UserMapping> createUserMapping(ADUser user) =>\n            Right<Exception, UserMapping>(new UserMapping(user + \" mapped\"));\n\n        static EitherT<Exception, IO, int> addUser(UserMapping user) =>\n            EitherT.Right<Exception, IO, int>(user.ToString().Length);\n\n        static IO<int> addUser2(UserMapping user) => \n            IO.lift(() => user.ToString().Length);\n\n        static IO<UserMapping> createUserMapping2(ADUser user) => \n            IO.lift(() => new UserMapping(user + \" mapped\"));\n\n        public IO<int> Issue207_5() =>\n            from us in IO.lift<ADUser>(() => throw new Exception(\"fail\"))\n            from mu in createUserMapping2(us)\n            from id in addUser2(mu)\n            select id;\n\n        //https://github.com/louthy/language-ext/issues/242\n        [Fact]\n        public void Issue208()\n        {\n            var r = from a in Left<Exception, int>(new Exception(\"error 1\"))\n                    from b in Right<Exception, int>(1)\n                    select a + b;\n        }\n\n        [Fact]\n        public void Issue346()\n        {\n            var list = 1.Cons().ToList();\n        }\n\n        [Fact]\n        public void Issue675()\n        {\n            var l1 = List(1, 2, 3);\n            var l2 = List(4, 5, 6);\n\n            var a = l1.AddRange(l2); // Count 6, [1,2,3,4,5,6]\n            var b = l1.AddRange(l2); // Count 5, [1,2,4,5,6]\n            var c = l1.AddRange(l2); // Count 8, [1,2,4,5,6,4,5,6]\n            var d = l1.AddRange(l2); // Count 7, [1,2,4,5,4,5,6]\n            var e = l1.AddRange(l2); // Count 6, [1,2,4,4,5,6]\n\n            Assert.True(a == b);\n            Assert.True(a == c);\n            Assert.True(a == d);\n            Assert.True(a == e);\n        }\n    }\n\n    public record ADUser(string u);\n    public record UserMapping(string u);\n}\n\n// https://github.com/louthy/language-ext/issues/245\npublic class TopHatTests\n{\n    public class TopHat : Record<TopHat>\n    {\n        public TopHat(int id, Option<int> id2)\n        {\n            Id = id;\n            Id2 = id2;\n        }\n\n        TopHat(SerializationInfo info, StreamingContext context) : base(info, context)\n        { }\n\n        public int Id { get; set; }\n        public Option<int> Id2 { get; set; }\n    }\n\n    OptionT<IO, int> SumOptionAsync() => liftIO(async _ =>\n    {\n        var first = await Task.FromResult(1);\n        var second = await Task.FromResult(2);\n\n        return first + second;\n    });\n\n    [Fact]\n    public void TopHatSerialisationTest()\n    {\n        var t1 = new TopHat(1, 1416);\n        var t3 = new TopHat(1, 1413);\n\n        var str = JsonConvert.SerializeObject(t1);\n\n        var t2 = JsonConvert.DeserializeObject<TopHat>(str);\n\n        Assert.True(t2 == t1);\n        Assert.True(t3 != t1);\n    }\n}\n\n//https://github.com/louthy/language-ext/issues/242\nnamespace Core.Tests\n{\n    using static ExternalSystem;\n\n    public class ExternalOptionsAndEithersTests\n    {\n        [Fact]\n        public void what_i_desire_EitherAsync()\n        {\n            EitherT<Error, IO, Pixel> GetPixelE(PixelId id) =>\n                GetPixel(id).ToEither(new Error(\"pixel not found\"));\n\n            var program =\n                from pixel in GetPixelE(new PixelId(\"wkrp\"))\n                from id in GenerateLinkId(pixel.Value)\n                from resource in ScrapeUrl(\"http://google.com\")\n                select resource;\n\n            program.Match(\n                Right: _ => Assert.Fail(\"this should not pass\"),\n                Left: e => Assert.Equal(\"pixel not found\", e.Value)\n            );\n        }\n    }\n\n    static class ExternalSystem\n    {\n        public record Error(string Value);\n\n        public static OptionT<IO, Pixel> GetPixel(PixelId id) =>\n            OptionT<IO, Pixel>.None;\n\n        public static EitherT<Error, IO, string> GenerateLinkId(PixelId pixelId) =>\n            Right<Error, string>($\"{pixelId}-1234\");\n\n        public static EitherT<Error, IO, WebResource> ScrapeUrl(string url) =>\n            Right<Error, WebResource>(new WebResource(200));\n\n        public record WebResource(int Value);\n        public record PixelId(string Value);\n        public record Pixel(PixelId Value);\n    }\n}\n\nnamespace Issues\n{\n    public record CollectorId(int Value);\n    public record TenantId(int Value);\n    public record UserId(int Value);\n    public record Instant(int Value);\n\n    public class Collector : Record<Collector>, ISerializable\n    {\n        public CollectorId Id { get; }\n        public string Name { get; }\n        public TenantId CurrentTenant { get; }\n        public UserId AssignedBy { get; }\n        public Instant InstantAssigned { get; }\n        public Collector(CollectorId id, string name, TenantId tenant, UserId assignedBy, Instant dateAssigned)\n        {\n            Id = id;\n            Name = name;\n            CurrentTenant = tenant;\n            AssignedBy = assignedBy;\n            InstantAssigned = dateAssigned;\n        }\n\n        Collector(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }\n    }\n\n    public class GitterTests\n    {\n        [Fact]\n        public void TestSerial()\n        {\n            var x = new Collector(new CollectorId(1), \"nick\", new TenantId(2), new UserId(3), new Instant(4));\n            var y = new Collector(new CollectorId(1), \"nick\", new TenantId(2), new UserId(3), new Instant(4));\n\n            var z1 = x == y;\n            var z2 = x.Equals(y);\n            var z3 = x.Equals((object)y);\n\n            var r = JsonConvert.SerializeObject(x);\n            var r2 = JsonConvert.DeserializeObject<Collector>(r);\n        }\n    }\n\n    public static class Issue251\n    {\n        public record Error(string Value);\n        public class ErrorException(Error error) : Exception(error.Value)\n        {\n            public readonly Error Error = error;\n        }\n\n        public static OptionT<IO, A> AsOptionT<A>(this Either<Error, Option<A>> ma) =>\n            ma.Match(\n                Right: liftIO,\n                Left: e => lift<A>(() => throw new ErrorException(e)));\n\n        public static OptionT<IO, A> AsTryOption<A>(this Either<Error, Option<A>> ma) =>\n            ma.Match(\n                Right: liftIO,\n                Left: e => lift<A>(() => throw new ErrorException(e)));\n\n        public static OptionT<IO, A> AsOptionT<A>(this Task<Either<Error, Option<A>>> ma) =>\n            ma.Map(either => either.AsTryOption()).Flatten();\n\n        public static Error AsError(this Exception ex) =>\n            ex is ErrorException err\n                ? err.Error\n                : new Error(ex.Message);\n    }\n\n    public class Issue263\n    {\n        public readonly Func<long, Unit> fire = i => unit;\n\n        public void Test() => ignore(act(fire));\n    }\n\n    public class Issue261\n    {\n        [Fact]\n        public void Test1()\n        {\n            var ma = Writer.pure<Seq<string>, int>(100);\n            var mb = Writer.pure<Seq<string>, int>(200);\n\n            var mc = from x in ma\n                     from y in mb\n                     from _1 in tell(Seq(\"Hello\"))\n                     from _2 in tell(Seq(\"World\"))\n                     from _3 in tell(Seq($\"the result is {x + y}\"))\n                     select x + y;\n\n            var r = mc.Run();\n\n            Assert.True(r.Value == 300);\n            Assert.True(r.Output == Seq(\"Hello\", \"World\", \"the result is 300\"));\n        }\n\n        [Fact]\n        public void Test2()\n        {\n            var ma = Writer.pure<Lst<string>, int>(100);\n            var mb = Writer.pure<Lst<string>, int>(200);\n\n            var mc = from x in ma\n                     from y in mb\n                     from _1 in tell(List(\"Hello\"))\n                     from _2 in tell(List(\"World\"))\n                     from _3 in tell(List($\"the result is {x + y}\"))\n                     select x + y;\n\n            var r = mc.Run();\n\n            Assert.True(r.Value == 300);\n            Assert.True(r.Output == List(\"Hello\", \"World\", \"the result is 300\"));\n        }\n\n        [Fact]\n        public void Test3()\n        {\n            var ma = (100, Seq<string>());\n            var mb = (200, Seq<string>());\n\n            var mc = from x in Writer.write(ma)\n                     from y in Writer.write(mb)\n                     from _1 in tell(Seq(\"Hello\"))\n                     from _2 in tell(Seq(\"World\"))\n                     from _3 in tell(Seq($\"the result is {x + y}\"))\n                     select x + y;\n\n            var r = mc.Run();\n\n            Assert.True(r.Value == 300);\n            Assert.True(r.Output == Seq(\"Hello\", \"World\", \"the result is 300\"));\n        }\n    }\n\n    public class Issue376\n    {\n        public static EitherT<string, IO, int> Op1() =>\n            Pure(1);\n\n        public static EitherT<string, IO, int> Op2() =>\n            IO.pure(2);\n\n        public static EitherT<string, IO, int> Op3() =>\n            Fail(\"error\");\n\n        public static EitherT<string, IO, int> Calculate(int x, int y, int z) =>\n            Pure(x + y + z);\n\n        public static int Test() =>\n            (from x in Op1()\n             from y in Op2()\n             from z in Op3()\n             from w in Calculate(x, y, z)\n             select w)\n            .IfLeft(0)\n            .As().Run();\n    }\n\n    public class Issue376_2\n    {\n        static async Task<Either<string, int>> Op1() => await 1.AsTask();\n        static async Task<Either<string, int>> Op2() => await 2.AsTask();\n        static async Task<Either<string, int>> Op3() => await \"error\".AsTask();\n        static async Task<Either<string, int>> Calculate(int x, int y, int z) => await Task.FromResult(x + y + z);\n\n        public static IO<Either<string, int>> Test() =>\n            (from x in Op1().ToIO()\n             from y in Op2().ToIO()\n             from z in Op3().ToIO()\n             from w in Calculate(x, y, z).ToIO()\n             select w)\n            .Run().As();\n    }\n\n    public class Issue376_3\n    {\n        static async Task<Option<int>> Op1() => await 1.AsTask();\n        static async Task<Option<int>> Op2() => await 2.AsTask();\n        static async Task<Option<int>> Op3() => await Option<int>.None.AsTask();\n        static async Task<Option<int>> Calculate(int x, int y, int z) => await Task.FromResult(x + y + z);\n\n        public static IO<Option<int>> Test() =>\n            (from x in Op1().ToIO()\n             from y in Op2().ToIO()\n             from z in Op3().ToIO()\n             from w in Calculate(x, y, z).ToIO()\n             select w).Run().As();\n    }\n\n    public class Issue533\n    {\n        [Fact]\n        public void Test()\n        {\n\n            var someData = Enumerable\n                .Range(0, 30000)\n                .Select(_ => Guid.NewGuid().ToString())\n                .ToArray();\n\n            var result = someData\n                            .Select(Some)\n                            .AsIterable()\n                            .Traverse(x => x)\n                            .Map(x => x.ToArray())\n                            .As();\n        }\n\n    }\n\n    // https://stackoverflow.com/questions/54609459/languageext-eitherasyn-with-aggegrate-bind-with-validation\n    public class StackOverflow_54609459\n    {\n        public class Error { }\n        public class HostResponse { }\n        public class Response { }\n\n        public class Command {\n\n            public readonly string Name;\n\n            static Either<Error, Func<string, EitherT<Error, IO, R>>> GetCommand<R>(\n                Map<string, Func<string, EitherT<Error, IO, R>>> commandMap, \n                Command hostCommand) =>\n                     commandMap.Find(hostCommand.Name)\n                               .ToEither(new Error());\n\n            internal static EitherT<Error, IO, R> ExecuteCommand<R>(\n                Func<string, EitherT<Error, IO, R>> command,\n                Command cmd) =>\n                    command(cmd.Name);\n\n            static Either<Error, Unit> Validate<R>(\n                Map<string, Func<string, EitherT<Error, IO, R>>> commandMap, \n                Command hostCommand) =>\n                    commandMap.Find(hostCommand.Name)\n                              .Map(_ => unit)\n                              .ToEither(new Error());\n\n            public static EitherT<Error, IO, Seq<R>> ExecuteAllAsync<R>(\n                Map<string, Func<string, EitherT<Error, IO, R>>> commandMap,\n                Seq<Command> hostCommands) =>\n                    hostCommands.Map(cmd =>\n                        from _ in Validate(commandMap, cmd).ToIO()\n                        from f in GetCommand(commandMap, cmd).ToIO()\n                        from r in ExecuteCommand(f, cmd)\n                        select r)\n                       .Traverse(x => x).As();\n        }\n    }\n    \n    \n    public class Issue1340\n    {\n        public sealed record CustomExpected(string Message, int Code, string Another) : Expected(Message, Code);\n\n        [Fact]\n        public void Test()\n        {\n            // Arrange\n            var      expected = new CustomExpected(\"Name\", 100, \"This is loss\");\n            Eff<int> effect   = liftEff<int>(() => expected);\n\n            // Act\n            Fin<int> fin = effect.Run();\n\n            // Assert\n            fin.Match(_ => Assert.True(false),\n                      error =>\n                      {\n                          Assert.Equal(error.Code, expected.Code);\n                          Assert.Equal(error.Message, expected.Message);\n\n                          var fail = (CustomExpected)error;\n                          Assert.Equal(fail.Another, expected.Another);\n                      });\n\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/IteratorTests/IteratorTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace LanguageExt.Tests.IteratorTests;\n\npublic class IteratorTests\n{\n    [Fact]\n    public void Iterator_BasicBehavior_Test()\n    {\n        // Arrange\n        var numbers = new List<int> { 1, 2, 3, 4 };\n        var iterator = numbers.GetIterator();\n\n        // Act and Assert\n        Assert.False(iterator.IsEmpty);                             // Iterator should not be empty\n        Assert.Equal(1, iterator.Head);                             // Verify the first element (Head)\n        Assert.Equal(2, iterator.Tail.Head);                        // Navigate to the Tail and check the next Head\n        Assert.Equal(3, iterator.Tail.Tail.Head);                   // Keep checking subsequent elements\n        Assert.Equal(4, iterator.Tail.Tail.Tail.Head);\n        Assert.True(iterator.Tail.Tail.Tail.Tail.IsEmpty);          // Check if the iterator ends correctly\n    }\n\n    [Fact]\n    public async Task Iterator_ThreadSafety_Test()\n    {\n        // Arrange\n        var numbers = Enumerable.Range(1, 1000).ToList();\n        var iterator = numbers.GetIterator();\n\n        // Act\n        var tasks = Enumerable.Range(0, 5).Select(\n            _ =>\n                Task.Run(() =>\n                         {\n                             var current = iterator;\n                             while (!current.IsEmpty)\n                             {\n                                 ignore(current.Head);   // Access the head\n                                 current = current.Tail; // Access the tail\n                             }\n                         })).ToArray();\n\n        // Assert\n        await Task.WhenAll(tasks); // Ensure all tasks complete without throwing exceptions\n    }\n\n    [Fact]\n    public void Iterator_Nil_Test()\n    {\n        // Arrange\n        var iterator = Iterator<int>.Nil.Default;\n\n        // Act and Assert\n        Assert.True(iterator.IsEmpty);                              // Nil should be empty\n        Assert.Throws<InvalidOperationException>(() => iterator.Head); // Accessing the Head should throw\n        Assert.Same(iterator, iterator.Tail);                       // The Tail of Nil should be itself\n    }\n\n    [Fact]\n    public void Iterator_MultipleEnumerationPrevention_Test()\n    {\n        // Arrange\n        var enumerator = \"Lazy Evaluation\".GetIterator();\n\n        // Act\n        var head1 = enumerator.Head;\n        var tail1 = enumerator.Tail; // Forces evaluation\n\n        // Attempt to re-access the same enumerator\n        var head2 = enumerator.Head; // Should be the same value, from cache\n\n        // Assert\n        Assert.Equal(head1, head2); // Items should not be re-enumerated\n    }\n\n    [Fact]\n    public void Iterator_EmptyEnumerable_Test()\n    {\n        // Arrange\n        var iterator = Enumerable.Empty<int>().GetIterator();\n\n        // Act and Assert\n        Assert.True(iterator.IsEmpty);                              // Empty iterator should be empty\n        Assert.Throws<InvalidOperationException>(() => iterator.Head);\n        Assert.Equal(iterator, iterator.Tail);                       // Tail of an empty iterator should be itself\n    }\n\n    [Fact]\n    public void Iterator_ThreadSafety_Test_WithContentCheck()\n    {\n        // Arrange\n        var threads        = 5;\n        var numbers        = Enumerable.Range(1, 1000).ToList();\n        var iterator       = numbers.GetIterator();\n        var resultingLists = new List<List<int>>();\n\n        for (var i = 0; i < threads; i++)\n        {\n            resultingLists.Add(new List<int>());\n        }\n\n        // Act\n        Parallel.ForEach(Enumerable.Range(0, 5), ix =>\n        {\n            var current = iterator;\n            while (!current.IsEmpty)\n            {\n                lock (resultingLists[ix])\n                {\n                    resultingLists[ix].Add(current.Head); // Safely add the emitted value into the list\n                }\n\n                current = current.Tail;\n            }\n        });\n\n        // Assert\n        // The final list length should equal the source list's length (sequentially added values)\n        foreach (var resultList in resultingLists)\n        {\n            Assert.True(Enumerable.SequenceEqual(numbers, resultList));\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/LanguageExt.Tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <FileVersion>3.0.0.0</FileVersion>\n    <AssemblyVersion>3.0.0.0</AssemblyVersion>\n    <LangVersion>default</LangVersion>\n    <TargetFramework>net10.0</TargetFramework>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n  <ItemGroup>\n      <PackageReference Include=\"FluentAssertions\" Version=\"6.11.0\" />\n      <PackageReference Include=\"System.Reactive\" Version=\"6.0.0\" />\n      <PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.3\" />\n    <PackageReference Include=\"Nito.AsyncEx\" Version=\"5.1.2\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.7.0\" />\n    <PackageReference Include=\"xunit\" Version=\"2.7.0\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    <ProjectReference Include=\"..\\LanguageExt.FSharp\\LanguageExt.FSharp.csproj\" />\n    <ProjectReference Include=\"..\\LanguageExt.Parsec\\LanguageExt.Parsec.csproj\" />\n    <ProjectReference Include=\"..\\LanguageExt.Rx\\LanguageExt.Rx.csproj\" />\n    <ProjectReference Include=\"..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    <ProjectReference Include=\"..\\LanguageExt.XUnitExt\\LanguageExt.XUnitExt.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Service Include=\"{82a7f48d-3b50-4b1e-b82e-3ada8210c358}\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "LanguageExt.Tests/LensTests.cs",
    "content": "﻿/*\n TODO: Restore when we have SourceGen\n \nusing System;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class LensTests\n    {\n        [Fact]\n        public void LensMutate()\n        {\n            var car = new Car(\"Maserati\", \"Ghibli\", 20000);\n            var editor = new Editor(\"Joe Bloggs\", 50000, car);\n            var book = new Book(\"Editors of the World\", \"Sarah Bloggs\", editor);\n\n            var bookEditorCarMileage = lens(Book.editor, Editor.car, Car.mileage);\n            var mileage = bookEditorCarMileage.Get(book);\n            var book2 = bookEditorCarMileage.Set(25000, book);\n\n            Assert.True(book2.Editor.Car.Mileage == 25000);\n        }\n\n        [Fact]\n        public void CollectionsMutate()\n        {\n            var person = new Person(\"Paul\", \"Louth\", Map(\n                (1, new Appt(1, DateTime.Parse(\"1/1/2010\"), ApptState.NotArrived)),\n                (2, new Appt(2, DateTime.Parse(\"2/1/2010\"), ApptState.NotArrived)),\n                (3, new Appt(3, DateTime.Parse(\"3/1/2010\"), ApptState.NotArrived))));\n\n            Lens<Person, ApptState> arrive(int id) => \n                lens(Person.appts, Map<int, Appt>.item(id), Appt.state);\n\n            var person2 = arrive(2).Set(ApptState.Arrived, person);\n\n            Assert.True(person2.Appts[2].State == ApptState.Arrived);\n        }\n    }\n\n    [WithLens]\n    public partial class Person : Record<Person>\n    {\n        public readonly string Name;\n        public readonly string Surname;\n        public readonly Map<int, Appt> Appts;\n\n        public Person(string name, string surname, Map<int, Appt> appts)\n        {\n            Name = name;\n            Surname = surname;\n            Appts = appts;\n        }\n    }\n\n    [WithLens]\n    public partial class Appt : Record<Appt>\n    {\n        public readonly int Id;\n        public readonly DateTime StartDate;\n        public readonly ApptState State;\n\n        public Appt(int id, DateTime startDate, ApptState state)\n        {\n            Id = id;\n            StartDate = startDate;\n            State = state;\n        }\n    }\n\n    public enum ApptState\n    {\n        NotArrived,\n        Arrived,\n        DNA,\n        Cancelled\n    }\n\n    [WithLens]\n    public partial class Car : Record<Car>\n    {\n        public readonly string Make;\n        public readonly string Model;\n        public readonly int Mileage;\n\n        public Car(string make, string model, int mileage)\n        {\n            Make = make;\n            Model = model;\n            Mileage = mileage;\n        }\n    }\n\n    [WithLens]\n    public partial class Editor : Record<Editor>\n    {\n        public readonly string Name;\n        public readonly int Salary;\n        public readonly Car Car;\n\n        public Editor(string name, int salary, Car car)\n        {\n            Name = name;\n            Salary = salary;\n            Car = car;\n        }\n    }\n\n    [WithLens]\n    public partial class Book : Record<Book>\n    {\n        public readonly string Name;\n        public readonly string Author;\n        public readonly Editor Editor;\n\n        public Book(string name, string author, Editor editor)\n        {\n            Name = name;\n            Author = author;\n            Editor = editor;\n        }\n    }\n}\n*/\n\n"
  },
  {
    "path": "LanguageExt.Tests/LinqTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing LanguageExt.UnsafeValueAccess;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class LinqTests\n{\n    [Fact]\n    public void EnumerableString()\n    {\n        var opt  = Some(\"pre \");\n        var list = Some(new[] { \"hello\", \"world\" }.AsEnumerable());\n\n        var res = from a in opt.ToIterable()\n                  from x in list.ToIterable()\n                  from y in x\n                  select a + y;\n\n        Assert.True(res.Head.ValueUnsafe()        == \"pre hello\");\n        Assert.True(res.Tail.Head.ValueUnsafe() == \"pre world\");\n\n        opt = None;\n\n        res = from a in opt.ToIterable()\n              from x in list.ToIterable()\n              from y in x\n              select a + y;\n\n        Assert.True(!res.Any());\n    }\n\n\n    [Fact]\n    public void MixedLinq()\n    {\n        var oa = Some(1);\n        var lb = List(2, 3, 4, 5);\n\n        var r1 =\n            from a in oa.Map(x => List(x)) // a : int\n            from b in Some(lb)             // b : int\n            select a + b;\n\n        Assert.True(r1 == Some(List(1, 2, 3, 4, 5)));\n    }\n\n    [Fact]\n    public void WithOptionSomeList()\n    {\n        var res = from v in GetOptionValue(true).ToIterable()\n                  from r in Range(1, 10)\n                  select v * r;\n\n        var res2 = res.ToList();\n\n        Assert.True(res2.Count() == 10);\n        Assert.True(res2[0]      == 10);\n        Assert.True(res2[9]      == 100);\n    }\n\n    [Fact]\n    public void WithOptionNoneList()\n    {\n        var res = from v in GetOptionValue(false).ToIterable()\n                  from r in Range(1, 10)\n                  select v * r;\n\n        Assert.True(!res.Any());\n    }\n    \n    [Fact]\n    public void WithEitherRightList()\n    {\n        var res = from v in toSeq(GetEitherValue(true))\n                  from r in Range(1, 10)\n                  select v * r;\n\n        var res2 = res.ToList();\n\n        Assert.True(res.Count() == 10);\n        Assert.True(res2[0]     == 10);\n        Assert.True(res2[9]     == 100);\n    }\n\n    [Fact]\n    public void WithEitherLeftList()\n    {\n        var res = from v in toSeq(GetEitherValue(false))\n                  from r in Range(1, 10)\n                  select v * r;\n\n        Assert.True(res.Count() == 0);\n    }\n    \n    [Fact]\n    public void WhereArrayTest()\n    {\n        var res1 = from v in Array(1, 2, 3, 4, 5)\n                   where v < 3\n                   select v;\n\n        Assert.True(res1.Count == 2);\n    }\n\n    [Fact]\n    public void WhereOptionTest()\n    {\n        var res1 = from v in GetOptionValue(true)\n                   where v == 10\n                   select v;\n\n        Assert.True(res1.IfNone(0) == 10);\n\n        var res2 = from v in GetOptionValue(false)\n                   where v == 10\n                   select v;\n\n        Assert.True(res2.IfNone(0) == 0);\n    }\n\n    [Fact]\n    public void OptionAndOrTest()\n    {\n        Option<int> optional1 = None;\n        Option<int> optional2 = Some(10);\n        Option<int> optional3 = Some(20);\n\n        var res = from x in optional1 || optional2\n                  from y in optional3\n                  select x + y;\n\n        Assert.True(res == Some(30));\n    }\n\n    private Option<int> GetOptionValue(bool select) =>\n        select\n            ? Some(10)\n            : None;\n\n    private Either<string, int> GetEitherValue(bool select)\n    {\n        if (select)\n            return 10;\n        else\n            return \"left\";\n    }\n\n\n    [Fact]\n    public void OptionLst1()\n    {\n        var list = List(1, 2, 3, 4);\n        var opt  = Some(5);\n\n        var res = from y in opt.ToList()\n                  from x in list\n                  select x + y;\n    }\n\n\n    [Fact]\n    public void OptionNoneTest1()\n    {\n        var res1 = from x in None\n                   from y in Some(123)\n                   from z in Some(456)\n                   select y + z;\n\n        var res2 = from y in Some(123)\n                   from x in None\n                   from z in Some(456)\n                   select y + z;\n\n        var res3 = from y in Some(123)\n                   from x in None\n                   from z in Some(456)\n                   select y + z;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ListMatchingTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class ListMatchingTests\n{\n    [Fact]\n    public void RecursiveMatchSumTest()\n    {\n        var list0 = List<int>();\n        var list1 = List(10);\n        var list5 = List(10,20,30,40,50);\n\n        Assert.True(Sum(list0) == 0);\n        Assert.True(Sum(list1) == 10);\n        Assert.True(Sum(list5) == 150);\n    }\n\n    public int Sum(IEnumerable<int> list) =>\n        match(list,\n              ()      => 0,\n              x       => x,\n              (x, xs) => x + Sum(xs));\n\n    [Fact]\n    public void RecursiveMatchMultiplyTest()\n    {\n        var list0 = List<int>();\n        var list1 = List(10);\n        var list5 = List(10, 20, 30, 40, 50);\n\n        Assert.True(Multiply(list0) == 0);\n        Assert.True(Multiply(list1) == 10);\n        Assert.True(Multiply(list5) == 12000000);\n    }\n\n    public int Multiply(IEnumerable<int> list) =>\n        list.Match(\n            ()      => 0,\n            x       => x,\n            (x, xs) => x * Multiply(xs));\n\n    [Fact]\n    public void AnotherRecursiveMatchSumTest()\n    {\n        var list0 = List<int>();\n        var list1 = List(10);\n        var list5 = List(10, 20, 30, 40, 50);\n\n        Assert.True(AnotherSum(list0) == 0);\n        Assert.True(AnotherSum(list1) == 10);\n        Assert.True(AnotherSum(list5) == 150);\n    }\n\n    public int AnotherSum(IEnumerable<int> list) =>\n        match(list,\n              ()      => 0,\n              (x, xs) => x + AnotherSum(xs));\n\n    [Fact]\n    public void AnotherRecursiveMatchMultiplyTest()\n    {\n        var list0 = List<int>();\n        var list1 = List(10);\n        var list5 = List(10, 20, 30, 40, 50);\n\n        Assert.True(AnotherMultiply(list0) == 1);\n        Assert.True(AnotherMultiply(list1) == 10);\n        Assert.True(AnotherMultiply(list5) == 12000000);\n    }\n\n    public int AnotherMultiply(IEnumerable<int> list) =>\n        list.Match(\n            ()      => 1,\n            (x, xs) => x * AnotherMultiply(xs));\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ListTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing System.Linq;\nusing static LanguageExt.List;\n\nnamespace LanguageExt.Tests;\n\npublic class ListTests\n{\n    [Fact]\n    public void ConsTest1()\n    {\n        var test = 1.Cons(2.Cons(3.Cons(4.Cons(5.Cons(empty<int>())))));\n\n        var array = test.ToArray();\n\n        Assert.True(array[0] == 1);\n        Assert.True(array[1] == 2);\n        Assert.True(array[2] == 3);\n        Assert.True(array[3] == 4);\n        Assert.True(array[4] == 5);\n    }\n\n    [Fact]\n    public void ListConstruct()\n    {\n        var test = List(1, 2, 3, 4, 5);\n\n        var array = test.ToArray();\n\n        Assert.True(array[0] == 1);\n        Assert.True(array[1] == 2);\n        Assert.True(array[2] == 3);\n        Assert.True(array[3] == 4);\n        Assert.True(array[4] == 5);\n    }\n\n    [Fact]\n    public void MapTest()\n    {\n        // Generates 10,20,30,40,50\n        var input   = List(1, 2, 3, 4, 5);\n        var output1 = map(input, x => x * 10);\n\n        // Generates 30,40,50\n        var output2 = filter(output1, x => x > 20);\n\n        // Generates 120\n        var output3 = fold(output2, 0, (x, s) => s + x);\n\n        Assert.True(output3 == 120);\n    }\n\n    [Fact]\n    public void ReduceTest()\n    {\n        // Generates 10,20,30,40,50\n        var input   = List(1, 2, 3, 4, 5);\n        var output1 = map(input, x => x * 10);\n\n        // Generates 30,40,50\n        var output2 = filter(output1, x => x > 20);\n\n        // Generates 120\n        var output3 = reduce(output2, (x, s) => s + x);\n\n        Assert.True(output3 == 120);\n    }\n\n    [Fact]\n    public void MapTestFluent()\n    {\n        var res = List(1, 2, 3, 4, 5)\n                 .Map(x => x * 10)\n                 .Filter(x => x > 20)\n                 .Fold(0, (x, s) => s + x);\n\n        Assert.True(res == 120);\n    }\n\n    [Fact]\n    public void ReduceTestFluent()\n    {\n        var res = List(1, 2, 3, 4, 5)\n                 .Map(x => x * 10)\n                 .Filter(x => x > 20)\n                 .Reduce((x, s) => s + x);\n\n        Assert.True(res == 120);\n    }\n\n    [Fact]\n    public void RangeTest1()\n    {\n        var r = Range(0, 10).AsIterable();\n        for (int i = 0; i < 10; i++)\n        {\n            Assert.True(r.First() == i);\n            r = r.Skip(1);\n        }\n    }\n\n    [Fact]\n    public void RangeTest2()\n    {\n        var r = Range(0, 100, 10).AsIterable();\n        for (int i = 0; i < 10; i+=10)\n        {\n            Assert.True(r.First() == i);\n            r = r.Skip(1);\n        }\n    }\n\n    [Fact]\n    public void RangeTest4()\n    {\n        var r = Range('a', 'f');\n        Assert.True(String.Join(\"\", r) == \"abcdef\");\n    }\n\n    [Fact]\n    public void RangeTest5()\n    {\n        var r = Range('f', 'a');\n        Assert.True(String.Join(\"\", r) == \"fedcba\");\n    }\n\n    [Fact]\n    public void RepeatTest()\n    {\n        var r = repeat(\"Hello\", 10);\n\n        foreach (var item in r)\n        {\n            Assert.True(item == \"Hello\");\n        }\n    }\n\n\n    [Fact]\n    public void GenerateTest()\n    {\n        var r = generate(10, i => \"Hello \" + i );\n\n        for (int i = 0; i < 10; i++)\n        {\n            Assert.True(r.First() == \"Hello \" +i);\n            r = r.Skip(1);\n        }\n    }\n\n    [Fact]\n    public void UnfoldTest()\n    {\n        var test = List(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181);\n\n        var fibs = take(unfold((0, 1), tup => map(tup, (a, b) => Some((a, (b, a + b))))), 20);\n\n        Assert.True( test.SequenceEqual(fibs) );\n    }\n\n    [Fact]\n    public void UnfoldTupleTest()\n    {\n        var test = List(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181);\n\n        var fibs = take( unfold( (0, 1), (a, b) => Some((a, b, a + b)) ), 20);\n\n        Assert.True(test.SequenceEqual(fibs));\n    }\n\n    [Fact]\n    public void UnfoldSingleTest()\n    {\n        var e = new Exception(\"Outer\", new Exception(\"Inner\"));\n\n        var list = unfold(e, (state) =>\n                                 state == null\n                                     ? None\n                                     : Optional(state.InnerException)\n        );\n\n        var res = list.ToList();\n\n        Assert.True(res[0].Message == \"Outer\" && res[1].Message == \"Inner\");\n    }\n\n    [Fact]\n    public void ReverseListTest1()\n    {\n        var list = List(1, 2, 3, 4, 5);\n        var rev  = list.Rev();\n\n        Assert.True(rev[0] == 5);\n        Assert.True(rev[4] == 1);\n    }\n\n    [Fact]\n    public void ReverseListTest2()\n    {\n        var list = List(1, 2, 3, 4, 5);\n        var rev  = list.Rev();\n\n        Assert.True(rev.IndexOf(1) == 4, \"Should have been 4, actually is: \" + rev.IndexOf(1));\n        Assert.True(rev.IndexOf(5) == 0, \"Should have been 0, actually is: \" + rev.IndexOf(5));\n    }\n\n    [Fact]\n    public void ReverseListTest3()\n    {\n        var list = List(1, 1, 2, 2, 2);\n        var rev  = list.Rev();\n\n        Assert.True(rev.LastIndexOf(1) == 4, \"Should have been 4, actually is: \" + rev.LastIndexOf(1));\n        Assert.True(rev.LastIndexOf(2) == 2, \"Should have been 2, actually is: \" + rev.LastIndexOf(5));\n    }\n\n    [Fact]\n    public void OpEqualTest()\n    {\n        var goodOnes = List(\n            (List(1, 2, 3), List(1, 2, 3)),\n            (Lst<int>.Empty, Lst<int>.Empty)\n        );\n        var badOnes = List(\n            (List(1, 2, 3), List(1, 2, 4)),\n            (List(1, 2, 3), Lst<int>.Empty)\n        );\n\n        goodOnes.Iter(t => t.Iter((fst, snd) =>\n                                  {\n                                      Assert.True(fst  == snd, $\"'{fst}' == '{snd}'\");\n                                      Assert.False(fst != snd, $\"'{fst}' != '{snd}'\");\n                                  }));\n\n        badOnes.Iter(t => t.Iter((fst, snd) =>\n                                 {\n                                     Assert.True(fst  != snd, $\"'{fst}' != '{snd}'\");\n                                     Assert.False(fst == snd, $\"'{fst}' == '{snd}'\");\n                                 }));\n    }\n\n    [Fact]\n    public void IterSimpleTest()\n    {\n        var embeddedSideEffectResult = 0;\n        var expression = from dummy in Some(unit).ToIterable()\n                         from i in List(2, 3, 5)\n                         let _ = fun(() => embeddedSideEffectResult += i)()\n                         select i;\n\n        Assert.Equal(0, embeddedSideEffectResult);\n\n        var sideEffectByAction = 0;\n\n        expression.Iter(i => sideEffectByAction += i * i);\n        Assert.Equal(2     + 3     + 5, embeddedSideEffectResult);\n        Assert.Equal(2 * 2 + 3 * 3 + 5 * 5, sideEffectByAction);\n    }\n\n    [Fact]\n    public void IterPositionalTest()\n    {\n        var embeddedSideEffectResult = 0;\n        var expression = from dummy in Some(unit).ToIterable()\n                         from i in List(2, 3, 5)\n                         let _ = fun(() => embeddedSideEffectResult += i)()\n                         select i;\n\n        Assert.Equal(0, embeddedSideEffectResult);\n\n        var sideEffectByAction = 0;\n\n        expression.Iter((pos, i) => sideEffectByAction += i * pos);\n        Assert.Equal(2     + 3     + 5, embeddedSideEffectResult);\n        Assert.Equal(2 * 0 + 3 * 1 + 5 * 2, sideEffectByAction);\n    }\n\n    [Fact]\n    public void ConsumeTest()\n    {\n        var embeddedSideEffectResult = 0;\n        System.Collections.Generic.IEnumerable<int> expression = from dummy in Some(unit).ToIterable()\n                                                                 from i in List(2, 3, 5)\n                                                                 let _ = fun(() => embeddedSideEffectResult += i)()\n                                                                 select i;\n\n        Assert.Equal(0, embeddedSideEffectResult);\n        expression.Consume();\n        Assert.Equal(2 + 3 + 5, embeddedSideEffectResult);\n    }\n        \n    [Fact]\n    public void SkipLastTest1()\n    {\n        var list = List(1, 2, 3, 4, 5);\n\n        var skipped = list.SkipLast().AsIterable().ToLst();\n\n        Assert.True(skipped == List(1, 2, 3, 4));\n    }\n\n    [Fact]\n    public void SkipLastTest2()\n    {\n        var list = List<int>();\n\n        var skipped = list.SkipLast().AsIterable().ToLst();\n\n        Assert.True(skipped == list);\n    }\n\n    [Fact]\n    public void SkipLastTest3()\n    {\n        var list = List(1, 2, 3, 4, 5);\n\n        var skipped = list.SkipLast(2).AsIterable().ToLst();\n\n        Assert.True(skipped == List(1, 2, 3));\n    }\n\n    [Fact]\n    public void SkipLastTest4()\n    {\n        var list = List<int>();\n\n        var skipped = list.SkipLast(2).AsIterable().ToLst();\n\n        Assert.True(skipped == list);\n    }\n\n    [Fact]\n    public void SetItemTest()\n    {\n        Lst<int> lint = new Lst<int>();\n        lint = lint.Insert(0, 0).Insert(1, 1).Insert(2, 2).Insert(3, 3);\n\n        Assert.True(lint[0] == 0);\n        Assert.True(lint[1] == 1);\n        Assert.True(lint[2] == 2);\n        Assert.True(lint[3] == 3);\n\n        lint = lint.SetItem(2, 500);\n\n        Assert.True(lint[0] == 0);\n        Assert.True(lint[1] == 1);\n        Assert.True(lint[2] == 500);\n        Assert.True(lint[3] == 3);\n    }\n\n    [Fact]\n    public void RemoveAllTest()\n    {\n        var test = List(1, 2, 3, 4, 5);\n        Assert.True(test.RemoveAll(x => x % 2 == 0) == List(1, 3, 5));\n    }\n\n    [Fact]\n    public void RemoveAtInsertTest()\n    {\n        Lst<int> lint = new Lst<int>();\n        lint = lint.Insert(0, 0).Insert(1, 1).Insert(2, 2).Insert(3, 3);\n\n        Assert.True(lint[0] == 0);\n        Assert.True(lint[1] == 1);\n        Assert.True(lint[2] == 2);\n        Assert.True(lint[3] == 3);\n\n        lint = lint.RemoveAt(2);\n\n        Assert.True(lint[0] == 0);\n        Assert.True(lint[1] == 1);\n        Assert.True(lint[2] == 3);\n\n        lint = lint.Insert(2, 500);\n\n        Assert.True(lint[0] == 0);\n        Assert.True(lint[1] == 1);\n        Assert.True(lint[2] == 500);\n        Assert.True(lint[3] == 3);\n    }\n\n    [Fact]\n    public void RemoveRange()\n    {\n        var list = List(1, 2, 3, 4);\n\n        Assert.Equal(list.RemoveRange(2, 2), List(1, 2));\n        Assert.Throws<IndexOutOfRangeException>(() => list.RemoveRange(2, 3));\n    }\n\n    [Fact]\n    public void SetItemManyTest()\n    {\n        var range = IterableExtensions.AsIterable(Range(0, 100)).ToLst();\n        for (int i = 0; i < 100; i++)\n        {\n            range = range.SetItem(i, i * 2);\n            Assert.True(range[i] == i  * 2);\n            for(var b = 0; b < i; b++)\n            {\n                Assert.True(range[b] == b * 2);\n            }\n            for (var a = i + 1; a < 100; a++)\n            {\n                Assert.True(range[a] == a);\n            }\n        }\n    }\n\n    [Fact]\n    public void RemoveAtInsertManyTest()\n    {\n        var range = IterableExtensions.AsIterable(Range(0, 100)).ToLst();\n        for (int i = 0; i < 100; i++)\n        {\n            range = range.RemoveAt(i);\n            Assert.True(range.Count == 99);\n            range = range.Insert(i, i * 2);\n            Assert.True(range[i] == i * 2);\n            for (var b = 0; b < i; b++)\n            {\n                Assert.True(range[b] == b * 2);\n            }\n            for (var a = i + 1; a < 100; a++)\n            {\n                Assert.True(range[a] == a);\n            }\n        }\n    }\n\n    [Fact]\n    public void EqualsTest()\n    {\n        Assert.False(List(1, 2, 3).Equals(List<int>()));\n        Assert.False(List<int>().Equals(List<int>(1, 2, 3)));\n        Assert.True(List<int>().Equals(List<int>()));\n        Assert.True(List<int>(1).Equals(List<int>(1)));\n        Assert.True(List<int>(1, 2).Equals(List<int>(1, 2)));\n        Assert.False(List<int>(1, 2).Equals(List<int>(1, 2, 3)));\n        Assert.False(List<int>(1, 2, 3).Equals(List<int>(1, 2)));\n    }\n\n    [Fact]\n    public void ListShouldRemoveByReference()\n    {\n        var o0 = new Object();\n        var o1 = new Object();\n        var o2 = new Object();\n        var l  = List(o0, o1);\n        l = l.Remove(o2);\n        Assert.Equal(2, l.Count);\n        l = l.Remove(o0);\n        Assert.Equal(1, l.Count);\n        l = l.Remove(o1);\n        Assert.Equal(0, l.Count);\n    }\n\n    [Fact]\n    public void ListShouldRemoveByReferenceForReverseLists()\n    {\n        var o0 = new Object();\n        var o1 = new Object();\n        var o2 = new Object();\n        var l  = List(o0, o1).Reverse();\n        l = l.Remove(o2);\n        Assert.Equal(2, l.Count);\n        l = l.Remove(o0);\n        Assert.Equal(1, l.Count);\n        l = l.Remove(o1);\n        Assert.Equal(0, l.Count);\n    }\n\n    [Fact]\n    public void FoldTest()\n    {\n        var input   = List(1, 2, 3, 4, 5);\n        var output1 = fold(input, \"\", (s, x) => s + x.ToString());\n        Assert.Equal(\"12345\", output1);\n    }\n\n    [Fact]\n    public void FoldBackTest()\n    {\n        var input   = List(1, 2, 3, 4, 5);\n        var output1 = foldBack(input, \"\", (s, x) => s + x.ToString());\n        Assert.Equal(\"54321\", output1);\n    }\n\n    [Fact]\n    public void FoldWhileTest()\n    {\n        var input = List(10, 20, 30, 40, 50);\n\n        var output1 = foldWhile(input, \"\", (s, x) => s + x.ToString(), x => x < 40);\n        Assert.Equal(\"102030\", output1);\n\n        var output2 = foldWhile(input, \"\", (s, x) => s + x.ToString(), (string s) => s.Length < 6);\n        Assert.Equal(\"102030\", output2);\n\n        var output3 = foldWhile(input, 0, (s, x) => s + x, preditem: x => x < 40);\n        Assert.Equal(60, output3);\n\n        var output4 = foldWhile(input, 0, (s, x) => s + x, predstate: s => s < 60);\n        Assert.Equal(60, output4);\n    }\n\n    [Fact]\n    public void FoldBackWhileTest()\n    {\n        var input = List(10, 20, 30, 40, 50);\n\n        var output1 = foldBackWhile(input, \"\", (s, x) => s + x.ToString(), x => x >= 40);\n        Assert.Equal(\"5040\", output1);\n\n        var output2 = foldBackWhile(input, \"\", (s, x) => s + x.ToString(), (string s) => s.Length < 4);\n        Assert.Equal(\"5040\", output2);\n\n        var output3 = foldBackWhile(input, 0, (s, x) => s + x, preditem: x => x >= 40);\n        Assert.Equal(90, output3);\n\n        var output4 = foldBackWhile(input, 0, (s, x) => s + x, predstate: s => s < 90);\n        Assert.Equal(90, output4);\n    }\n\n    [Fact]\n    public void FoldUntilTest()\n    {\n        var input = List(10, 20, 30, 40, 50);\n\n        var output1 = foldUntil(input, \"\", (s, x) => s + x.ToString(), x => x >= 40);\n        Assert.Equal(\"102030\", output1);\n\n        var output2 = foldUntil(input, \"\", (s, x) => s + x.ToString(), (string s) => s.Length >= 6);\n        Assert.Equal(\"102030\", output2);\n\n        var output3 = foldUntil(input, 0, (s, x) => s + x, preditem: x => x >= 40);\n        Assert.Equal(60, output3);\n\n        var output4 = foldUntil(input, 0, (s, x) => s + x, predstate: s => s >= 60);\n        Assert.Equal(60, output4);\n    }\n\n    [Fact]\n    public void FoldBackUntilTest()\n    {\n        var input = List(10, 20, 30, 40, 50);\n\n        var output1 = foldBackUntil(input, \"\", (s, x) => s + x.ToString(), x => x < 40);\n        Assert.Equal(\"5040\", output1);\n\n        var output2 = foldBackUntil(input, \"\", (s, x) => s + x.ToString(), (string s) => s.Length >= 4);\n        Assert.Equal(\"5040\", output2);\n\n        var output3 = foldBackUntil(input, 0, (s, x) => s + x, preditem: x => x < 40);\n        Assert.Equal(90, output3);\n\n        var output4 = foldBackUntil(input, 0, (s, x) => s + x, predstate: s => s >= 90);\n        Assert.Equal(90, output4);\n    }\n\n    [Fact]\n    public void itemLensGetShouldGetExistingValue()\n    {\n        var expected = \"3\";\n        var list     = List(\"0\",\"1\", \"2\", \"3\", \"4\", \"5\");\n        var actual   = Lst<string>.item(3).Get(list);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void itemLensGetShouldThrowExceptionForNonExistingValue()\n    {\n        Assert.Throws<IndexOutOfRangeException>(() =>\n                                                {\n                                                    var list   = List(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\");\n                                                    var actual = Lst<string>.item(10).Get(list);\n                                                });\n    }\n\n    [Fact]\n    public void itemOrNoneLensGetShouldGetExistingValue()\n    {\n        var expected = \"3\";\n        var list     = List(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\");\n        var actual   = Lst<string>.itemOrNone(3).Get(list);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void itemOrNoneLensGetShouldReturnNoneForNonExistingValue()\n    {\n        var expected = Option<string>.None;\n        var list     = List(\"0\", \"1\", \"2\", \"3\", \"4\", \"5\");\n        var actual   = Lst<string>.itemOrNone(10).Get(list);\n\n        Assert.Equal(expected, actual);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/MapTests.cs",
    "content": "﻿using static LanguageExt.Map;\nusing Xunit;\nusing System;\nusing System.Linq;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests;\n\npublic class MapTests\n{\n    [Fact]\n    public void MapGeneratorTest()\n    {\n        var m1 = Map<int, string>();\n        m1 = add(m1, 100, \"hello\");\n        Assert.True(m1.Count == 1 && containsKey(m1,100));\n    }\n\n    [Fact]\n    public void MapGeneratorAndMatchTest()\n    {\n        Map<int, string> m2 = [(1, \"a\"), (2, \"b\"), (3, \"c\")];\n\n        m2 = add(m2, 100, \"world\");\n\n        var res = match(\n            m2, 100,\n            v  => v,\n            () => \"failed\"\n        );\n\n        Assert.True(res == \"world\");\n    }\n\n    [Fact]\n    public void MapSetTest()\n    {\n        var m1 = Map( (1, \"a\"),\n                      (2, \"b\"),\n                      (3, \"c\") );\n\n        var m2 = setItem(m1, 1, \"x\");\n\n        match( \n            m1, 1, \n            Some: v => Assert.True(v == \"a\"), \n            None: () => Assert.False(true) \n        );\n\n        match(\n            find(m2, 1),\n            Some: v => Assert.True(v == \"x\"),\n            None: () => Assert.False(true)\n        );\n\n        Assert.Throws<ArgumentException>(() => setItem(m1, 4, \"y\"));\n    }\n\n        \n    [Fact]\n    public void MapOrdSetTest()\n    {\n        var m1 = Map<OrdStringOrdinalIgnoreCase, string, int>((\"one\", 1), (\"two\",2), (\"three\", 3));\n        var m2 = m1.SetItem(\"One\", -1);\n            \n        Assert.Equal(3, m2.Count);\n        Assert.Equal(-1, m2[\"one\"]);\n        Assert.DoesNotContain(\"one\", m2.Keys.AsEnumerable()); // make sure key got replaced, too\n        Assert.Contains(\"One\", m2.Keys.AsEnumerable());       // make sure key got replaced, too\n\n        Assert.Throws<ArgumentException>(() => m1.SetItem(\"four\", identity));\n\n        var m3 = m1.TrySetItem(\"four\", 0).Add(\"five\", 0).TrySetItem(\"Five\", 5);\n        Assert.Equal(5, m3[\"fiVe\"]);\n        Assert.DoesNotContain(\"four\", m3.Keys.AsEnumerable());\n        Assert.DoesNotContain(\"five\", m3.Keys.AsEnumerable());\n        Assert.Contains(\"Five\", m3.Keys.AsEnumerable());\n    }\n\n    [Fact]\n    public void MapAddInOrderTest()\n    {\n        var m = Map((1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = Map((1, 1), (2, 2));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = Map((1, 1), (2, 2), (3, 3));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = Map((1, 1), (2, 2), (3, 3), (4, 4));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n    [Fact]\n    public void MapAddInReverseOrderTest()\n    {\n        var m = Map((2, 2), (1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = Map((3, 3), (2, 2), (1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = Map((4, 4), (3, 3), (2, 2), (1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = Map((5, 5), (4, 4), (3, 3), (2, 2), (1, 1));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n    [Fact]\n    public void MapAddInMixedOrderTest()\n    {\n        var m = Map((5, 5), (1, 1), (3, 3), (2, 2), (4, 4));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n\n        m = Map((1, 1), (3, 3), (5, 5), (2, 2), (4, 4));\n        m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n        m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n    }\n\n\n    [Fact]\n    public void MapRemoveTest()\n    {\n        var m = Map((1, \"a\"),\n                    (2, \"b\"),\n                    (3, \"c\"),\n                    (4, \"d\"),\n                    (5, \"e\"));\n\n        m.Find(1).IfNone(() => failwith<string>(\"Broken 1\"));\n        m.Find(2).IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(3).IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(4).IfNone(() => failwith<string>(\"Broken 4\"));\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        Assert.True(m.Count == 5);\n\n        m = remove(m,4);\n        Assert.True(m.Count == 4);\n        Assert.True(m.Find(4).IsNone);\n        m.Find(1).IfNone(() => failwith<string>(\"Broken 1\"));\n        m.Find(2).IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(3).IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, 1);\n        Assert.True(m.Count == 3);\n        Assert.True(m.Find(1).IsNone);\n        m.Find(2).IfNone(() => failwith<string>(\"Broken 2\"));\n        m.Find(3).IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, 2);\n        Assert.True(m.Count == 2);\n        Assert.True(m.Find(2).IsNone);\n        m.Find(3).IfNone(() => failwith<string>(\"Broken 3\"));\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, 3);\n        Assert.True(m.Count == 1);\n        Assert.True(m.Find(3).IsNone);\n        m.Find(5).IfNone(() => failwith<string>(\"Broken 5\"));\n\n        m = remove(m, 5);\n        Assert.True(m.Count == 0);\n        Assert.True(m.Find(5).IsNone);\n    }\n\n    [Fact]\n    public void MassAddRemoveTest()\n    {\n        int max = 100000;\n\n        var items = LanguageExt.List.map(Range(1, max), _ => (Guid.NewGuid(), Guid.NewGuid()))\n                               .ToDictionary(kv => kv.Item1, kv => kv.Item2);\n\n        var m = Map<Guid, Guid>().AddRange(items);\n        Assert.True(m.Count == max);\n\n        foreach (var item in items)\n        {\n            Assert.True(m.ContainsKey(item.Key));\n            m = m.Remove(item.Key);\n            Assert.False(m.ContainsKey(item.Key));\n            max--;\n            Assert.True(m.Count == max);\n        }\n    }\n        \n    [Fact]\n    public void MapOrdSumTest()\n    {\n        var m1 = Map<OrdStringOrdinalIgnoreCase, string, int>((\"one\", 1), (\"two\",2));\n        var m2 = Map<OrdStringOrdinalIgnoreCase, string, int>((\"three\", 3));\n\n        var sum = m1 + m2;\n            \n        Assert.Equal(sum, m1.AddRange(m2));\n        Assert.Equal(m2, sum.Clear() + m2);\n    }\n\n\n    [Fact]\n    public void MapOptionTest()\n    {\n        var m = Map<(Option<int>, Option<int>), string>();\n\n        m = m.AddOrUpdate((Some(1), Some(1)), \"Some Some\");\n        m = m.AddOrUpdate((None, Some(1)), \"None Some\");\n        m = m.AddOrUpdate((Some(1), None), \"Some None\");\n        m = m.AddOrUpdate((None, None), \"None None\");\n\n        Assert.True(m[(Some(1), Some(1))] == \"Some Some\");\n        Assert.True(m[(None, Some(1))]    == \"None Some\");\n        Assert.True(m[(Some(1), None)]    == \"Some None\");\n        Assert.True(m[(None, None)]       == \"None None\");\n\n        Assert.True(m.Count == 4);\n\n        m = m.Filter(v => v.EndsWith(\"None\", StringComparison.Ordinal));\n\n        Assert.True(m.Count == 2);\n    }\n\n    [Fact]\n    public void MapValuesTest()\n    {\n        var m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5));\n\n        var vs = toSeq(m.Values);\n\n        Assert.True(vs.Head                     == 1);\n        Assert.True(vs.Tail.Head                == 2);\n        Assert.True(vs.Tail.Tail.Head           == 3);\n        Assert.True(vs.Tail.Tail.Tail.Head      == 4);\n        Assert.True(vs.Tail.Tail.Tail.Tail.Head == 5);\n        Assert.True(vs.Count                    == 5);\n    }\n\n    [Fact]\n    public void MapKeysTest()\n    {\n        var m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5));\n\n        var vs = toSeq(m.Keys);\n\n        Assert.True(vs.Head                     == 1);\n        Assert.True(vs.Tail.Head                == 2);\n        Assert.True(vs.Tail.Tail.Head           == 3);\n        Assert.True(vs.Tail.Tail.Tail.Head      == 4);\n        Assert.True(vs.Tail.Tail.Tail.Tail.Head == 5);\n        Assert.True(vs.Count                    == 5);\n    }\n\n    [Fact]\n    public void MapUnionTest1()\n    {\n        var x = Map((1, 1), (2, 2), (3, 3));\n        var y = Map((1, 1), (2, 2), (3, 3));\n\n        var z = union(x, y, (k, l, r) => l + r);\n\n        Assert.True(z == Map((1, 2), (2, 4), (3, 6)));\n    }\n\n    [Fact]\n    public void MapUnionTest2()\n    {\n        var x = Map((1, 1), (2, 2), (3, 3));\n        var y = Map((4, 4), (5, 5), (6, 6));\n\n        var z = union(x, y, (k, l, r) => l + r);\n\n        Assert.True(z == Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)));\n    }\n\n    [Fact]\n    public void MapIntesectTest1()\n    {\n        var x = Map(        (2, 2), (3, 3));\n        var y = Map((1, 1), (2, 2)        );\n\n        var z = intersect(x, y, (k, l, r) => l + r);\n\n        Assert.True(z == Map((2, 4)));\n    }\n\n    [Fact]\n    public void MapExceptTest()\n    {\n        var x = Map((1, 1), (2, 2), (3, 3));\n        var y = Map((1, 1));\n\n        var z = except(x, y);\n\n        Assert.True(z == Map((2, 2), (3, 3)));\n    }\n\n    [Fact]\n    public void MapSymmetricExceptTest()\n    {\n        var x = Map((1, 1), (2, 2), (3, 3));\n        var y = Map((1, 1),         (3, 3));\n\n        var z = symmetricExcept(x, y);\n\n        Assert.True(z == Map((2, 2)));\n    }\n\n    [Fact]\n    public void EqualsTest()\n    {\n        var emp = Map<int, int>();\n\n        Assert.True(emp.Equals(emp));\n        Assert.False(Map((1, 2)).Equals(emp));\n        Assert.False(emp.Equals(Map((1, 2))));\n        Assert.True(Map((1, 2)).Equals(Map((1, 2))));\n        Assert.False(Map((1, 2)).Equals(Map((1, 3))));\n        Assert.False(Map((1, 2), (3, 4)).Equals(Map((1, 2))));\n        Assert.False(Map((1, 2)).Equals(Map((1, 2), (3, 4))));\n        Assert.True(Map((1, 2), (3, 4)).Equals(Map((1, 2), (3, 4))));\n        Assert.True(Map((3, 4), (1, 2)).Equals(Map((1, 2), (3, 4))));\n        Assert.True(Map((3, 4), (1, 2)).Equals(Map((3, 4), (1, 2))));\n    }\n\n    [Fact]\n    public void SliceTest()\n    {\n        var m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5));\n\n        var x = m.Slice(1, 2);\n\n        Assert.True(x.Count == 2);\n        Assert.True(x.ContainsKey(1));\n        Assert.True(x.ContainsKey(2));\n\n        var y = m.Slice(2, 4);\n\n        Assert.True(y.Count == 3);\n        Assert.True(y.ContainsKey(2));\n        Assert.True(y.ContainsKey(3));\n        Assert.True(y.ContainsKey(4));\n\n        var z = m.Slice(4, 5);\n\n        Assert.True(z.Count == 2);\n        Assert.True(z.ContainsKey(4));\n        Assert.True(z.ContainsKey(5));\n    }\n\n    [Fact]\n    public void MinMaxTest()\n    {\n        var m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5));\n\n        Assert.True(m.Min == (1, 1));\n        Assert.True(m.Max == (5, 5));\n\n        var me = Map<int, int>();\n\n        Assert.True(me.Min == None);\n        Assert.True(me.Max == None);\n    }\n\n\n\n    [Fact]\n    public void FindPredecessorWhenKeyExistsTest()\n    {\n        var m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15));\n\n        Assert.True(m.FindPredecessor(1)  == None);\n        Assert.True(m.FindPredecessor(2)  == (1, 1));\n        Assert.True(m.FindPredecessor(3)  == (2, 2));\n        Assert.True(m.FindPredecessor(4)  == (3, 3));\n        Assert.True(m.FindPredecessor(5)  == (4, 4));\n        Assert.True(m.FindPredecessor(6)  == (5, 5));\n        Assert.True(m.FindPredecessor(7)  == (6, 6));\n        Assert.True(m.FindPredecessor(8)  == (7, 7));\n        Assert.True(m.FindPredecessor(9)  == (8, 8));\n        Assert.True(m.FindPredecessor(10) == (9, 9));\n        Assert.True(m.FindPredecessor(11) == (10, 10));\n        Assert.True(m.FindPredecessor(12) == (11, 11));\n        Assert.True(m.FindPredecessor(13) == (12, 12));\n        Assert.True(m.FindPredecessor(14) == (13, 13));\n        Assert.True(m.FindPredecessor(15) == (14, 14));\n    }\n\n    [Fact]\n    public void FindPredecessorWhenKeyNotExistsTest()\n    {\n        var m = Map((1, 1), (3, 3), (5, 5), (7, 7), (9, 9), (11, 11), (13, 13), (15, 15));\n\n        Assert.True(m.FindPredecessor(1)  == None);\n        Assert.True(m.FindPredecessor(2)  == (1, 1));\n        Assert.True(m.FindPredecessor(3)  == (1, 1));\n        Assert.True(m.FindPredecessor(4)  == (3, 3));\n        Assert.True(m.FindPredecessor(5)  == (3, 3));\n        Assert.True(m.FindPredecessor(6)  == (5, 5));\n        Assert.True(m.FindPredecessor(7)  == (5, 5));\n        Assert.True(m.FindPredecessor(8)  == (7, 7));\n        Assert.True(m.FindPredecessor(9)  == (7, 7));\n        Assert.True(m.FindPredecessor(10) == (9, 9));\n        Assert.True(m.FindPredecessor(11) == (9, 9));\n        Assert.True(m.FindPredecessor(12) == (11, 11));\n        Assert.True(m.FindPredecessor(13) == (11, 11));\n        Assert.True(m.FindPredecessor(14) == (13, 13));\n        Assert.True(m.FindPredecessor(15) == (13, 13));\n    }\n\n    [Fact]\n    public void FindExactOrPredecessorWhenKeyExistsTest()\n    {\n        var m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15));\n\n        Assert.True(m.FindExactOrPredecessor(1)  == (1, 1));\n        Assert.True(m.FindExactOrPredecessor(2)  == (2, 2));\n        Assert.True(m.FindExactOrPredecessor(3)  == (3, 3));\n        Assert.True(m.FindExactOrPredecessor(4)  == (4, 4));\n        Assert.True(m.FindExactOrPredecessor(5)  == (5, 5));\n        Assert.True(m.FindExactOrPredecessor(6)  == (6, 6));\n        Assert.True(m.FindExactOrPredecessor(7)  == (7, 7));\n        Assert.True(m.FindExactOrPredecessor(8)  == (8, 8));\n        Assert.True(m.FindExactOrPredecessor(9)  == (9, 9));\n        Assert.True(m.FindExactOrPredecessor(10) == (10, 10));\n        Assert.True(m.FindExactOrPredecessor(11) == (11, 11));\n        Assert.True(m.FindExactOrPredecessor(12) == (12, 12));\n        Assert.True(m.FindExactOrPredecessor(13) == (13, 13));\n        Assert.True(m.FindExactOrPredecessor(14) == (14, 14));\n        Assert.True(m.FindExactOrPredecessor(15) == (15, 15));\n    }\n\n    [Fact]\n    public void FindExactOrPredecessorWhenKeySometimesExistsTest()\n    {\n        var m = Map((1, 1), (3, 3), (5, 5), (7, 7), (9, 9), (11, 11), (13, 13), (15, 15));\n\n        Assert.True(m.FindExactOrPredecessor(1)  == (1, 1));\n        Assert.True(m.FindExactOrPredecessor(2)  == (1, 1));\n        Assert.True(m.FindExactOrPredecessor(3)  == (3, 3));\n        Assert.True(m.FindExactOrPredecessor(4)  == (3, 3));\n        Assert.True(m.FindExactOrPredecessor(5)  == (5, 5));\n        Assert.True(m.FindExactOrPredecessor(6)  == (5, 5));\n        Assert.True(m.FindExactOrPredecessor(7)  == (7, 7));\n        Assert.True(m.FindExactOrPredecessor(8)  == (7, 7));\n        Assert.True(m.FindExactOrPredecessor(9)  == (9, 9));\n        Assert.True(m.FindExactOrPredecessor(10) == (9, 9));\n        Assert.True(m.FindExactOrPredecessor(11) == (11, 11));\n        Assert.True(m.FindExactOrPredecessor(12) == (11, 11));\n        Assert.True(m.FindExactOrPredecessor(13) == (13, 13));\n        Assert.True(m.FindExactOrPredecessor(14) == (13, 13));\n        Assert.True(m.FindExactOrPredecessor(15) == (15, 15));\n    }\n\n    [Fact]\n    public void FindSuccessorWhenKeyExistsTest()\n    {\n        var m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15));\n\n        Assert.True(m.FindSuccessor(1)  == (2, 2));\n        Assert.True(m.FindSuccessor(2)  == (3, 3));\n        Assert.True(m.FindSuccessor(3)  == (4, 4));\n        Assert.True(m.FindSuccessor(4)  == (5, 5));\n        Assert.True(m.FindSuccessor(5)  == (6, 6));\n        Assert.True(m.FindSuccessor(6)  == (7, 7));\n        Assert.True(m.FindSuccessor(7)  == (8, 8));\n        Assert.True(m.FindSuccessor(8)  == (9, 9));\n        Assert.True(m.FindSuccessor(9)  == (10, 10));\n        Assert.True(m.FindSuccessor(10) == (11, 11));\n        Assert.True(m.FindSuccessor(11) == (12, 12));\n        Assert.True(m.FindSuccessor(12) == (13, 13));\n        Assert.True(m.FindSuccessor(13) == (14, 14));\n        Assert.True(m.FindSuccessor(14) == (15, 15));\n        Assert.True(m.FindSuccessor(15) == None);\n    }\n\n    [Fact]\n    public void FindSuccessorWhenKeyNotExistsTest()\n    {\n        var m = Map((1, 1), (3, 3), (5, 5), (7, 7), (9, 9), (11, 11), (13, 13), (15, 15));\n\n        Assert.True(m.FindSuccessor(1)  == (3, 3));\n        Assert.True(m.FindSuccessor(2)  == (3, 3));\n        Assert.True(m.FindSuccessor(3)  == (5, 5));\n        Assert.True(m.FindSuccessor(4)  == (5, 5));\n        Assert.True(m.FindSuccessor(5)  == (7, 7));\n        Assert.True(m.FindSuccessor(6)  == (7, 7));\n        Assert.True(m.FindSuccessor(7)  == (9, 9));\n        Assert.True(m.FindSuccessor(8)  == (9, 9));\n        Assert.True(m.FindSuccessor(9)  == (11, 11));\n        Assert.True(m.FindSuccessor(10) == (11, 11));\n        Assert.True(m.FindSuccessor(11) == (13, 13));\n        Assert.True(m.FindSuccessor(12) == (13, 13));\n        Assert.True(m.FindSuccessor(13) == (15, 15));\n        Assert.True(m.FindSuccessor(14) == (15, 15));\n        Assert.True(m.FindSuccessor(15) == None);\n    }\n\n    [Fact]\n    public void FindExactOrSuccessorWhenKeyExistsTest()\n    {\n        var m = Map((1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15));\n\n        Assert.True(m.FindExactOrSuccessor(1)  == (1, 1));\n        Assert.True(m.FindExactOrSuccessor(2)  == (2, 2));\n        Assert.True(m.FindExactOrSuccessor(3)  == (3, 3));\n        Assert.True(m.FindExactOrSuccessor(4)  == (4, 4));\n        Assert.True(m.FindExactOrSuccessor(5)  == (5, 5));\n        Assert.True(m.FindExactOrSuccessor(6)  == (6, 6));\n        Assert.True(m.FindExactOrSuccessor(7)  == (7, 7));\n        Assert.True(m.FindExactOrSuccessor(8)  == (8, 8));\n        Assert.True(m.FindExactOrSuccessor(9)  == (9, 9));\n        Assert.True(m.FindExactOrSuccessor(10) == (10, 10));\n        Assert.True(m.FindExactOrSuccessor(11) == (11, 11));\n        Assert.True(m.FindExactOrSuccessor(12) == (12, 12));\n        Assert.True(m.FindExactOrSuccessor(13) == (13, 13));\n        Assert.True(m.FindExactOrSuccessor(14) == (14, 14));\n        Assert.True(m.FindExactOrSuccessor(15) == (15, 15));\n    }\n\n    [Fact]\n    public void FindExactOrSuccessorWhenKeySometimesExistsTest()\n    {\n        var m = Map((1, 1), (3, 3), (5, 5), (7, 7), (9, 9), (11, 11), (13, 13), (15, 15));\n\n        Assert.True(m.FindExactOrSuccessor(1)  == (1, 1));\n        Assert.True(m.FindExactOrSuccessor(2)  == (3, 3));\n        Assert.True(m.FindExactOrSuccessor(3)  == (3, 3));\n        Assert.True(m.FindExactOrSuccessor(4)  == (5, 5));\n        Assert.True(m.FindExactOrSuccessor(5)  == (5, 5));\n        Assert.True(m.FindExactOrSuccessor(6)  == (7, 7));\n        Assert.True(m.FindExactOrSuccessor(7)  == (7, 7));\n        Assert.True(m.FindExactOrSuccessor(8)  == (9, 9));\n        Assert.True(m.FindExactOrSuccessor(9)  == (9, 9));\n        Assert.True(m.FindExactOrSuccessor(10) == (11, 11));\n        Assert.True(m.FindExactOrSuccessor(11) == (11, 11));\n        Assert.True(m.FindExactOrSuccessor(12) == (13, 13));\n        Assert.True(m.FindExactOrSuccessor(13) == (13, 13));\n        Assert.True(m.FindExactOrSuccessor(14) == (15, 15));\n        Assert.True(m.FindExactOrSuccessor(15) == (15, 15));\n    }\n\n    // Exponential test - takes too long to run\n    //[Fact]\n    //public void Issue_454()\n    //{\n    //    var tmp = \"\".PadLeft(30000, 'x'); // something big enough (one Referral object = 20-40kb)\n    //    var map = Map<int, string>();\n\n    //    for (int i = 0; i < 30000; i++) // for our real system it is only 3000 items, but with string it needs more\n    //    {\n    //        map = map.AddOrUpdate(i, tmp);\n    //        map = map.Filter(_ => true);\n    //    }\n\n    //    map.Filter(_ => false);\n    //}\n\n    [Fact]\n    public void itemLensGetShouldGetExistingValue()\n    {\n        var expected = \"3\";\n        var map      = Map((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n        var actual   = Map<int, string>.item(3).Get(map);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void itemLensGetShouldThrowExceptionForNonExistingValue()\n    {\n        Assert.Throws<Exception>(() =>\n                                 {\n                                     var map    = Map((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n                                     var actual = Map<int, string>.item(10).Get(map);\n                                 });\n    }\n\n    [Fact]\n    public void itemOrNoneLensGetShouldGetExistingValue()\n    {\n        var expected = \"3\";\n        var map      = Map((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n        var actual   = Map<int, string>.itemOrNone(3).Get(map);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void itemOrNoneLensGetShouldReturnNoneForNonExistingValue()\n    {\n        var expected = Option<string>.None;\n        var map      = Map((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n        var actual   = Map<int, string>.itemOrNone(10).Get(map);\n\n        Assert.Equal(expected, actual);\n    }\n    \n    [Fact]\n    public void foldStepValuesShouldYieldInOrder()\n    {\n        var expected = Seq(\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\");\n        var map      = Map((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"), (6, \"6\"), (7, \"7\"), (8, \"8\"), (9, \"9\"), (10, \"10\"));\n\n        var step = map.FoldStepValues(Seq<string>());\n\n        while (step is not Fold<string, Seq<string>>.Done)\n        {\n            if (step is Fold<string, Seq<string>>.Loop loop)\n            {\n                step = loop.Next(loop.State.Add(loop.Value));\n            }\n        }\n        Assert.True(expected == step.State);\n    }\n        \n    [Fact]\n    public void foldStepBackValuesShouldYieldInReverseOrder()\n    {\n        var expected = Seq(\"10\", \"9\", \"8\", \"7\", \"6\", \"5\", \"4\", \"3\", \"2\", \"1\");\n        var map      = Map((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"), (6, \"6\"), (7, \"7\"), (8, \"8\"), (9, \"9\"), (10, \"10\"));\n\n        var step = map.FoldStepBackValues(Seq<string>());\n\n        while (step is not Fold<string, Seq<string>>.Done)\n        {\n            if (step is Fold<string, Seq<string>>.Loop loop)\n            {\n                step = loop.Next(loop.State.Add(loop.Value));\n            }\n        }\n        Assert.True(expected == step.State);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/MemoImplTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing System.Linq;\nusing static LanguageExt.List;\n\nnamespace LanguageExt.Tests;\n\npublic class MemoImplTests\n{\n    [Fact]\n    public void MemoTest1()\n    {\n        var saved = DateTime.Now;\n        var date  = saved;\n\n        var f = memo(() => date.ToString());\n\n        var res1 = ~f;\n\n        date = DateTime.Now.AddDays(1);\n\n        var res2 = ~f;\n\n        Assert.True(res1 == res2);\n    }\n\n    [Fact]\n    public void MemoTest2()\n    {\n        var fix   = 0;\n        var count = 100;\n\n        Func<int, int> fn = x => x + fix;\n\n        var m = fn.MemoUnsafe();\n\n        var nums1 = map(Range(0, count), i => m(i));\n\n        fix = 1000;\n\n        var nums2 = map(Range(0, count), i => m(i));\n\n        Assert.True(\n            length(filter(zip(nums1, nums2, (a, b) => a == b), v => v)) == count\n        );\n    }\n        \n    // Commenting out because this test is unreliable when all the other tests are\n    // running.  This functionality is likely never going to change, so I'm fine with\n    // that for now.\n    //[Fact]\n    //public void MemoTest3()\n    //{\n    //    GC.Collect();\n    //    var fix = 0;\n    //    var count = 100;\n    //    Func<int, int> fn = x => x + fix;\n    //    var m = fn.Memo();\n    //    var nums1 = freeze(map(Range(0, count), i => m(i)));\n    //    fix = 100;\n    //    var nums2 = freeze(map(Range(0, count), i => m(i)));\n    //    var matches = length(filter(zip(nums1, nums2, (a, b) => a == b), v => v));\n    //    Assert.True(matches == count, \"Numbers don't match (\" + matches + \" total matches, should be \" + count + \")\");\n    //}\n\n    [Fact]\n    public void ListMemoTest()\n    {\n        var vals = List(1,2,3,4,5).Memo();\n\n        Assert.True(vals.Sum() == 15);\n        Assert.True(vals.Sum() == 15);\n    }\n\n    /*\n        Uncomment this if you have time on your hands\n\n    [Fact]\n    public void MemoMemoryTest()\n    {\n        var mbStart = GC.GetTotalMemory(false) / 1048576L;\n\n        Func<int, string> fn = x => x.ToString();\n        var m = fn.Memo();\n\n        Range(0, Int32.MaxValue).Iter(i => m(i));\n\n        var mbFinish = GC.GetTotalMemory(false) / 1048576L;\n\n        Assert.True(mbFinish - mbStart < 30);\n    }\n    */\n}\n"
  },
  {
    "path": "LanguageExt.Tests/MemoryConsoleTests.cs",
    "content": "using System;\nusing Xunit;\nusing LanguageExt.Sys.Test;\n\nusing Console = LanguageExt.Sys.Console<LanguageExt.Sys.Test.Runtime>;\n\nnamespace LanguageExt.Tests;\n\npublic class MemoryConsoleTests\n{\n    [Theory]\n    [InlineData(\"abc\")]\n    [InlineData(\"abc\\ndef\")]\n    [InlineData(\"abc\\ndef\\nghi\")]\n    [InlineData(\"abc\\n\\n\")]\n    [InlineData(\"abc\\ndef\\n\")]\n    public void Write_line(string unsplitLines)\n    {\n        var       lines = unsplitLines.Split('\\n').AsIterable();\n        using var rt    = Runtime.New();\n\n        var xs = lines.Traverse(Either.Right<Unit, string>);\n        \n        var comp = lines.Traverse(Console.writeLine).As();\n        comp.Run(rt, EnvIO.New()).ThrowIfFail();\n\n        var clines = rt.Env.Console.AsIterable();\n        Assert.True(lines == clines, $\"sequences don't match {lines} != {clines}\");\n    }\n        \n    [Theory]\n    [InlineData(\"abc\")]\n    [InlineData(\"abc\\ndef\")]\n    [InlineData(\"abc\\ndef\\nghi\")]\n    [InlineData(\"abc\\n\\n\")]\n    [InlineData(\"abc\\ndef\\n\")]\n    public void Read_line_followed_by_write_line(string unsplitLines)\n    {\n        // Prep the runtime and the keyboard buffer with the typed lines\n        using var rt    = Runtime.New();\n        var       lines = unsplitLines.Split('\\n').AsIterable().ToSeq();\n        lines.Iter(line => rt.Env.Console.WriteKeyLine(line));\n\n        // test\n        var comp = repeat(from l in Console.readLine\n                          from _ in Console.writeLine(l)\n                          select unit) | unitEff;\n            \n        // run and assert\n        comp.Run(rt, EnvIO.New()).ThrowIfFail();\n        Assert.True(lines == rt.Env.Console.AsIterable().ToSeq(), \"sequences don't match\");\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/MemoryFSTests.cs",
    "content": "/*\nusing Xunit;\nusing System.IO;\nusing LanguageExt.Sys.Test;\nusing System.Threading.Tasks;\nusing LanguageExt.Sys;\nusing LanguageExt.UnsafeValueAccess;\nusing File = LanguageExt.Sys.IO.File<LanguageExt.Eff<LanguageExt.Sys.Test.Runtime>, LanguageExt.Sys.Test.Runtime>;\nusing Dir  = LanguageExt.Sys.IO.Directory<LanguageExt.Eff<LanguageExt.Sys.Test.Runtime>, LanguageExt.Sys.Test.Runtime>;\n\nnamespace LanguageExt.Tests;\n\npublic class MemoryFSTests\n{\n    [Fact]\n    public void Write_and_read_file()\n    {\n        var root = MemoryFS.IsUnix ? \"/\" : \"C:\\\\\";\n        var rt   = Runtime.New();\n\n        var comp = from _ in File.writeAllText($\"{root}test.txt\", \"Hello, World\")\n                   from t in File.readAllText($\"{root}test.txt\")\n                   select t;\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r == \"Hello, World\", FailMsg(r));\n    }\n        \n    [Fact]\n    public void Write_to_non_existent_folder()\n    {\n        var rt = Runtime.New();\n\n        var comp = from _ in File.writeAllText(\"C:\\\\non-exist\\\\test.txt\", \"Hello, World\")\n                   from t in File.readAllText(\"C:\\\\non-exist\\\\test.txt\")\n                   select t;\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r.IsFail);\n    }\n        \n    [Fact]\n    public void Create_folder_write_and_read_file()\n    {\n        var root = MemoryFS.IsUnix ? \"/non-exist/\" : \"C:\\\\non-exist\\\\\"; \n        \n        var rt = Runtime.New();\n\n        var comp = from _1 in Dir.create(root)\n                   from _2 in File.writeAllText($\"{root}test.txt\", \"Hello, World\")\n                   from tx in File.readAllText($\"{root}test.txt\")\n                   select tx;\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r == \"Hello, World\", FailMsg(r));\n    }\n        \n    [Fact]\n    public void Create_nested_folder_write_and_read_file()\n    {\n        var root = MemoryFS.IsUnix ? \"/non-exist/also-non-exist\" : \"C:\\\\non-exist\\\\also-non-exist\";\n        var rt   = Runtime.New();\n\n        var comp = from _1 in Dir.create(root)\n                   from _2 in File.writeAllText(Path.Combine(root, \"test.txt\"), \"Hello, World\")\n                   from tx in File.readAllText(Path.Combine(root, \"test.txt\"))\n                   select tx;\n            \n        var r  = comp.As().Run(rt, EnvIO.New());\n        var eq = r == \"Hello, World\";\n        Assert.True(eq, FailMsg(r));\n    }\n        \n    [Fact]\n    public void Create_nested_folder_write_two_files_enumerate_one_of_them_using_star_pattern()\n    {\n        var fldr = MemoryFS.IsUnix ? \"/non-exist/also-non-exist\" : \"C:\\\\non-exist\\\\also-non-exist\";\n        var root = MemoryFS.IsUnix ? \"/\" : \"C:\\\\\";\n        \n        var rt = Runtime.New();\n\n        var comp = from _1 in Dir.create(fldr)\n                   from _2 in File.writeAllText(Path.Combine(fldr, \"test.txt\"), \"Hello, World\")\n                   from _3 in File.writeAllText(Path.Combine(fldr, \"test.bat\"), \"Goodbye, World\")\n                   from en in Dir.enumerateFiles(root, \"*.txt\", SearchOption.AllDirectories)\n                   from tx in File.readAllText(en.Head.ValueUnsafe()!)\n                   select (tx, en.Count);\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r == (\"Hello, World\", 1), FailMsg(r));\n    }\n        \n    [Fact]\n    public void Create_nested_folder_write_two_files_enumerate_one_of_them_using_qm_pattern()\n    {\n        var fldr = MemoryFS.IsUnix ? \"/non-exist/also-non-exist\" : \"C:\\\\non-exist\\\\also-non-exist\";\n        var root = MemoryFS.IsUnix ? \"/\" : \"C:\\\\\";\n        \n        var rt   = Runtime.New();\n\n        var comp = from _1 in Dir.create(fldr)\n                   from _2 in File.writeAllText(Path.Combine(fldr, \"test.txt\"), \"Hello, World\")\n                   from _3 in File.writeAllText(Path.Combine(fldr, \"test.bat\"), \"Goodbye, World\")\n                   from en in Dir.enumerateFiles(root, \"????.txt\", SearchOption.AllDirectories)\n                   from tx in File.readAllText(en.Head.ValueUnsafe()!)\n                   select (tx, en.Count);\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r == (\"Hello, World\", 1), FailMsg(r));\n    }\n        \n    [Fact]\n    public void Create_nested_folder_write_two_files_enumerate_fail_using_singular_qm_pattern()\n    {\n        var rt = Runtime.New();\n\n        var comp = from _1 in Dir.create(\"C:\\\\non-exist\\\\also-non-exist\")\n                   from _2 in File.writeAllText(\"C:\\\\non-exist\\\\also-non-exist\\\\test.txt\", \"Hello, World\")\n                   from _3 in File.writeAllText(\"C:\\\\non-exist\\\\also-non-exist\\\\test.bat\", \"Goodbye, World\")\n                   from en in Dir.enumerateFiles(\"C:\\\\\", \"?.txt\", SearchOption.AllDirectories)\n                   from tx in File.readAllText(en.Head.ValueUnsafe()!)\n                   select (tx, en.Count);\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r.IsFail);\n    }\n        \n    [Theory]\n    [InlineData(\"C:\\\\non-exist\", \"/non-exist\")]\n    [InlineData(\"C:\\\\non-exist\\\\also-non-exist\", \"/non-exist/also-non-exist\")]\n    [InlineData(\"C:\\\\a\\\\b\\\\c\\\\d\", \"/a/b/c/d\")]\n    public void Create_and_delete_folder(string windowsPath, string linuxPath)\n    {\n        var path = MemoryFS.IsUnix ? linuxPath : windowsPath;\n        \n        var rt = Runtime.New();\n\n        var comp = from p  in Pure(path)\n                   from _1 in Dir.create(p)\n                   from e1 in Dir.exists(p)\n                   from _2 in Dir.delete(p)\n                   from e2 in Dir.exists(p)\n                   select (e1, e2);\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r == (true, false), FailMsg(r));\n    }\n\n    [Theory]\n    [InlineData(\"C:\\\\non-exist\")]\n    [InlineData(\"C:\\\\non-exist\\\\also-non-exist\")]\n    [InlineData(\"D:\\\\a\\\\b\\\\c\\\\d\")]\n    public void Delete_non_existent_folder(string path)\n    {\n        var rt = Runtime.New();\n\n        var comp = from p in SuccessEff(path)\n                   from _ in Dir.delete(p)\n                   select unit;\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r.IsFail);\n    }\n        \n    [Theory]\n    [InlineData(false, \"C:\\\\non-exist\", \"C:\\\\non-exist\\\\test.txt\")]\n    [InlineData(false, \"C:\\\\non-exist\\\\also-non-exist\", \"C:\\\\non-exist\\\\also-non-exist\\\\test.txt\")]\n    [InlineData(true, \"/non-exist\", \"/non-exist/test.txt\")]\n    [InlineData(true, \"/non-exist/also-non-exist\", \"/non-exist/also-non-exist/test.txt\")]\n    public void File_exists(bool isUnix, string folder, string file)\n    {\n        if (MemoryFS.IsUnix != isUnix) return;\n        var rt = Runtime.New();\n\n        var comp = from _1 in Dir.create(folder)\n                   from _2 in File.writeAllText(file, \"Hello, World\")\n                   from ex in File.exists(file)\n                   select ex;\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r == true, FailMsg(r));\n    }\n        \n    [Theory]\n    [InlineData(\"C:\\\\non-exist\\\\test.txt\")]\n    [InlineData(\"C:\\\\non-exist\\\\also-non-exist\\\\test.txt\")]\n    [InlineData(\"X:\\\\non-exist\\\\also-non-exist\\\\test.txt\")]\n    [InlineData(\"X:\\\\test.txt\")]\n    public void File_doesnt_exist(string file)\n    {\n        var rt = Runtime.New();\n\n        var comp = from _2 in File.writeAllText(file, \"Hello, World\")\n                   from ex in File.exists(file)\n                   select ex;\n            \n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r.IsFail);\n    }\n\n    [Theory]\n    [InlineData(false, \"C:\\\\\", \"C:\\\\a\\\\b\\\\c\\\\d\", new[] {\"C:\\\\a\", \"C:\\\\a\\\\b\", \"C:\\\\a\\\\b\\\\c\", \"C:\\\\a\\\\b\\\\c\\\\d\" }, \"*\")]\n    [InlineData(false, \"C:\\\\\", \"C:\\\\a\\\\b\\\\c\", new[] {\"C:\\\\a\", \"C:\\\\a\\\\b\", \"C:\\\\a\\\\b\\\\c\"}, \"*\")]\n    [InlineData(false, \"C:\\\\\", \"C:\\\\a\\\\b\", new[] {\"C:\\\\a\", \"C:\\\\a\\\\b\"}, \"*\")]\n    [InlineData(false, \"C:\\\\\", \"C:\\\\a\", new[] {\"C:\\\\a\"}, \"*\")]\n    [InlineData(false, \"C:\\\\\", \"C:\\\\and\\\\all\\\\the\\\\arrows\", new[] {\"C:\\\\and\", \"C:\\\\and\\\\all\", \"C:\\\\and\\\\all\\\\the\\\\arrows\" }, \"*a*\")]\n    [InlineData(true, \"/\", \"/a/b/c/d\", new[] {\"/a\", \"/a/b\", \"/a/b/c\", \"/a/b/c/d\" }, \"*\")]\n    [InlineData(true, \"/\", \"/a/b/c\", new[] {\"/a\", \"/a/b\", \"/a/b/c\"}, \"*\")]\n    [InlineData(true, \"/\", \"/a/b\", new[] {\"/a\", \"/a/b\"}, \"*\")]\n    [InlineData(true, \"/\", \"/a\", new[] {\"/a\"}, \"*\")]\n    [InlineData(true, \"/\", \"/and/all/the/arrows\", new[] {\"/and\", \"/and/all\", \"/and/all/the/arrows\" }, \"*a*\")]\n    public void Enumerate_folders(bool isUnix, string root, string path, string[] folders, string pattern)\n    {\n        if (MemoryFS.IsUnix != isUnix) return;\n        \n        var rt = Runtime.New();\n\n        var comp = from _1 in Dir.create(path)\n                   from ds in Dir.enumerateDirectories(root, pattern, SearchOption.AllDirectories)\n                   select ds.Strict();\n\n        var r   = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r == toSeq(folders));\n    }\n\n    [Theory]\n    [InlineData(false, \"C:\\\\a\\\\b\", \"C:\\\\c\\\\d\", \"test.txt\")]\n    [InlineData(false, \"C:\\\\\", \"C:\\\\c\\\\d\", \"test.txt\")]\n    [InlineData(true, \"/a/b\", \"/c/d\", \"test.txt\")]\n    [InlineData(true, \"/\", \"/c/d\", \"test.txt\")]\n    public void Move_file_from_one_folder_to_another(bool isUnix, string srcdir, string destdir, string file)\n    {\n        if (MemoryFS.IsUnix != isUnix) return;\n        \n        var rt = Runtime.New();\n\n        var comp = from _1 in Dir.create(srcdir)\n                   from _2 in Dir.create(destdir)\n                   from sf in Pure(Path.Combine(srcdir, file))\n                   from df in Pure(Path.Combine(destdir, file))\n                   from _3 in File.writeAllText(sf, \"Hello, World\")\n                   from _4 in Dir.move(sf, df)\n                   from tx in File.readAllText(df)\n                   from ex in File.exists(sf)\n                   select (ex, tx);\n\n        var r = comp.As().Run(rt, EnvIO.New());\n        Assert.True(r == (false, \"Hello, World\"), FailMsg(r));\n    }\n        \n    static string FailMsg<A>(Fin<A> ma) =>\n        ma.Match(Succ: _ => \"\", Fail: e => e.Message);\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Tests/MonadTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing static LanguageExt.List;\n\nnamespace LanguageExt.Tests;\n\npublic class MonadTests\n{\n    [Fact]\n    public void WriterTest()\n    {\n        var tell1 = fun((string x) => tell(List(x)));\n\n        var value = fun((int x) => from _ in tell1($\"Got number: {x}\")\n                                   select x);\n\n        var multWithLog = from a in value(3)\n                          from b in value(5)\n                          from _ in tell1(\"Gonna multiply these two\")\n                          select a * b;\n\n        var res = multWithLog.Run();\n\n        Assert.True(length(res.Output)           == 3);\n        Assert.True(res.Value                    == 15);\n        Assert.True(head(res.Output)             == \"Got number: 3\");\n        Assert.True(head(tail(res.Output))       == \"Got number: 5\");\n        Assert.True(head(tail(tail(res.Output))) == \"Gonna multiply these two\");\n    }\n\n    static Writer<Seq<string>, int> writer(int value, Seq<string> output) => \n        Writer.write(value, output);\n\n    static Writer<Seq<string>, Seq<int>> multWithLog(Seq<int> input) =>\n        from _ in writer(0, Seq(\"Start\"))\n        from r in input.Traverse(i => writer(i * 10, Seq($\"Number: {i}\")))\n        select r;\n\n    [Fact]\n    public void WriterSequenceTest()\n    {\n        var res = multWithLog(Seq(1, 2, 3)).Run();\n\n        Assert.True(res.Value  == Seq(10, 20, 30));\n        Assert.True(res.Output == Seq(\"Start\", \"Number: 1\", \"Number: 2\", \"Number: 3\"));\n    }\n\n    private class Bindings\n    {\n        public readonly Map<string, int> Map;\n        public Bindings(params (string, int)[] items) => \n            Map = toMap(items);\n\n        public static Bindings New(params (string, int)[] items) => \n            new (items);\n    }\n\n    [Fact]\n    public void ReaderAskTest()\n    {\n        var lookupVar = fun((string name, Bindings bindings) => Map.find(bindings.Map, name).IfNone(0));\n\n        var calcIsCountCorrect = from count in Reader.asks((Bindings env) => lookupVar(\"count\", env))\n                                 from bindings in ask<Bindings>()\n                                 select count == Map.length(bindings.Map);\n\n        var sampleBindings = Bindings.New((\"count\", 3), (\"1\", 1), (\"b\", 2));\n\n        bool res = calcIsCountCorrect.Run(sampleBindings);\n        Assert.True(res);\n    }\n\n    [Fact]\n    public void ReaderLocalTest()\n    {\n        var calculateContentLen = from content in Reader.ask<string>()\n                                  select content.Length;\n\n        var calculateModifiedContentLen = Reader.local(content => \"Prefix \" + content, calculateContentLen);\n\n        var s           = \"12345\";\n        var modifiedLen = calculateModifiedContentLen.Run(s);\n        var len         = calculateContentLen.Run(s);\n\n        Assert.True(modifiedLen == 12);\n        Assert.True(len         == 5);\n    }\n\n    [Fact]\n    public void StateTest()\n    {\n        var comp = from inp in State.get<string>()\n                   let hw = inp + \", world\"\n                   from _ in State.put(hw)\n                   select hw.Length;\n\n        var r = comp.Run(\"hello\");\n\n        Assert.True(r.Value == 12);\n        Assert.True(r.State == \"hello, world\");\n    }\n    // TODO: Restore when traits are complete\n\n    /*\n    [Fact]\n    public void RWSTest()\n    {\n        var previous = RWS<MLst<string>, bool, Lst<string>,  Map<int, string>, int>(1);\n        var comp =\n            from val in previous\n            from state in get<MLst<string>, bool, Lst<string>, Map<int, string>, int>()\n            from env in ask<MLst<string>, bool, Lst<string>, Map<int, string>>()\n            from _ in put<MLst<string>, bool, Lst<string>, Map<int, string>, int>(state.Add(2, \"B\"))\n            from __ in tell<MLst<string>, bool, Lst<string>, Map<int, string>, int>(List($\"{val}\", $\"{env}\"))\n            select val + 2;\n\n        var (value, output, finalState, faulted) = comp(true, Map((1, \"a\")));\n        Assert.True(value      == 3);\n        Assert.True(output     == List(\"1\", \"True\"));\n        Assert.True(finalState == Map((1, \"a\"), (2, \"B\")));\n    }\n\n    [Fact]\n    public void RWSFailTest()\n    {\n        var previous = RWS<MLst<string>, bool, Lst<string>,  Map<int, string>, int>(1);\n        var comp =\n            from val in previous\n            from _ in modify<MLst<string>, bool, Lst<string>, Map<int, string>, int>(_ => failwith<Map<int,string>>(\"\"))\n            select val + 2;\n\n        Assert.ThrowsAny<Exception>(act(comp.Run(false, Map((1, \"a\"))).IfFailThrow));\n    }\n\n    [Fact]\n    public void RWSBottomTest()\n    {\n        var previous = RWS<MLst<string>, bool, Lst<string>,  Map<int, string>, int>(1);\n        var comp =\n            from val in previous\n            where false\n            select val + 3;\n\n        Assert.ThrowsAny<Exception>(act(comp.Run(false, Map((1, \"a\"))).IfFailThrow));\n    }\n    */\n\n    //[Fact]\n    //public void ReaderWriterBindTest()\n    //{\n    //    var x = from a in ask<string>()\n    //            from b in tell(\"Hello \" + a)\n    //            select b;\n\n    //    Assert.True(x(\"everyone\").Value().Output.Head() == \"Hello everyone\");\n    //}\n\n    //[Fact]\n    //public void TryReaderBindTest()\n    //{\n    //    var tryadd = from a in Try(() => 123)\n    //                 from b in ask<int>()\n    //                 select a + b;\n\n    //    var res = tryadd.Map(r => r.Lift(123))\n    //                    .Lift();\n\n    //    Assert.True(res == 246);\n    //}\n\n    //[Fact]\n    //public void SomeLiftTest()\n    //{\n    //    var z = Some(Some(10));\n    //    var r = z.LiftT();\n    //    Assert.True(r == 10);\n    //}\n\n    //[Fact]\n    //public void FilterTTest()\n    //{\n    //    var o = Some(List(1, 2, 3, 4, 5));\n    //    var o2 = o.FilterT(n => n > 2);\n\n    //    Assert.True(o2.Count() == 1);\n    //    Assert.True(o2.CountT() == 3);\n    //}\n\n\n    //[Fact]\n    //public void ReaderListSumTest()\n    //{\n    //    var r2 = from v in ask<int>()\n    //             from l in List(1, 2, 3, 4, 5)\n    //             select l * v;\n\n    //    var r3 = r2.SumT()(10);\n\n    //    Assert.True(r3 == 150);\n    //}\n\n    //private static string Error()\n    //{\n    //    throw new Exception(\"Nooooo\");\n    //}\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Multiplicable.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Xunit;\nusing static LanguageExt.Prelude;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests\n{\n    public class Multiplicable\n    {\n        [Fact]\n        public void OptionalNumericMultiply()\n        {\n            var x = Some(10);\n            var y = Some(20);\n            var z = product<TInt, int>(x, y);\n\n            Assert.True(z == 200);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/NullChecks/AbstractNullCheckTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.NullChecks\n{\n    public abstract class AbstractNullCheckTests\n    {\n        protected abstract bool ExpectedWhenNull { get; }\n        protected abstract bool NullCheck<T>(T value);\n\n        private bool ExpectedWhenNotNull => !ExpectedWhenNull;\n\n        [Fact]\n        public void NullCheck_NullObject_AsExpectedWhenNull()\n        {\n            object value = null;\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_NonNullObject_AsExpectedWhenNotNull()\n        {\n            object value = new object();\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNotNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_NullString_AsExpectedWhenNull()\n        {\n            string value = null;\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_HelloString_AsExpectedWhenNotNull()\n        {\n            string value = \"hello\";\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNotNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_NullCustomClass_AsExpectedWhenNull()\n        {\n            FooClass value = null;\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_DefaultConstructorCustomClass_AsExpectedWhenNotNull()\n        {\n            FooClass value = new FooClass();\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNotNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_NullNullableByte_AsExpectedWhenNull()\n        {\n            byte? value = null;\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_ZeroNullableByte_AsExpectedWhenNotNull()\n        {\n            byte? value = 0;\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNotNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_ZeroInt_AsExpectedWhenNotNull()\n        {\n            int value = 0;\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNotNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_DefaultCustomEnum_AsExpectedWhenNull()\n        {\n            FooEnum value = default(FooEnum);\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNotNull, actual);\n        }\n\n        [Fact]\n        public void NullCheck_DefaultConstructorCustomStruct_AsExpectedWhenNull()\n        {\n            FooStruct value = new FooStruct();\n            var actual = NullCheck(value);\n            Assert.Equal(ExpectedWhenNotNull, actual);\n        }\n\n        private class FooClass { }\n        private enum FooEnum { }\n        private struct FooStruct { }\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/NullChecks/IsNullExtensionTests.cs",
    "content": "﻿namespace LanguageExt.Tests.NullChecks\n{\n    public class IsNullExtensionTests : AbstractNullCheckTests\n    {\n        protected override bool ExpectedWhenNull => true;\n        protected override bool NullCheck<T>(T value) => value.IsNull();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/NullChecks/isnullPreludeTests.cs",
    "content": "﻿namespace LanguageExt.Tests.NullChecks\n{\n    public class isnullPreludeTests : AbstractNullCheckTests\n    {\n        protected override bool ExpectedWhenNull => true;\n        protected override bool NullCheck<T>(T value) => Prelude.isnull(value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/NullChecks/notnullPreludeTests.cs",
    "content": "﻿namespace LanguageExt.Tests.NullChecks\n{\n    public class notnullPreludeTests : AbstractNullCheckTests\n    {\n        protected override bool ExpectedWhenNull => false;\n        protected override bool NullCheck<T>(T value) => Prelude.notnull(value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/OptionApply.cs",
    "content": "﻿using System;\nusing Xunit;\nusing LanguageExt.ClassInstances;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class OptionApply\n{\n    Func<int, int, int> add = (a, b) => a + b;\n\n    [Fact]\n    public void ApplySomeArgs()\n    {\n        var opt = Some(add).Apply(Some(3)).Apply(Some(4));\n        Assert.Equal(Some(7), opt);\n    }\n\n    [Fact]\n    public void ApplySomeArgsF()\n    {\n        var opt = map(add, Some(3)).Apply(Some(4));\n        Assert.Equal(Some(7), opt);\n    }\n\n    [Fact]\n    public void ApplySomeArgsF2()\n    {\n        var opt = Some(add).Apply(Some(3)).Apply(Some(4));\n        Assert.True(equals<EqInt, int>(Some(7), opt));\n    }\n\n    [Fact]\n    public void ApplyNoneArgs()\n    {\n        var opt = add.Map(Option<int>.None).Apply(Some(4));\n        Assert.Equal(None, opt);\n    }\n\n    [Fact]\n    public void ApplyNoneArgsF()\n    {\n        var opt = apply(apply(Some(add), Option<int>.None), Some(4));\n        Assert.Equal(None, opt);\n    }\n\n    [Fact]\n    public void ApplyNoneArgsF2()\n    {\n        var opt = Some(add).Apply(Option<int>.None).Apply(Some(4));\n\n        Assert.True(equals<EqInt, int>(Option<int>.None, opt));\n    }\n\n    [Fact]\n    public void ApplicativeLawHolds()\n    {\n        var first = Some(add)\n                      .Apply(Some(3))\n                      .Apply(Some(4));\n\n        var second = Some(3)\n                        .ParMap(add)\n                        .Apply(Some(4));\n\n        Assert.Equal(first, second);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/OptionCoalesceTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class OptionCoalesceTests\n{\n    [Fact]\n    public void OptionCoalesceTest1()\n    {\n        var optional = Some(123);\n        var value    = optional || 456;\n        Assert.True(value == 123);\n    }\n\n    [Fact]\n    public void OptionCoalesceTest2()\n    {\n        Option<int> optional = None;\n\n        var value = optional || 456;\n        Assert.True(value == 456);\n    }\n\n    [Fact]\n    public void OptionCoalesceTest3()\n    {\n        Option<int> optional1 = None;\n        Option<int> optional2 = None;\n        var         value     = optional1 || optional2 || 456;\n        Assert.True(value == 456);\n    }\n\n    [Fact]\n    public void OptionUnsafeCoalesceTest1()\n    {\n        var optional = Some(123);\n        var value    = optional || 456;\n        Assert.True(value == 123);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/OptionLazy.cs",
    "content": "﻿//using Xunit;\n//using System;\n//using System.Collections.Generic;\n//using LanguageExt;\n//using static LanguageExt.Prelude;\n\n//namespace LanguageExt.Tests\n//{\n//    public class OptionLazyTests\n//    {\n//        [Fact]\n//        public void OptionLazyTest1()\n//        {\n//            var items = List<int>();\n\n//            var option = from w in Some(_ => { items = items.Add(5); return 5; })\n//                         from x in Some(_ => { items = items.Add(10); return 10; })\n//                         from y in Some(_ => { items = items.Add(15); return 15; })\n//                         from z in Some(_ => { items = items.Add(20); return 20; })\n//                         select w + x + y + z;\n\n//            Assert.True(items.Count == 0);\n\n//            var value = option.IfNone(0);\n\n//            Assert.True(items.Count == 4);\n//            Assert.True(value == 50);\n\n//            var value2 = option.IfNone(0);\n//            var value3 = option.IfNone(0);\n//            var value4 = option.IfNone(0);\n//            var value5 = option.IfNone(0);\n//            var value6 = option.IfNone(0);\n\n//            Assert.True(items.Count == 4);\n//            Assert.True(value6 == 50);\n//        }\n\n//        [Fact]\n//        public void OptionLazyStrictCombinedTest1()\n//        {\n//            var items = List<int>();\n\n//            var option = from w in Some(_ => { items = items.Add(5); return 5; })\n//                         from x in Some(_ => { items = items.Add(10); return 10; })\n//                         from y in Some(_ => { items = items.Add(15); return 15; })\n//                         from z in Some(_ => { items = items.Add(20); return 20; })\n//                         from i in Some(30)\n//                         select w + x + y + z + i;\n\n//            Assert.True(items.Count == 0);\n\n//            var value = option.IfNone(0);\n\n//            Assert.True(items.Count == 4);\n//            Assert.True(value == 80);\n\n//            var value2 = option.IfNone(0);\n//            var value3 = option.IfNone(0);\n//            var value4 = option.IfNone(0);\n//            var value5 = option.IfNone(0);\n//            var value6 = option.IfNone(0);\n\n//            Assert.True(items.Count == 4);\n//            Assert.True(value6 == 80);\n//        }\n\n//        [Fact]\n//        public void OptionLazyStrictCombinedTest2()\n//        {\n//            var items = List<int>();\n\n//            var option = from i in Some(30)\n//                         from w in Some(_ => { items = items.Add(5); return 5; })\n//                         from x in Some(_ => { items = items.Add(10); return 10; })\n//                         from y in Some(_ => { items = items.Add(15); return 15; })\n//                         from z in Some(_ => { items = items.Add(20); return 20; })\n//                         select w + x + y + z + i;\n\n//            Assert.True(items.Count == 0);\n\n//            var value = option.IfNone(0);\n\n//            Assert.True(items.Count == 4);\n//            Assert.True(value == 80);\n\n//            var value2 = option.IfNone(0);\n//            var value3 = option.IfNone(0);\n//            var value4 = option.IfNone(0);\n//            var value5 = option.IfNone(0);\n//            var value6 = option.IfNone(0);\n\n//            Assert.True(items.Count == 4);\n//            Assert.True(value6 == 80);\n//        }\n\n//        [Fact]\n//        public void OptionStrictOnlyTest()\n//        {\n//            var items = List<int>();\n\n//            var option = from t in Some(30)\n//                         let _a = items = items.Add(5)\n//                         from u in Some(30)\n//                         let _b = items = items.Add(10)\n//                         from v in Some(30)\n//                         let _c = items = items.Add(15)\n//                         select t * u * v;\n\n//            Assert.True(!option.IsLazy);\n//            Assert.True(items.Count == 3);\n\n//            var res = option.IfNone(0);\n\n//            Assert.True(res == 27000);\n//        }\n\n//        [Fact]\n//        public void OptionLazyMapTest()\n//        {\n//            var n = 0;\n\n//            var x = Some(_ => ++n);\n\n//            Assert.True(x.IsLazy);\n//            Assert.True(n == 0);\n\n//            var y = x.Map(v => v * 10);\n\n//            Assert.True(x.IsLazy);\n//            Assert.True(n == 0);\n\n//            Assert.True(y == 10);\n//            Assert.True(n == 1);\n//        }\n\n//        [Fact]\n//        public void OptionLazyFilter()\n//        {\n//            var items = List<int>();\n\n//            var option = from i in Some(30)\n//                         where i > 10\n//                         from w in Some(_ => { items = items.Add(5); return 5; })\n//                         where w > 4\n//                         from x in Some(_ => { items = items.Add(10); return 10; })\n//                         where x > 9\n//                         from y in Some(_ => { items = items.Add(15); return 15; })\n//                         where y > 14\n//                         from z in Some(_ => { items = items.Add(20); return 20; })\n//                         where z > 19\n//                         select w + x + y + z + i;\n\n//            Assert.True(items.Count == 0);\n\n//            var value = option.IfNone(0);\n\n//            Assert.True(items.Count == 4);\n//            Assert.True(value == 80);\n\n//            var value2 = option.IfNone(0);\n//            var value3 = option.IfNone(0);\n//            var value4 = option.IfNone(0);\n//            var value5 = option.IfNone(0);\n//            var value6 = option.IfNone(0);\n\n//            Assert.True(items.Count == 4);\n//            Assert.True(value6 == 80);\n//        }\n//    }\n//}\n"
  },
  {
    "path": "LanguageExt.Tests/OptionTTests.cs",
    "content": "﻿using Xunit;\nusing System.Linq;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests;\n\npublic class OptionTTests\n{\n    [Fact]\n    public void TestOptionT2()\n    {\n        var list = List(Some(1), Some(2), Some(3), Some(4), Some(5));\n\n        var newlist = list.KindT<Lst, Option, Option<int>, int>()\n                          .BindT(x => x % 2 == 0 ? Some(x) : None)\n                          .AsT<Lst, Option, Option<int>, int>().As();\n\n        Assert.True(newlist == List(None, Some(2), None, Some(4), None));\n    }\n\n    [Fact]\n    public void TestOptionT3()\n    {\n        var list = List(Some(1), Some(2), Some(3), Some(4), Some(5));\n\n        var result = list.KindT<Lst, Option, Option<int>, int>()\n                         .SumT();\n\n        Assert.True(result == 15);\n    }\n\n    [Fact]\n    public void TestOptionT4()\n    {\n        var list = List(Some(1), Some(2), Some(3), Some(4), Some(5));\n\n        var result = list.KindT<Lst, Option, Option<int>, int>()\n                         .CountT();\n\n        Assert.True(result == 5);\n    }\n\n    [Fact]\n    public void WrappedListTest()\n    {\n        var opt  = Some(List(1, 2, 3, 4, 5));\n        var res  = opt.KindT<Option, Lst, Lst<int>, int>().FoldT(0, (s, v) => s + v);\n        var mopt = opt.KindT<Option, Lst, Lst<int>, int>().MapT(x => x * 2);\n        var mres = mopt.FoldT(0, (s, v) => s + v);\n\n        Assert.True(res  == 15, \"Expected 15, but got \" + res);\n        Assert.True(mres == 30, \"Expected 30, but got \" + mres);\n        Assert.True(opt.KindT<Option, Lst, Lst<int>, int>().CountT() == 5,\n                    \"opt != 5, (\" + opt.KindT<Option, Lst, Lst<int>, int>().CountT() + \")\");\n        Assert.True(mopt.CountT() == 5, \"mopt != 5, (\" + mopt.CountT() + \")\");\n\n        opt = None;\n        res = opt.KindT<Option, Lst, Lst<int>, int>().FoldT(0, (s, v) => s + v);\n\n        Assert.True(res == 0, \"res != 0, got \" + res);\n        Assert.True(opt.KindT<Option, Lst, Lst<int>, int>().CountT() == 0,\n                    \"opt.Count() != 0, got \" + opt.KindT<Option, Lst, Lst<int>, int>().CountT());\n    }\n\n    //[Fact]\n    //public void WrappedMapTest()\n    //{\n    //    var opt = Some(Map(Tuple(1, \"A\"), Tuple(2, \"B\"), Tuple(3, \"C\"), Tuple(4, \"D\"), Tuple(5, \"E\")));\n    //    var res = opt.FoldT(\"\", (s, v) => s + v);\n    //    var mopt = opt.MapT(x => x.ToLower());\n    //    var mres = mopt.FoldT(\"\", (s, v) => s + v);\n\n    //    Assert.True(res == \"ABCDE\");\n    //    Assert.True(opt.CountT() == 5);\n    //    Assert.True(mopt.CountT() == 5);\n\n    //    match(mopt,\n    //        Some: x =>\n    //        {\n    //            Assert.True(x[1] == \"a\");\n    //            Assert.True(x[2] == \"b\");\n    //            Assert.True(x[3] == \"c\");\n    //            Assert.True(x[4] == \"d\");\n    //            Assert.True(x[5] == \"e\");\n    //        },\n    //        None: () => Assert.False(true)\n    //    );\n    //}\n\n    [Fact]\n    public void WrappedListLinqTest()\n    {\n        var opt = Some(List(1, 2, 3, 4, 5));\n\n        var res = from x in opt.ToIterable()\n                  from y in x\n                  select y * 2;\n\n        var total = res.Sum();\n\n        Assert.True(total == 30);\n    }\n\n    [Fact]\n    public void WrappedMapLinqTest()\n    {\n        var opt = Some(Map((1, \"A\"), (2, \"B\"), (3, \"C\"), (4, \"D\"), (5, \"E\")));\n\n        var res = from x in opt.ToIterable()\n                  from y in x.AsIterable()\n                  select y.Value.ToLower();\n\n        var fd = res.Fold(\"\", (s, x) => s + x);\n\n        Assert.True(fd == \"abcde\");\n    }\n\n    [Fact]\n    public void WrappedOptionOptionLinqTest()\n    {\n        var opt = Some(Some(Some(100)));\n\n        var res = from x in opt\n                  from y in x\n                  from z in y\n                  select z * 2;\n\n        Assert.True(equals<EqInt, int>(res, Some(200)));\n\n        opt = Some(Some<Option<int>>(None));\n\n        var res2 = from x in opt\n                   from y in x\n                   from z in y\n                   select z * 2;\n\n        Assert.False(equals<EqInt, int>(res, Some(0)));\n    }\n\n    [Fact]\n    public void WrappedOptionLinqTest()\n    {\n        var opt = Some(Some(100));\n\n        var res = from x in opt\n                  from y in x\n                  select y * 2;\n\n        Assert.True(res.Map(x => x == 200).IfNone(false));\n\n        opt = Some<Option<int>>(None);\n\n        res = from x in opt\n              from y in x\n              select y * 2;\n\n        var bopt = res.Map(x => x == 1);\n\n        Assert.True(bopt.IfNone(true));\n    }\n\n    //[Fact]\n    //public void WrappedEitherLinqTest()\n    //{\n    //    var opt = Some(Right<string, int>(100));\n\n    //    var res = from x in opt\n    //              from y in x\n    //              select y * 2;\n\n    //    Assert.True(res.LiftT() == 200);\n\n    //    opt = Some(Left<string, int>(\"left\"));\n\n    //    res = from x in opt\n    //          from y in x\n    //          select y * 2;\n\n    //    Assert.True(res.LiftT() == 0);\n    //}\n\n\n    [Fact]\n    public void WrappedListOfOptionsTest2()\n    {\n        var opt = List(Some(1), Some(2), Some(3), Some(4), Some(5));\n\n        opt = opt.KindT<Lst, Option, Option<int>, int>()\n                 .FoldT(Lst<Option<int>>.Empty, (xs, x) => x > 2 ? xs.Add(x) : xs);\n              // .FilterT(x => x > 2);   <-- TODO: Above was this -- should we restore a filter operation? Can we even?\n\n        Assert.True(opt.Count() == 3, \"Count should be 3, is: \"                   + opt.Count());\n        Assert.True(equals<TInt, int>(opt[0], Some(3)), \"opt[0] != Some(3), Is: \" + opt[0]);\n        Assert.True(equals<TInt, int>(opt[1], Some(4)), \"opt[1] != Some(4), Is: \" + opt[1]);\n        Assert.True(equals<TInt, int>(opt[2], Some(5)), \"opt[2] != Some(5), Is: \" + opt[2]);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/OptionTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    \n    public class OptionTests\n    {\n        [Fact]\n        public void SomeGeneratorTestsObject()\n        {\n            var optional = Some(123);\n\n            optional.Match(Some: i => Assert.True(i == 123),\n                           None: () => Assert.Fail(\"Shouldn't get here\"));\n\n            int c = optional.Match(Some: i => i + 1,\n                                   None: () => 0);\n\n            Assert.True(c == 124);\n        }\n\n        [Fact]\n        public void SomeGeneratorTestsFunction()\n        {\n            var optional = Some(123);\n\n            match(optional, Some: i => Assert.True(i == 123),\n                            None: () => Assert.Fail(\"Shouldn't get here\"));\n\n            int c = match(optional, Some: i => i + 1,\n                                    None: () => 0);\n\n            Assert.True(c == 124);\n        }\n\n        [Fact]\n        public void NoneGeneratorTestsObject()\n        {\n            Option<int> optional = None;\n\n            optional.Match(Some: i => Assert.Fail(\"Shouldn't get here\"),\n                           None: () => Assert.True(true));\n\n            int c = optional.Match(Some: i => i + 1,\n                                   None: () => 0);\n\n            Assert.True(c == 0);\n        }\n\n        [Fact]\n        public void NoneGeneratorTestsFunction()\n        {\n            Option<int> optional = None;\n\n            match(optional, Some: i => Assert.Fail(\"Shouldn't get here\"),\n                            None: () => Assert.True(true));\n\n            int c = match(optional, Some: i => i + 1,\n                                    None: () => 0);\n\n            Assert.True(c == 0);\n        }\n\n        [Fact]\n        public void SomeLinqTest()\n        {\n            var two = Some(2);\n            var four = Some(4);\n            var six = Some(6);\n\n            var expr = from x in two\n                       from y in four\n                       from z in six\n                       select x + y + z;\n\n            match(expr,\n                Some: v => Assert.True(v == 12),\n                None: failwith(\"Shouldn't get here\"));\n        }\n\n        [Fact]\n        public void NoneLinqTest()\n        {\n            var two = Some(2);\n            var four = Some(4);\n            var six = Some(6);\n            Option<int> none = None;\n\n            match(from x in two\n                  from y in four\n                  from _ in none\n                  from z in six\n                  select x + y + z,\n                   Some: v => failwith<int>(\"Shouldn't get here\"),\n                   None: () => Assert.True(true));\n        }\n\n        [Fact]\n        public void OptionFluentSomeNoneTest()\n        {\n            int res1 = GetValue(true)\n                        .Some(x => x + 10)\n                        .None(0);\n\n            int res2 = GetValue(false)\n                        .Some(x => x + 10)\n                        .None(() => 0);\n\n            Assert.True(res1 == 1010);\n            Assert.True(res2 == 0);\n        }\n        [Fact]\n        public void NullableTest()\n        {\n            var res = GetNullable(true)\n                        .Some(v => v)\n                        .None(() => 0);\n\n            Assert.True(res == 1000);\n        }\n\n        [Fact]\n        public void NullableDenySomeNullTest()\n        {\n            Assert.Throws<ValueIsNullException>(\n                    () =>\n                    {\n                        var res = GetNullable(false)\n                                    .Some(v => v)\n                                    .None(() => 0);\n                    }\n                );\n        }\n\n        [Fact]\n        public void BiIterSomeTest()\n        {\n            var x = Some(3);\n            int way = 0;\n            var dummy = x.BiIter(_ => way = 1, () => way = 2);\n            Assert.Equal(1, way);\n        }\n\n        [Fact]\n        public void BiIterNoneTest()\n        {\n            var x = Option<int>.None;\n            int way = 0;\n            var dummy = x.BiIter(_ => way = 1, () => way = 2);\n            Assert.Equal(2, way);\n        }\n\n        [Fact]\n        public void IfNoneSideEffect()\n        {\n            int sideEffectResult = 0;\n\n            Action sideEffectNone = () => sideEffectResult += 1;\n\n            Assert.Equal(0, Option.Some(\"test\").IfNone(sideEffectNone).Return(sideEffectResult));\n            Assert.Equal(1, Option<string>.None.IfNone(sideEffectNone).Return(sideEffectResult));\n        }\n\n        [Fact]\n        public void ISomeSideEffect()\n        {\n            int sideEffectResult = 0;\n\n            Action<string> sideEffectSome = _ => sideEffectResult += 2;\n\n            Assert.Equal(0, Option<string>.None.IfSome(sideEffectSome).Return(sideEffectResult));\n            Assert.Equal(2, Option.Some(\"test\").IfSome(sideEffectSome).Return(sideEffectResult));\n        }\n\n        [Fact]\n        public void OptionToFin()\n        {\n            var e = LanguageExt.Common.Error.New(\"Example error\");\n            var some = Some(123);\n            var none = Option<int>.None;\n\n            var mx = Fin.Succ(123);\n            var my = some.ToFin();\n            var me = none.ToFin(e);\n\n            var e2 = mx.Equals(my);\n            var e1 = mx == my;\n            var e3 = mx.Equals((object)my);\n            \n            Assert.True(e1);\n            Assert.True(e2);\n            Assert.True(e3);\n            Assert.True(me.IsFail);\n        }\n\n        private Option<string?> GetStringNone()\n        {\n            string? nullStr = null;\n            return Some(nullStr);\n        }\n\n        private Option<int> GetNullable(bool select) =>\n            select\n                ? Some((int?)1000)\n                : Some((int?)null);\n\n        private Option<int> GetValue(bool select) =>\n            select\n                ? Some(1000)\n                : None;\n\n        private Option<Option<int>> GetSomeOptionValue(bool select) =>\n            select\n                ? Some(Some(1000))\n                : Some(Option<int>.None);\n\n        private Option<int> ImplicitConversion() => 1000;\n\n        private Option<int> ImplicitNoneConversion() => None;\n\n        private void InferenceTest1()\n        {\n            Action<int> actionint = v => v = v * 2;\n            Option<int> optional1 = Some(123);\n            optional1.Some(actionint) //Compiler tries to call:  public static Option<T> Some(T value)\n                     .None(() => { });\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/OptionUnsafeApply.cs",
    "content": "﻿using System;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class OptionUnsafeApply\n    {\n        Func<int, int, int> add = (a, b) => a + b;\n\n        // TODO: Restore\n\n        //[Fact]\n        //public void ApplySomeArgs()\n        //{\n        //    var opt = SomeUnsafe(add)\n        //        .Apply(SomeUnsafe(3))\n        //        .Apply(SomeUnsafe(4));\n\n        //    Assert.Equal(SomeUnsafe(7), opt);\n        //}\n\n        //[Fact]\n        //public void ApplySomeArgsF()\n        //{\n        //    var opt = apply(apply(SomeUnsafe(add), SomeUnsafe(3)), SomeUnsafe(4));\n        //    Assert.Equal(SomeUnsafe(7), opt);\n        //}\n\n        //[Fact]\n        //public void ApplyNoneArgs()\n        //{\n        //    var opt = SomeUnsafe(add)\n        //        .Apply(None)\n        //        .Apply(SomeUnsafe(4));\n\n        //    Assert.Equal(None, opt);\n        //}\n\n        //[Fact]\n        //public void ApplyNoneArgsF()\n        //{\n        //    var opt = apply(apply(SomeUnsafe(add), None), SomeUnsafe(4));\n        //    Assert.Equal(None, opt);\n        //}\n\n        //[Fact]\n        //public void ApplicativeLawHolds()\n        //{\n        //    var first = SomeUnsafe(add)\n        //        .Apply(SomeUnsafe(3))\n        //        .Apply(SomeUnsafe(4));\n\n        //    var second = SomeUnsafe(3)\n        //        .ParMap(add)\n        //        .Apply(SomeUnsafe(4));\n\n        //    Assert.Equal(first, second);\n        //}\n\n        //[Fact]\n        //public void ApplicativeLawHoldsF()\n        //{\n        //    var first = apply(apply(SomeUnsafe(add), SomeUnsafe(3)), SomeUnsafe(4));\n        //    var second = apply(parmap(SomeUnsafe(3), add), SomeUnsafe(4));\n\n        //    Assert.Equal(first, second);\n        //}\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ParsecIOTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Xunit;\nusing LanguageExt.Common;\nusing LanguageExt.Parsec;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.PrimIO;\nusing static LanguageExt.Parsec.ItemIO;\nusing static LanguageExt.Parsec.IndentIO;\nusing Char = System.Char;\n\nnamespace LanguageExt.Tests\n{\n    public class ParsecIOTests\n    {\n        class Tok\n        {\n            public Tok(int col, int ln, char val)\n            {\n                Col = col;\n                Ln  = ln;\n                Val = val;\n            }\n\n            public readonly int Col;\n            public readonly int Ln;\n            public readonly char Val;\n        }\n\n        [Fact]\n        public void Indent1SuccessTest()\n        {\n            var toks    = Seq(new Tok(1, 1, 'a'), new Tok(2, 1, 'b'), new Tok(2, 2, 'c'), new Tok(1, 3, 'd'), new Tok(1, 4, '1'));\n            var letter  = satisfy<Tok>(t => Char.IsLetter(t.Val));\n            var digit   = satisfy<Tok>(t => Char.IsDigit(t.Val));\n            var letters = many1(attempt(letter));\n            var digits  = many1(attempt(digit));\n\n            var block = from ls1 in indented1<Tok, Seq<Tok>>(letters)\n                        from ls2 in indented1<Tok, Seq<Tok>>(letters)\n                        from dg1 in indented1<Tok, Seq<Tok>>(digits)\n                        from ___ in eof<Tok>()\n                        select (ls1, ls2, dg1);\n\n            var res = block.Parse(toks, t => new Pos(t.Ln - 1, t.Col - 1)).ToEither().IfLeft(() => default);\n\n            Assert.True(res.Item1.Count == 3);\n            Assert.True(res.Item2.Count == 1);\n            Assert.True(res.Item3.Count == 1);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ParsecTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Xunit;\nusing M = LanguageExt.Map;\nusing LanguageExt.Parsec;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Parsec.Prim;\nusing static LanguageExt.Parsec.Char;\nusing static LanguageExt.Parsec.Expr;\nusing static LanguageExt.Parsec.Token;\nusing static LanguageExt.UnitsOfMeasure;\nusing LanguageExt.ClassInstances;\nusing Char = System.Char;\n\nnamespace LanguageExt.Tests\n{\n    public class ParsecTests\n    {\n\n        [Fact]\n        public void MultiLineNestedComments()\n        {\n            var jstp = makeTokenParser(Language.JavaStyle.With(NestedComments: true));\n            var ws = jstp.WhiteSpace;\n            var test3 = parse(ws, @\"\n/*\n*/\n\");\n        }\n\n        [Fact]\n        public void MultiLineComments()\n        {\n            var jstp = makeTokenParser(Language.JavaStyle.With(NestedComments: false));\n            var ws = jstp.WhiteSpace;\n            var test3 = parse(ws, @\"\n/*\n*/\n\");\n        }\n\n        [Fact]\n        public void ResultComb()\n        {\n            var p = result(1234);\n            var r = parse(p, \"Hello\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 1234);\n        }\n\n        [Fact]\n        public void ZeroComb()\n        {\n            var p = zero<Unit>();\n            var r = parse(p, \"Hello\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void ItemComb()\n        {\n            var p = anyChar;\n            var r = parse(p, \"Hello\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 'H');\n            Assert.True(r.Reply.State.ToString() == \"ello\");\n        }\n\n        [Fact]\n        public void ItemFailComb()\n        {\n            var p = anyChar;\n            var r = parse(p, \"\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void Item2Comb()\n        {\n            var p = anyChar;\n            var r1 = parse(p, \"Hello\");\n\n            Assert.False(r1.IsFaulted);\n            Assert.True(r1.Reply.Result == 'H');\n            Assert.True(r1.Reply.State.ToString() == \"ello\");\n\n            var r2 = parse(p, r1.Reply.State);\n\n            Assert.False(r2.IsFaulted);\n            Assert.True(r2.Reply.Result == 'e');\n            Assert.True(r2.Reply.State.ToString() == \"llo\");\n\n        }\n\n        [Fact]\n        public void Item1LinqComb()\n        {\n            var p = from x in anyChar\n                    select x;\n\n            var r = parse(p, \"Hello\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 'H');\n            Assert.True(r.Reply.State.ToString() == \"ello\");\n        }\n\n        [Fact]\n        public void Item2LinqComb()\n        {\n            var p = from x in anyChar\n                    from y in anyChar\n                    select (x, y);\n\n            var r = parse(p, \"Hello\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result.Item1 == 'H');\n            Assert.True(r.Reply.Result.Item2 == 'e');\n            Assert.True(r.Reply.State.ToString() == \"llo\");\n        }\n\n        [Fact]\n        public void EitherFirstComb()\n        {\n            var p = either(ch('a'), ch('1'));\n\n            var r = parse(p, \"a\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 'a');\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void EitherSecondComb()\n        {\n            var p = either(ch('a'), ch('1'));\n\n            var r = parse(p, \"1\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == '1');\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void EitherLINQComb()\n        {\n            var p = from x in either(ch('a'), ch('1'))\n                    from y in either(ch('a'), ch('1'))\n                    select (x, y);\n\n            var r = parse(p, \"a1\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result.Item1 == 'a');\n            Assert.True(r.Reply.Result.Item2 == '1');\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void UpperComb()\n        {\n            var p = upper;\n            var r = parse(p, \"Hello\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 'H');\n            Assert.True(r.Reply.State.ToString() == \"ello\");\n        }\n\n        [Fact]\n        public void UpperFailComb()\n        {\n            var p = upper;\n            var r = parse(p, \"hello\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void LowerComb()\n        {\n            var p = Parsec.Char.lower;\n            var r = parse(p, \"hello\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 'h');\n            Assert.True(r.Reply.State.ToString() == \"ello\");\n        }\n\n        [Fact]\n        public void LowerFailComb()\n        {\n            var p = Parsec.Char.lower;\n            var r = parse(p, \"Hello\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void DigitComb()\n        {\n            var p = digit;\n            var r = parse(p, \"1234\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == '1');\n            Assert.True(r.Reply.State.ToString() == \"234\");\n        }\n\n        [Fact]\n        public void DigitFailComb()\n        {\n            var p = digit;\n            var r = parse(p, \"Hello\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void LetterComb()\n        {\n            var p = letter;\n            var r = parse(p, \"hello\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 'h');\n            Assert.True(r.Reply.State.ToString() == \"ello\");\n        }\n\n        [Fact]\n        public void LetterFailComb()\n        {\n            var p = letter;\n            var r = parse(p, \"1ello\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void WordComb()\n        {\n            var p = asString(many1(letter));\n            var r = parse(p, \"hello   \");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == \"hello\");\n            Assert.True(r.Reply.State.ToString() == \"   \");\n        }\n\n        [Fact]\n        public void WordFailComb()\n        {\n            var p = asString(many1(letter));\n            var r = parse(p, \"1ello  \");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void StringMatchComb()\n        {\n            var p = str(\"hello\");\n            var r = parse(p, \"hello world\");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == \"hello\");\n            Assert.True(r.Reply.State.ToString() == \" world\");\n        }\n\n        [Fact]\n        public void StringMatchFailComb()\n        {\n            var p = str(\"hello\");\n            var r = parse(p, \"no match\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void StringOrdinalIgnoreCase()\n        {\n            var p = str<EqCharOrdinalIgnoreCase>(\"Hello\");\n\n            Assert.Equal(\"hello\", parse(p, \"hello\").ToOption());\n            Assert.Equal(\"Hello\", parse(p, \"Hello\").ToOption());\n            Assert.Equal(\"HELLO\" , parse(p, \"HELLO\").ToOption());\n            Assert.Equal(\"hELLO\", parse(p, \"hELLO\").ToOption());\n            Assert.True(parse(p, \"olleH\").IsFaulted);\n            Assert.True(parse(p, \"Héllo\").IsFaulted);\n        }\n\n        [Fact]\n        public void NaturalNumberComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.Natural;\n            var r = parse(p, \"1234  \");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 1234);\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void NaturalNumberFailComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.Natural;\n            var r = parse(p, \"no match\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void IntegerNumberComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.Integer;\n            var r = parse(p, \"1234  \");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 1234);\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void IntegerNegativeNumberComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.Integer;\n            var r = parse(p, \"-1234  \");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == -1234);\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void IntegerNumberFailComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.Integer;\n            var r = parse(p, \"no match\");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void BracketAndIntegerComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = from x in tok.Brackets(tok.Integer)\n                    from _ in tok.WhiteSpace\n                    select x;\n\n            var r = parse(p, \"[1]  \");\n\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == 1);\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void BracketAndIntegerFailComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.Brackets(tok.Integer);\n            var r = parse(p, \"[x]  \");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void BracketAndIntegerListComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = from x in tok.BracketsCommaSep(tok.Integer)\n                    from _ in tok.WhiteSpace\n                    select x;\n            var r = parse(p, \"[1,2,3,4]  \");\n\n            Assert.False(r.IsFaulted);\n\n            var arr = r.Reply.Result.ToArray();\n            Assert.True(arr[0] == 1);\n            Assert.True(arr[1] == 2);\n            Assert.True(arr[2] == 3);\n            Assert.True(arr[3] == 4);\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void BracketAndSpacedIntegerListComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = from x in tok.BracketsCommaSep(tok.Integer)\n                    from _ in tok.WhiteSpace\n                    select x;\n\n            var r = parse(p, \"[ 1, 2 ,3,   4]  \");\n\n            Assert.False(r.IsFaulted);\n\n            var arr = r.Reply.Result.ToArray();\n            Assert.True(arr[0] == 1);\n            Assert.True(arr[1] == 2);\n            Assert.True(arr[2] == 3);\n            Assert.True(arr[3] == 4);\n            Assert.True(r.Reply.State.ToString() == \"\");\n        }\n\n        [Fact]\n        public void BracketAndIntegerListFailComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.BracketsCommaSep(tok.Integer);\n            var r = parse(p, \"[1,x,3,4]  \");\n\n            Assert.True(r.IsFaulted);\n        }\n\n        [Fact]\n        public void JunkEmptyComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.WhiteSpace;\n            var r = parse(p, \"\");\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == unit);\n        }\n\n        [Fact]\n        public void JunkNoMatchComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.WhiteSpace;\n            var r = parse(p, \",\");\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == unit);\n        }\n\n        [Fact]\n        public void JunkFourSpacesComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.WhiteSpace;\n            var r = parse(p, \"    ,\");\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == unit);\n        }\n\n        [Fact]\n        public void JunkFourSpacesThenCommentComb()\n        {\n            var tok = makeTokenParser(Language.JavaStyle);\n            var p = tok.WhiteSpace;\n            var r = parse(p, \"    // A comment\\nabc\");\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == unit);\n            Assert.True(r.Reply.State.ToString() == \"abc\");\n        }\n\n        [Fact]\n        public void StringLiteralComb()\n        {\n            var tok = makeTokenParser(Language.HaskellStyle);\n\n            var p = tok.StringLiteral;\n            var r = parse(p, \"\\\"/abc\\\"\");\n            Assert.False(r.IsFaulted);\n            Assert.True(r.Reply.Result == \"/abc\");\n        }\n\n        [Theory]\n        [InlineData(\"1234\")]\n        [InlineData(\"12345\")]\n        [InlineData(\"123456\")]\n        [InlineData(\"1234567\")]\n        [InlineData(\"12345678\")]\n        public void ParseNTimes(string input)\n        {\n            var p = asString(manyn(digit, 4));\n\n            var r = parse(p, input).ToEither();\n\n            Assert.True(r.IfLeft(\"\") == \"1234\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\"1\")]\n        [InlineData(\"12\")]\n        [InlineData(\"123\")]\n        public void ParseNTimesFail(string input)\n        {\n            var p = asString(manyn(digit, 4));\n\n            var r = parse(p, input).ToEither();\n\n            Assert.True(r.IsLeft);\n        }\n\n        [Theory]\n        [InlineData(\"1\", \"1\")]\n        [InlineData(\"12\", \"12\")]\n        [InlineData(\"123\", \"123\")]\n        [InlineData(\"1234\", \"1234\")]\n        [InlineData(\"12345\", \"1234\")]\n        public void ParseN1Times(string input, string expected)\n        {\n            var p = asString(manyn1(digit, 4));\n\n            var r = parse(p, input).ToEither();\n\n            Assert.True(r.IfLeft(\"\") == expected);\n        }\n\n        [Fact]\n        public void ParseN1TimesFail()\n        {\n            var p = asString(manyn1(digit, 4));\n\n            var r = parse(p, \"\").ToEither();\n\n            Assert.True(r.IsLeft);\n        }\n\n        [Theory]\n        [InlineData(\"\", \"\")]\n        [InlineData(\"1\", \"1\")]\n        [InlineData(\"12\", \"12\")]\n        [InlineData(\"123\", \"123\")]\n        [InlineData(\"1234\", \"1234\")]\n        [InlineData(\"12345\", \"1234\")]\n        public void ParseN0Times(string input, string expected)\n        {\n            var p = asString(manyn0(digit, 4));\n\n            var r = parse(p, input).ToEither();\n\n            Assert.True(r.IfLeft(\"\") == expected);\n        }\n        \n        [Fact]\n        public void ParseN0TimesZeroNegative()\n        {\n            Assert.True(parse(asString(manyn0(digit, 0)), \"123\").ToEither().IfLeft(\"x\") == \"\");\n            Assert.True(parse(asString(manyn0(digit, -1)), \"123\").ToEither().IfLeft(\"x\") == \"\");\n        }\n\n        [Fact]\n        public void SepByTest()\n        {\n            // greedy, but works because of nice input\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(sepBy1(asString(many1(alphaNum)), ch('/')), \"this/is/a/path\").ToEither());\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(sepBy1(asString(many1(alphaNum)), ch('/')), \"this/is/a/path.\").ToEither());\n\n            // greedy + runs into dead end\n            Assert.True(parse(sepBy1(asString(many1(alphaNum)), ch('/')), \"this/is/a/path/\").IsFaulted);\n\n            // consume as many items as possible without failing\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(from x in asString(many1(alphaNum)) from xs in many(attempt(from sep in ch('/') from word in asString(many1(alphaNum)) select word)) select x.Cons(xs), \"this/is/a/path/\").ToEither());\n        }\n\n        [Fact]\n        public void EndByTest()\n        {\n            // greedy, but works because of nice input\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"folder\"), parse(endBy1(asString(many1(alphaNum)), ch('/')), \"this/is/a/folder//\").ToEither());\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"folder\"), parse(endBy1(asString(many1(alphaNum)), ch('/')), \"this/is/a/folder/\").ToEither());\n\n            // greedy + runs into dead end\n            Assert.True(parse(endBy1(attempt(asString(many1(alphaNum))), attempt(ch('/'))), \"this/is/a/folder/filename\").IsFaulted);\n\n            // consume as many items as possible without failing\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"folder\"), parse(many1(attempt(from word in asString(many1(alphaNum)) from sep in ch('/') select word)), \"this/is/a/folder/filename\").ToEither());\n        }\n\n        [Fact]\n        public void SepEndByTest()\n        {\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(sepEndBy1(asString(many1(alphaNum)), ch('/')), \"this/is/a/path//\").ToEither());\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(sepEndBy1(asString(many1(alphaNum)), ch('/')), \"this/is/a/path/\").ToEither());\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(sepEndBy1(asString(many1(alphaNum)), ch('/')), \"this/is/a/path\").ToEither());\n            Assert.True(parse(sepEndBy1(asString(many1(alphaNum)), ch('/')), \".\").IsFaulted);\n            \n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(sepEndBy(asString(many1(alphaNum)), ch('/')), \"this/is/a/path//\").ToEither());\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(sepEndBy(asString(many1(alphaNum)), ch('/')), \"this/is/a/path/\").ToEither());\n            Assert.Equal(Seq(\"this\", \"is\", \"a\", \"path\"), parse(sepEndBy(asString(many1(alphaNum)), ch('/')), \"this/is/a/path\").ToEither());\n            Assert.Equal(Seq<string>(), parse(sepEndBy(asString(many1(alphaNum)), ch('/')), \".\").ToEither());\n\n        }\n        \n        [Fact]\n        public void ParallelCheck()\n        {\n            // works\n            Parallel.ForEach(Enumerable.Repeat(\"\", 4), str => parse(from _ in notFollowedBy(anyChar).label(\"end of input\") select unit, str));\n            \n            // sometimes crashes (net461)\n            Parallel.ForEach(Enumerable.Repeat(\"\", 4), str => parse(from _ in eof select unit, str));\n        }\n\n        [Fact]\n        public void FlattenCheck()\n        {\n            Parser<string> HexDigitParser() =>\n                from hexDigitString in asString(flatten(sepBy1(many1(hexDigit), ch('-'))))\n                from end in eof\n                select hexDigitString;\n\n            Assert.Equal(\"17CBA779DF1E4794A4992AAB59802C19\", parse(HexDigitParser(), \"17CBA779-DF1E-4794-A499-2AAB59802C19\").ToOption());\n            Assert.Equal(\"17CBA779DF1E4794A4992AAB59802C19\", parse(HexDigitParser(), \"17CBA779DF1E4794A4992AAB59802C19\").ToOption());\n            Assert.Equal(Option<string>.None, parse(HexDigitParser(), \"-17CBA779-DF1E-4794-A499-2AAB59802C19\").ToOption());       \n            Assert.Equal(Option<string>.None, parse(HexDigitParser(), \"17CBA779-DF1E-4794-A499--2AAB59802C19\").ToOption());\n        }\n        \n        [Fact]\n        public void ConsCheck()\n        {\n            Parser<string> HexDigitBlocksParser() =>\n                from guidString in asString(flatten(cons(many1(hexDigit), many(cons(ch('-'), many1(hexDigit))))))\n                from end in eof\n                select guidString;\n\n            Assert.Equal(\"17CBA779-DF1E-4794-A499-2AAB59802C19\", parse(HexDigitBlocksParser(), \"17CBA779-DF1E-4794-A499-2AAB59802C19\").ToOption());\n            Assert.Equal(\"17CBA779DF1E4794A4992AAB59802C19\", parse(HexDigitBlocksParser(), \"17CBA779DF1E4794A4992AAB59802C19\").ToOption());\n            Assert.Equal(Option<string>.None, parse(HexDigitBlocksParser(), \"-17CBA779-DF1E-4794-A499-2AAB59802C19\").ToOption());       \n            Assert.Equal(Option<string>.None, parse(HexDigitBlocksParser(), \"17CBA779-DF1E-4794-A499--2AAB59802C19\").ToOption());\n        }\n        \n        [Fact]\n        public void EMailParserCheck()\n        {\n            // Note: This e-mail parser is not correct! See https://tools.ietf.org/html/rfc5322#section-3.4.1 and related RFCs\n            Parser<string> QuickAndDirtyEMailParser() =>\n                from localpart in asString(flatten(cons(many1(alphaNum), many(cons(oneOf('-','.'), many1(alphaNum)))))) // simple name\n                from at in ch('@')\n                from domain in asString(flatten(cons(many1(alphaNum), many1(cons(ch('.'), many1(alphaNum)))))) // domain with at least one dot\n             select $\"{localpart}{at}{domain.ToLower()}\";\n\n            Assert.Equal(\"john@example.org\", parse(QuickAndDirtyEMailParser(), \"john@EXAMPLE.org\").ToOption());\n            Assert.EndsWith(\"expecting letter or digit or '@'\", parse(QuickAndDirtyEMailParser(), \"john @EXAMPLE.org\").ToEither().IfRight(\"\"));\n            Assert.EndsWith(\"expecting letter or digit\", parse(QuickAndDirtyEMailParser(), \".john @EXAMPLE.org\").ToEither().IfRight(\"\"));\n            Assert.EndsWith(\"expecting letter or digit or '.'\", parse(QuickAndDirtyEMailParser(), \"john.doe@EXAMPLE\").ToEither().IfRight(\"\"));\n            Assert.Equal(\"john-doe@example.org\", parse(QuickAndDirtyEMailParser(), \"john-doe@EXAMPLE.org\").ToOption());\n            Assert.Equal(\"john.doe@example.org\", parse(QuickAndDirtyEMailParser(), \"john.doe@EXAMPLE.org\").ToOption());\n        }\n\n        [Fact]\n        public void Issue889()\n        {\n            // Code adapted from the AccountingDSL example, keeping only the basic arithmetic operators\n            var opChars = \"+-*/\";\n\n            var definition = GenLanguageDef.Empty.With(\n                CommentStart: \"/*\",\n                CommentEnd: \"*/\",\n                CommentLine: \"//\",\n                NestedComments: true,\n                OpStart: oneOf(opChars),\n                OpLetter: oneOf(opChars),\n                IdentStart: letter,\n                IdentLetter: either(alphaNum, ch('_')),\n                ReservedNames: Empty,\n                ReservedOpNames: List(\"+\", \"-\", \"*\", \"/\")\n            );\n\n            var lexer = makeTokenParser(definition);\n            var input = \"3.14159\";\n            var result = lexer.NaturalOrFloat.Parse(input).ToEither().Map(x => x.IfLeft(Double.MaxValue));\n                // > Success(Right(1418.9))\n\n            var expected = lexer.Float.Parse(input).ToEither().IfLeft(Double.MinValue);\n                // > Success(3.14159)\n\n            Assert.True(result == expected);\n        }\n\n        [Fact]\n        public void Nat_or_float_must_be_int()\n        {\n            var opChars = \"+-*/\";\n\n            var definition = GenLanguageDef.Empty.With(\n                CommentStart: \"/*\",\n                CommentEnd: \"*/\",\n                CommentLine: \"//\",\n                NestedComments: true,\n                OpStart: oneOf(opChars),\n                OpLetter: oneOf(opChars),\n                IdentStart: letter,\n                IdentLetter: either(alphaNum, ch('_')),\n                ReservedNames: Empty,\n                ReservedOpNames: List(\"+\", \"-\", \"*\", \"/\")\n            );\n\n            var lexer  = makeTokenParser(definition);\n            var input  = \"300\";\n            var result = lexer.NaturalOrFloat.Parse(input).ToEither().Map(x => x.IfRight(0));\n            Assert.True(result == 300);\n        }\n\n        [Fact]\n        public void ExpressionResultShouldBeSixDueToMultiplicationOperationPriority()\n        {\n            // Arrange\n            var tokenParser = makeTokenParser(Language.JavaStyle);\n            var reservedOp = tokenParser.ReservedOp;\n\n            // Natural parser\n            var natural = from n in tokenParser.Natural\n                          select Expr.Natural(n);\n\n            // Binary operator expression factory\n            Func<Expr, Expr, Expr> binaryOp(string op) =>\n                (Expr lhs, Expr rhs) =>\n                    op == \"+\" ? Expr.Add(lhs, rhs)\n                  : op == \"-\" ? Expr.Sub(lhs, rhs)\n                  : op == \"/\" ? Expr.Div(lhs, rhs)\n                  : op == \"*\" ? Expr.Mul(lhs, rhs)\n                  : throw new NotSupportedException();\n\n            // Binary operator parser builder\n            Operator<Expr> binary(string op, Assoc assoc) =>\n                Operator.Infix(assoc,\n                    from x in reservedOp(op)\n                    select binaryOp(op));\n\n            // Operator table\n            Operator<Expr>[][] table =\n            {\n                new[] { binary(\"+\", Assoc.Left), binary(\"-\", Assoc.Left) },\n                new[] { binary(\"*\", Assoc.Left), binary(\"/\", Assoc.Left) }\n            };\n\n            // Null because it will be not null later and can be used by the lazyp parser\n            Parser<Expr> expr = null; \n\n            // Build up the expression term\n            var term = either(\n                            attempt(natural), \n                            tokenParser.Parens(lazyp(() => expr)));\n\n            // Build the expression parser\n            expr = buildExpressionParser(table, term).label(\"expression\");\n\n\n            var expression = \"2 + 2 * 2\";\n            var exprectedResult = 6;\n\n            // Act\n            var actualResult = parse(expr, expression)\n                                  .ToOption()\n                                  .Map(ex => ex.Eval())\n                                  .IfNone(0);\n\n            // Assert\n            Assert.Equal(exprectedResult, actualResult);\n        }\n\n        public abstract class Expr\n        {\n            public abstract int Eval();\n\n            public static Expr Natural(int x) => new NaturalExpr(x);\n            public static Expr Add(Expr left, Expr right) => new AddExpr(left, right);\n            public static Expr Sub(Expr left, Expr right) => new SubExpr(left, right);\n            public static Expr Mul(Expr left, Expr right) => new MulExpr(left, right);\n            public static Expr Div(Expr left, Expr right) => new DivExpr(left, right);\n\n            public class NaturalExpr : Expr\n            {\n                public int Value;\n                public NaturalExpr(int value) => Value = value;\n                public override int Eval() => Value;\n            }\n\n            public class AddExpr : Expr\n            {\n                public readonly Expr Left;\n                public readonly Expr Right;\n                public AddExpr(Expr left, Expr right)\n                {\n                    Left = left;\n                    Right = right;\n                }\n                public override int Eval() =>\n                    Left.Eval() + Right.Eval();\n            }\n            public class SubExpr : Expr\n            {\n                public readonly Expr Left;\n                public readonly Expr Right;\n                public SubExpr(Expr left, Expr right)\n                {\n                    Left = left;\n                    Right = right;\n                }\n                public override int Eval() =>\n                    Left.Eval() - Right.Eval();\n            }\n            public class MulExpr : Expr\n            {\n                public readonly Expr Left;\n                public readonly Expr Right;\n                public MulExpr(Expr left, Expr right)\n                {\n                    Left = left;\n                    Right = right;\n                }\n                public override int Eval() =>\n                    Left.Eval() * Right.Eval();\n            }\n            public class DivExpr : Expr\n            {\n                public readonly Expr Left;\n                public readonly Expr Right;\n                public DivExpr(Expr left, Expr right)\n                {\n                    Left = left;\n                    Right = right;\n                }\n                public override int Eval() =>\n                    Left.Eval() / Right.Eval();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/AbstractParseTPrecisionIntervalTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public abstract class AbstractParseTPrecisionIntervalTests<T>\n        : AbstractParseTTests<T>\n        where T : struct\n    {\n        protected abstract T MinValue { get; }\n        protected abstract T MaxValue { get; }\n\n        [Fact]\n        public void ParseT_ValidStringFromMinValue_SomeMinValue() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(MinValue);\n\n        [Fact]\n        public void ParseT_ValidStringFromMaxValue_SomeMaxValue() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(MaxValue);\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/AbstractParseTSignedPrecisionIntervalTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public abstract class AbstractParseTSignedPrecisionIntervalTests<T>\n        : AbstractParseTPrecisionIntervalTests<T>\n        where T : struct\n    {\n        protected abstract T NegativeOne { get; }\n        protected abstract T PositiveOne { get; }\n\n        [Fact]\n        public void ParseT_ValidStringFromNegativeOne_SomeNegativeOne() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(NegativeOne);\n\n        [Fact]\n        public void ParseT_ValidStringFromPositiveOne_SomePositiveOne() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(PositiveOne);\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/AbstractParseTTests.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public abstract class AbstractParseTTests<T> where T : struct\n    {\n        protected abstract Option<T> ParseT(string value);\n\n        [Fact]\n        public void ParseT_NullString_None()\n        {\n            Option<T> expected = None;\n            var actual = ParseT(null);\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void ParseT_EmptyString_None()\n        {\n            Option<T> expected = None;\n            var actual = ParseT(\"\");\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void ParseT_ValidStringFromDefaultValue_SomeDefaultValue() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(default(T));\n\n        protected void ParseT_ValidStringFromGiven_SomeAsGiven(T expected) =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(expected, expected.ToString());\n\n        protected void ParseT_ValidStringFromGivenToLower_SomeAsGiven(T expected) =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(expected, expected.ToString().ToLower());\n\n        private void ParseT_ValidStringFromGiven_SomeAsGiven(T expected, string value)\n        {\n            var actual = ParseT(value);\n            Assert.Equal(expected, actual);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/AbstractParseTUnsignedPrecisionIntervalTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public abstract class AbstractParseTUnsignedPrecisionIntervalTests<T>\n        : AbstractParseTPrecisionIntervalTests<T>\n        where T : struct\n    {\n        protected abstract T PositiveOne { get; }\n        protected abstract T PositiveTwo { get; }\n\n        [Fact]\n        public void ParseT_ValidStringFromPositiveOne_SomePositiveOne() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(PositiveOne);\n\n        [Fact]\n        public void ParseT_ValidStringFromPositiveTwo_SomePositiveTwo() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(PositiveTwo);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseBoolTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public class parseBoolTests : AbstractParseTTests<bool>\n    {\n        protected override Option<bool> ParseT(string value) => Prelude.parseBool(value);\n\n        [Fact]\n        public void parseBool_ValidStringFromTrue_SomeTrue() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(true);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseByteTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseByteTests : AbstractParseTUnsignedPrecisionIntervalTests<byte>\n    {\n        protected override Option<byte> ParseT(string value) => Prelude.parseByte(value);\n\n        protected override byte MinValue => byte.MinValue;\n        protected override byte MaxValue => byte.MaxValue;\n        protected override byte PositiveOne => 1;\n        protected override byte PositiveTwo => 2;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseCharTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public class parseCharTests : AbstractParseTPrecisionIntervalTests<char>\n    {\n        protected override Option<char> ParseT(string value) => Prelude.parseChar(value);\n\n        protected override char MinValue => char.MinValue;\n        protected override char MaxValue => char.MaxValue;\n\n        [Theory]\n        [InlineData('a')]\n        [InlineData('1')]\n        [InlineData(' ')]\n        public void parseChar_ValidStringFromGiven_SomeAsGiven(char value) =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseDateTimeOffsetTests.cs",
    "content": "﻿using System;\nusing Xunit;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace LanguageExt.Tests.Parsing;\n\npublic class parseDateTimeOffsetTests : AbstractParseTTests<DateTimeOffset>\n{\n    protected override Option<DateTimeOffset> ParseT(string value) => Prelude.parseDateTimeOffset(value);\n\n    [Fact]\n    public void parseDateTimeOffset_ValidStringFromNewMillennium_SomeUtc() =>\n        ParseT_ValidStringFromGiven_SomeAsGiven(new DateTimeOffset(2001, 1, 1, 12, 0, 0, 0 * hours));\n\n    [Fact]\n    public void parseDateTimeOffset_ValidStringFromNewMillennium_SomeBerlin() =>\n        ParseT_ValidStringFromGiven_SomeAsGiven(new DateTimeOffset(2001, 1, 1, 12, 0, 0, 1 * hours));\n\n    [Fact]\n    public void parseDateTimeOffset_ISO8601_SomeBerlin() =>\n        Assert.Equal(Some(new DateTimeOffset(2018, 1, 25, 15, 32, 5, 1 * hours)), parseDateTimeOffset(\"2018-01-25T15:32:05+01:00\"));\n\n    [Fact]\n    public void parseDateTimeOffset_ISO8601_SomeUtc() =>\n        Assert.Equal(Some(new DateTimeOffset(2018, 1, 25, 15, 32, 5, 0 * hours)), parseDateTimeOffset(\"2018-01-25T15:32:05Z\"));\n\n    [Fact]\n    public void parseDateTimeOffset_Universal_SomeBerlin() =>\n        Assert.Equal(Some(new DateTimeOffset(2018, 1, 25, 15, 32, 5, 1 * hours)), parseDateTimeOffset(\"2018-01-25 15:32:05+01:00\"));\n\n    [Fact]\n    public void parseDateTimeOffset_Universal_SomeUtc() =>\n        Assert.Equal(Some(new DateTimeOffset(2018, 1, 25, 15, 32, 5, 0 * hours)), parseDateTimeOffset(\"2018-01-25 15:32:05Z\"));\n\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseDateTimeTests.cs",
    "content": "﻿using System;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public class parseDateTimeTests : AbstractParseTTests<DateTime>\n    {\n        protected override Option<DateTime> ParseT(string value) => Prelude.parseDateTime(value);\n\n        [Fact]\n        public void parseDateTime_ValidStringFromNewMillennium_SomeNewMillennium() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(new DateTime(2001, 1, 1));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseDecimalTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseDecimalTests : AbstractParseTPrecisionIntervalTests<decimal>\n    {\n        protected override Option<decimal> ParseT(string value) => Prelude.parseDecimal(value);\n\n        protected override decimal MinValue => decimal.MinValue;\n        protected override decimal MaxValue => decimal.MaxValue;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseDoubleTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public class parseDoubleTests : AbstractParseTTests<double>\n    {\n        protected override Option<double> ParseT(string value) => Prelude.parseDouble(value);\n\n        [Theory]\n        [InlineData(0.5)]\n        [InlineData(-0.5)]\n        [InlineData(double.Epsilon)]\n        [InlineData(double.NegativeInfinity)]\n        [InlineData(double.PositiveInfinity)]\n        public void parseDouble_ValidStringFromGiven_SomeAsGiven(double value) =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseEnumTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public class parseEnumTests : AbstractParseTTests<FooBarEnum>\n    {\n        protected override Option<FooBarEnum> ParseT(string value) => Prelude.parseEnum<FooBarEnum>(value);\n\n        [Fact]\n        public void parseEnum_ValidStringFromFoo_SomeFoo() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(FooBarEnum.Foo);\n\n        [Fact]\n        public void parseEnum_ValidStringFromBar_SomeBar() =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(FooBarEnum.Bar);\n\n    }\n\n    public class parseEnumIgnoreCaseTests : AbstractParseTTests<FooBarEnum>\n    {\n        protected override Option<FooBarEnum> ParseT(string value) => Prelude.parseEnumIgnoreCase<FooBarEnum>(value);\n\n        [Fact]\n        public void parseEnum_ValidStringFromFoo_SomeFoo() =>\n            ParseT_ValidStringFromGivenToLower_SomeAsGiven(FooBarEnum.Foo);\n\n        [Fact]\n        public void parseEnum_ValidStringFromBar_SomeBar() =>\n            ParseT_ValidStringFromGivenToLower_SomeAsGiven(FooBarEnum.Bar);\n\n    }\n\n    public enum FooBarEnum\n    {\n        Foo,\n        Bar\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseFloatTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public class parseFloatTests : AbstractParseTTests<float>\n    {\n        protected override Option<float> ParseT(string value) => Prelude.parseFloat(value);\n\n        [Theory]\n        [InlineData(0.5)]\n        [InlineData(-0.5)]\n        [InlineData(float.Epsilon)]\n        [InlineData(float.NegativeInfinity)]\n        [InlineData(float.PositiveInfinity)]\n        //[InlineData(float.NaN)] TODO -- Why is this here?\n        public void parseFloat_ValidStringFromGiven_SomeAsGiven(float value) =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(value);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseGuidTests.cs",
    "content": "﻿using System;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public class parseGuidTests : AbstractParseTTests<Guid>\n    {\n        protected override Option<Guid> ParseT(string value) => Prelude.parseGuid(value);\n\n        [Fact]\n        public void ParseGuid_ValidStringFixedGuid_SomeOfSameFixedGuid()\n        {\n            var guid = Guid.Parse(\"F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4\");\n            ParseT_ValidStringFromGiven_SomeAsGiven(guid);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseIntTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseIntTests : AbstractParseTSignedPrecisionIntervalTests<int>\n    {\n        protected override Option<int> ParseT(string value) => Prelude.parseInt(value);\n\n        protected override int MinValue => int.MinValue;\n        protected override int MaxValue => int.MaxValue;\n        protected override int NegativeOne => -1;\n        protected override int PositiveOne => 1;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseLongTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseLongTests : AbstractParseTSignedPrecisionIntervalTests<long>\n    {\n        protected override Option<long> ParseT(string value) => Prelude.parseLong(value);\n\n        protected override long MinValue => long.MinValue;\n        protected override long MaxValue => long.MaxValue;\n        protected override long NegativeOne => -1;\n        protected override long PositiveOne => 1;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseSByteTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseSByteTests : AbstractParseTSignedPrecisionIntervalTests<sbyte>\n    {\n        protected override Option<sbyte> ParseT(string value) => Prelude.parseSByte(value);\n\n        protected override sbyte MinValue => sbyte.MinValue;\n        protected override sbyte MaxValue => sbyte.MaxValue;\n        protected override sbyte NegativeOne => -1;\n        protected override sbyte PositiveOne => 1;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseShortTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseShortTests : AbstractParseTSignedPrecisionIntervalTests<short>\n    {\n        protected override Option<short> ParseT(string value) => Prelude.parseShort(value);\n\n        protected override short MinValue => short.MinValue;\n        protected override short MaxValue => short.MaxValue;\n        protected override short NegativeOne => -1;\n        protected override short PositiveOne => 1;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseTimeSpanTests.cs",
    "content": "﻿using System;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Parsing\n{\n    public class parseTimeSpanTests : AbstractParseTTests<TimeSpan>\n    {\n        protected override Option<TimeSpan> ParseT(string value) => Prelude.parseTimeSpan(value);\n\n        [Fact]\n        public void parseTimeSpan_valid() =>\n            Assert.Equal(Prelude.Some(new TimeSpan(0, 0, 0, 19, 12)), Prelude.parseTimeSpan(\"00:00:19.0120000\"));\n\n        [Theory]\n        [InlineData(\"00:00:19.1200000\")]\n        [InlineData(\"00:00:19\")]\n        [InlineData(\"00:00\")]\n        public void parseTimeSpan_multipleValid(string input) =>\n            ParseT_ValidStringFromGiven_SomeAsGiven(TimeSpan.Parse(input));\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\"petter\")]\n        [InlineData(\"0:60:0\")]\n        [InlineData(\"0:0:60\")]\n        [InlineData(\".123\")]\n        [InlineData(\"10.12\")]\n        public void parseTimeSpan_multipleInvalid(string input) => Assert.Equal(Prelude.None, Prelude.parseTimeSpan(input));\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseUIntTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseUIntTests : AbstractParseTUnsignedPrecisionIntervalTests<uint>\n    {\n        protected override Option<uint> ParseT(string value) => Prelude.parseUInt(value);\n\n        protected override uint MinValue => uint.MinValue;\n        protected override uint MaxValue => uint.MaxValue;\n        protected override uint PositiveOne => 1;\n        protected override uint PositiveTwo => 2;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseULongTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseULongTests : AbstractParseTUnsignedPrecisionIntervalTests<ulong>\n    {\n        protected override Option<ulong> ParseT(string value) => Prelude.parseULong(value);\n\n        protected override ulong MinValue => ulong.MinValue;\n        protected override ulong MaxValue => ulong.MaxValue;\n        protected override ulong PositiveOne => 1;\n        protected override ulong PositiveTwo => 2;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Parsing/parseUShortTests.cs",
    "content": "﻿namespace LanguageExt.Tests.Parsing\n{\n    public class parseUShortTests : AbstractParseTUnsignedPrecisionIntervalTests<ushort>\n    {\n        protected override Option<ushort> ParseT(string value) => Prelude.parseUShort(value);\n\n        protected override ushort MinValue => ushort.MinValue;\n        protected override ushort MaxValue => ushort.MaxValue;\n        protected override ushort PositiveOne => 1;\n        protected override ushort PositiveTwo => 2;\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/PartialAndCurryingTests.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class PartialAndCurryingTests\n    {\n        [Fact]\n        public void CurryTest()\n        {\n            var add = curry((int x, int y) => x + y);\n            Assert.True(add(10)(5) == 15);\n        }\n\n        [Fact]\n        public void PartialTest1()\n        {\n            var partial = curry((int x, int y) => x + y)(10);\n\n            Assert.True(partial(5) == 15);\n        }\n\n        [Fact]\n        public void PartialTest2()\n        {\n            var partial = par((int x, int y) => x + y, 10);\n\n            Assert.True(partial(5) == 15);\n        }\n\n        [Fact]\n        public void PartialTest3()\n        {\n            var partial = par((int x, int y, int c, int d) => x + y + c + d, 10, 10);\n\n            Assert.True(partial(5, 5) == 30);\n        }\n\n        [Fact]\n        public void CurryPartialTest()\n        {\n            var partial = curry(par((int x, int y, int c, int d) => x + y + c + d, 10, 10));\n\n            Assert.True(partial(5)(5) == 30);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/PatchTests.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing static LanguageExt.Patch;\nusing LanguageExt.ClassInstances;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    public class PatchTests\n    {\n        [Fact]\n        public void PatchAppendEmptyIsPatch()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Hello\", \"World\", \"Again\");\n\n            var patchA = diff<EqString, string>(docA, docB);\n            var patchB = append(patchA, Patch<EqString, string>.Empty);\n\n            Assert.True(patchA == patchB);\n        }\n\n        [Fact]\n        public void EmptyPatchAppendPatchIsPatch()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Hello\", \"World\", \"Again\");\n\n            var patchA = diff<EqString, string>(docA, docB);\n            var patchB = append(Patch<EqString, string>.Empty, patchA);\n\n            Assert.True(patchA == patchB);\n        }\n\n        [Fact]\n        public void PatchCommutes()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Hello\", \"World\", \"Again\");\n            var docC = List(\"World\");\n            var docD = List(\"World\", \"War\");\n\n            var patchAB = diff<EqString, string>(docA, docB);\n            var patchBC = diff<EqString, string>(docB, docC);\n            var patchCD = diff<EqString, string>(docC, docD);\n\n            var patchA_BC = append(patchAB, append(patchBC, patchCD));\n            var patchAB_C = append(append(patchAB, patchBC), patchCD);\n\n            Assert.True(patchA_BC == patchAB_C);\n        }\n\n        [Fact]\n        public void InsertAtEndDiff()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Hello\", \"World\", \"Again\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Insert.New(2, \"Again\"));\n        }\n\n        [Fact]\n        public void InsertAtBeginningDiff()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Again\", \"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Insert.New(0, \"Again\"));\n        }\n\n        [Fact]\n        public void InsertAtMidDiff()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Hello\", \"Again\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Insert.New(1, \"Again\"));\n        }\n\n        [Fact]\n        public void InsertMultiDiff()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 3);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Insert.New(0, \"It's\"));\n            Assert.True(patch.Edits.Tail.Head == Edit<EqString, string>.Insert.New(1, \"Again\"));\n            Assert.True(patch.Edits.Tail.Tail.Head == Edit<EqString, string>.Insert.New(2, \"Cheers\"));\n        }\n\n\n        [Fact]\n        public void DeleteAtEndDiff()\n        {\n            var docA = List(\"Hello\", \"World\", \"Again\");\n            var docB = List(\"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Delete.New(2, \"Again\"));\n        }\n\n        [Fact]\n        public void DeleteAtBeginningDiff()\n        {\n            var docA = List(\"Again\", \"Hello\", \"World\");\n            var docB = List(\"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Delete.New(0, \"Again\"));\n        }\n\n        [Fact]\n        public void DeleteAtMidDiff()\n        {\n            var docA = List(\"Hello\", \"Again\", \"World\");\n            var docB = List(\"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Delete.New(1, \"Again\"));\n        }\n\n        [Fact]\n        public void DeleteMultiDiff()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 3);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Delete.New(0, \"It's\"));\n            Assert.True(patch.Edits.Tail.Head == Edit<EqString, string>.Delete.New(2, \"Again\"));\n            Assert.True(patch.Edits.Tail.Tail.Head == Edit<EqString, string>.Delete.New(4, \"Cheers\"));\n        }\n\n\n        [Fact]\n        public void ReplaceAtEndDiff()\n        {\n            var docA = List(\"Hello\", \"World\", \"Again\");\n            var docB = List(\"Hello\", \"World\", \"Once More\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Replace.New(2, \"Again\", \"Once More\"));\n        }\n\n        [Fact]\n        public void ReplaceAtBeginningDiff()\n        {\n            var docA = List(\"Again\", \"Hello\", \"World\");\n            var docB = List(\"Once More\", \"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Replace.New(0, \"Again\", \"Once More\"));\n        }\n\n        [Fact]\n        public void ReplaceAtMidDiff()\n        {\n            var docA = List(\"Hello\", \"Again\", \"World\");\n            var docB = List(\"Hello\", \"Once More\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 1);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Replace.New(1, \"Again\", \"Once More\"));\n        }\n\n        [Fact]\n        public void ReplaceMultiDiff()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            Assert.True(patch.Edits.Count == 3);\n            Assert.True(patch.Edits.Head == Edit<EqString, string>.Replace.New(0, \"It's\", \"Yes\"));\n            Assert.True(patch.Edits.Tail.Head == Edit<EqString, string>.Replace.New(2, \"Again\", \"My\"));\n            Assert.True(patch.Edits.Tail.Tail.Head == Edit<EqString, string>.Replace.New(4, \"Cheers\", \"Of Joy\"));\n        }\n\n        [Fact]\n        public void ApplyInsertAtEndDiff()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Hello\", \"World\", \"Again\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyInsertAtBeginningDiff()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Again\", \"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyInsertAtMidDiff()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"Hello\", \"Again\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyInsertMultiDiff()\n        {\n            var docA = List(\"Hello\", \"World\");\n            var docB = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n\n        [Fact]\n        public void ApplyDeleteAtEndDiff()\n        {\n            var docA = List(\"Hello\", \"World\", \"Again\");\n            var docB = List(\"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyDeleteAtBeginningDiff()\n        {\n            var docA = List(\"Again\", \"Hello\", \"World\");\n            var docB = List(\"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyDeleteAtMidDiff()\n        {\n            var docA = List(\"Hello\", \"Again\", \"World\");\n            var docB = List(\"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyDeleteMultiDiff()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n\n        [Fact]\n        public void ApplyReplaceAtEndDiff()\n        {\n            var docA = List(\"Hello\", \"World\", \"Again\");\n            var docB = List(\"Hello\", \"World\", \"Once More\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyReplaceAtBeginningDiff()\n        {\n            var docA = List(\"Again\", \"Hello\", \"World\");\n            var docB = List(\"Once More\", \"Hello\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyReplaceAtMidDiff()\n        {\n            var docA = List(\"Hello\", \"Again\", \"World\");\n            var docB = List(\"Hello\", \"Once More\", \"World\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void ApplyReplaceMultiDiff()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var docC = apply(patch, docA);\n\n            Assert.True(docB == docC);\n        }\n\n        [Fact]\n        public void PatchAppendInversePatchIsEmpty()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n\n            var patch    = diff<EqString, string>(docA, docB);\n            var inverseP = inverse(patch);\n            var patch1   = patch.Combine(inverseP);\n            var empty    = Patch<EqString, string>.Empty;\n\n            Assert.True(patch1 == empty);\n        }\n\n        [Fact]\n        public void InversePatchAppendPatchIsEmpty()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n\n            var patch = diff<EqString, string>(docA, docB);\n            var inverseP = inverse(patch);\n\n            var patch1 = inverseP.Combine(patch);\n            var empty  = Patch<EqString, string>.Empty;\n\n            Assert.True(patch1 == empty);\n        }\n\n        [Fact]\n        public void InverseInversePatchIsPatch()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n\n            var patch = diff<EqString, string>(docA, docB);\n            var inverseP = inverse(patch);\n            var inverseInverse = inverse(inverseP);\n\n            Assert.True(patch == inverseInverse);\n        }\n\n        [Fact]\n        public void PatchAppend()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n            var docC = List(\"Yes\", \"My\", \"Of Joy\");\n\n            var patchP = diff<EqString, string>(docA, docB);\n            var patchQ = diff<EqString, string>(docB, docC);\n\n            var patchPQ = patchP.Combine(patchQ);\n\n            var docD = apply(patchPQ, docA);\n\n            //var docD1 = apply(patchP, docA);\n            //var docD2 = apply(patchQ, docD1);\n\n            Assert.True(docC == docD);\n\n            var edits = patchPQ.Edits.ToArr();\n\n            Assert.True(edits[0] == Edit<EqString, string>.Replace.New(0, \"It's\", \"Yes\"));\n            Assert.True(edits[1] == Edit<EqString, string>.Delete.New(1, \"Hello\"));\n            Assert.True(edits[2] == Edit<EqString, string>.Replace.New(2, \"Again\", \"My\"));\n            Assert.True(edits[3] == Edit<EqString, string>.Delete.New(3, \"World\"));\n            Assert.True(edits[4] == Edit<EqString, string>.Replace.New(4, \"Cheers\", \"Of Joy\"));\n        }\n\n        [Fact]\n        public void InverseOfPatchPAppendPatchQIsInversePatchQAppendInversePatchP()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n            var docC = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\", \"And More\");\n\n            var patchP = diff<EqString, string>(docA, docB);\n            var patchQ = diff<EqString, string>(docB, docC);\n\n            var invPatchP = inverse(patchP);\n            var invPatchQ = inverse(patchQ);\n\n            Assert.True(inverse(invPatchP) == patchP);\n            Assert.True(inverse(invPatchQ) == patchQ);\n\n            var patchPQ    = patchP.Combine(patchQ);\n            var invPatchPQ = inverse(patchPQ);\n\n            Assert.True(inverse(invPatchPQ) == patchPQ);\n\n            var invPatchQinvPatchP = invPatchQ.Combine(invPatchP);\n\n            Assert.True(inverse(invPatchPQ) == inverse(invPatchQinvPatchP));\n\n            Assert.True(invPatchPQ == invPatchQinvPatchP);\n        }\n\n        [Fact]\n        public void InverseEmptyIsEmpty()\n        {\n            var empty = Patch<EqString, string>.Empty;\n            Assert.True(empty == inverse(empty));\n        }\n\n        [Fact]\n        public void ComposableWithInverse()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var isComposable = composable(patch, inverse(patch));\n\n            Assert.True(isComposable);\n        }\n\n        [Fact]\n        public void InverseComposableWith()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var isComposable = composable(inverse(patch), patch);\n\n            Assert.True(isComposable);\n        }\n\n        [Fact]\n        public void InverseApplicableToAnyAppliedPatchOfP()\n        {\n            var docA = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var docB = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n            var docC = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\", \"And More\");\n\n            var patch = diff<EqString, string>(docA, docB);\n\n            var invPatch = inverse(patch);\n\n            var isApplicable = applicable(invPatch, apply(patch, docC));\n\n            Assert.True(isApplicable);\n        }\n\n        [Fact]\n        public void ApplyDiffResultsInTargetDocument()\n        {\n            var d = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var e = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n\n            Assert.True(apply(diff<EqString, string>(d, e), d) == e);\n        }\n\n        [Fact]\n        public void DiffTheSameDocumentProducesEmptyPatch()\n        {\n            var d = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n\n            Assert.True(diff<EqString, string>(d, d) == empty<EqString, string>());\n        }\n\n        [Fact]\n        public void DiffsBetweenThreePatchesAreEqualToDiffsBetweenFirstAndLastPatch()\n        {\n            var a = List(\"It's\", \"Hello\", \"Again\", \"World\", \"Cheers\");\n            var b = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\");\n            var c = List(\"Yes\", \"Hello\", \"My\", \"World\", \"Of Joy\", \"And More\");\n\n            Assert.True(\n                apply(append(diff<EqString, string>(a, b), diff<EqString, string>(b, c)), a) == apply(diff<EqString, string>(a, c), a)\n                );\n        }\n\n        [Fact]\n        public void DiffWithConflictTakeOurs()\n        {\n            var a = List(\"Hello\", \"World\");\n            var b = List(\"World\", \"Hello\");\n            var c = List(\"Worldy\", \"Hello\");\n\n            var ab = diff<EqString, string>(a, b);\n            var ac = diff<EqString, string>(a, c);\n\n            var (pa, pb) = transformWith(ours, ab, ac);\n\n            var newa = apply(pa, apply(ab, a));\n            var newb = apply(pb, apply(ac, a));\n\n            Assert.True(newa == newb);\n            Assert.True(newa == b);\n            Assert.True(newb == b);\n        }\n\n        [Fact]\n        public void DiffWithConflictTakeTheirs()\n        {\n            var a = List(\"Hello\", \"World\");\n            var b = List(\"World\", \"Hello\");\n            var c = List(\"Worldy\", \"Hello\");\n\n            var ab = diff<EqString, string>(a, b);\n            var ac = diff<EqString, string>(a, c);\n\n            var (pa, pb) = transformWith(theirs, ab, ac);\n\n            var newa = apply(pa, apply(ab, a));\n            var newb = apply(pb, apply(ac, a));\n\n            Assert.True(newa == newb);\n            Assert.True(newa == c);\n            Assert.True(newb == c);\n        }\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/PipesTests.cs",
    "content": "﻿using LanguageExt.Sys.Test;\nusing Xunit;\nusing static LanguageExt.Pipes.Producer;\nusing static LanguageExt.Pipes.Consumer;\n\nnamespace LanguageExt.Tests;\n\npublic class PipesTests\n{\n    [Fact]\n    public void MergeSynchronousProducersSucceeds()\n    {\n        using var rt = Runtime.New();\n        \n        (merge(yield<Runtime, int>(1), yield<Runtime, int>(1))\n           | awaiting<Runtime, int>().Map(ignore))\n               .Run().As()\n               .Run(rt, EnvIO.New())\n               .Ignore();\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/PrismTests.cs",
    "content": "﻿/*\n TODO: Restore when SourceGen available\n \nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class PrismTests\n{\n    private static readonly Prism<Job, int> jobWorkerCarMileage = prism(Job.worker.ToPrism(), Worker.car.ToPrism(), Car.mileage.ToPrism());\n\n    [Fact]\n    public void PrismShouldGetSome()\n    {\n        var expected = Some(20000);\n            \n        var car    = new Car(\"Maserati\", \"Ghibli\", 20000);\n        var worker = new Worker(\"Joe Bloggs\", 50000, car);\n        var job    = new Job(\"Programmer\", \"Write code and tests.\", worker);\n\n        var actual = jobWorkerCarMileage.Get(job);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void PrismShouldGetNone()\n    {\n        var expected = Option<int>.None;\n            \n        var worker = new Worker(\"Joe Bloggs\", 50000, Option<Car>.None);\n        var job    = new Job(\"Programmer\", \"Write code and tests.\", worker);\n\n        var actual = jobWorkerCarMileage.Get(job);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void PrismShouldSetWhenOptionalPartOfChainIsSome()\n    {\n        var expectedCar    = new Car(\"Maserati\", \"Ghibli\", 25000);\n        var expectedWorker = new Worker(\"Joe Bloggs\", 50000, expectedCar);\n        var expected       = new Job(\"Programmer\", \"Write code and tests.\", expectedWorker);\n            \n        var car    = new Car(\"Maserati\", \"Ghibli\", 20000);\n        var worker = new Worker(\"Joe Bloggs\", 50000, car);\n        var job    = new Job(\"Programmer\", \"Write code and tests.\", worker);\n            \n        var actual = jobWorkerCarMileage.Set(25000, job);\n\n        Assert.Equal(expected, actual);\n    }\n\n    [Fact]\n    public void PrismShouldNotSetWhenOptionalPartOfChainIsNone()\n    {\n        var expectedWorker = new Worker(\"Joe Bloggs\", 50000, Option<Car>.None);\n        var expected       = new Job(\"Programmer\", \"Write code and tests.\", expectedWorker);\n\n        var worker = new Worker(\"Joe Bloggs\", 50000, Option<Car>.None);\n        var job    = new Job(\"Programmer\", \"Write code and tests.\", worker);\n\n        var actual = jobWorkerCarMileage.Set(25000, job);\n\n        Assert.Equal(expected, actual);\n    }\n\n}\n    \n[Record]\npublic partial class Worker\n{\n    public readonly string Name;\n    public readonly int Salary;\n    public readonly Option<Car> Car;\n}\n\n[Record]\npublic partial class Job\n{\n    public readonly string Name;\n    public readonly string Description;\n    public readonly Worker Worker;\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Tests/QueryTests.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Query;\n\nnamespace LanguageExt.Tests\n{\n    \n    public class QueryTests\n    {\n        [Fact]\n        public void MapTest()\n        {\n            // Generates 10,20,30,40,50\n            var input = toQuery(new[] { 1, 2, 3, 4, 5 });\n\n            var output1 = map(input, x => x * 10);\n\n            // Generates 30,40,50\n            var output2 = filter(output1, x => x > 20);\n\n            // Generates 120\n            var output3 = fold(output2, 0, (x, s) => s + x);\n\n            Assert.True(output3 == 120);\n        }\n\n        [Fact]\n        public void ReduceTest1()\n        {\n            // Generates 10,20,30,40,50\n            var input = toQuery(new[] { 1, 2, 3, 4, 5 });\n            var output1 = map(input, (i,x) => x * 10);\n\n            // Generates 30,40,50\n            var output2 = filter(output1, x => x > 20);\n\n            // Generates 120\n            var output3 = reduce(output2, (x, s) => s + x);\n\n            Assert.True(output3 == 120);\n        }\n\n        [Fact]\n        public void ReduceTest2()\n        {\n            // Generates 10,20,30,40,50\n            var input = toQuery(new[] { 1, 2, 3, 4, 5 });\n            var output1 = map(input, (i, x) => (i + 1) * 10);\n\n            // Generates 30,40,50\n            var output2 = filter(output1, x => x > 20);\n\n            // Generates 120\n            var output3 = reduce(output2, (x, s) => s + x);\n\n            Assert.True(output3 == 120);\n        }\n\n        [Fact]\n        public void MapTestFluent()\n        {\n            var res = toQuery(new[] { 1, 2, 3, 4, 5 })\n                        .Map(x => x * 10)\n                        .Filter(x => x > 20)\n                        .Fold(0, (x, s) => s + x);\n\n            Assert.True(res == 120);\n        }\n\n        [Fact]\n        public void ReduceTestFluent()\n        {\n            var res = toQuery(new[] { 1, 2, 3, 4, 5 })\n                        .Map(x => x * 10)\n                        .Filter(x => x > 20)\n                        .Reduce((x, s) => s + x);\n\n            Assert.True(res == 120);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/QueueTests.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing static LanguageExt.List;\nusing static LanguageExt.Queue;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    \n    public class QueueTests\n    {\n        [Fact]\n        public void EmptyQueuePeek()\n        {\n            var test = Queue<int>();\n            var res = peek(test);\n\n            Assert.True(res.IsNone);\n        }\n\n        [Fact]\n        public void EmptyQueueDeq()\n        {\n            var test = Queue<int>();\n            var res = map(deq(test), (stack, value) => value);\n\n            Assert.True(res.IsNone);\n        }\n\n        [Fact]\n        public void Dequeuing()\n        {\n            var test = Queue(1, 2, 3, 4, 5);\n            Deq5(test);\n        }\n\n        [Fact]\n        public void EnqDeq5()\n        {\n            var test = Queue<int>();\n\n            test = enq(test, 1);\n            test = enq(test, 2);\n            test = enq(test, 3);\n            test = enq(test, 4);\n            test = enq(test, 5);\n\n            Deq5(test);\n        }\n\n        void Deq5(Que<int> test)\n        {\n            test = map(deq(test), (queue, value) => { Assert.True(value.IsSome); return queue; });\n            test = map(deq(test), (queue, value) => { Assert.True(value.IsSome); return queue; });\n            test = map(deq(test), (queue, value) => { Assert.True(value.IsSome); return queue; });\n            test = map(deq(test), (queue, value) => { Assert.True(value.IsSome); return queue; });\n\n            match(peek(test),\n                Some: v => Assert.True(v == 5, \"Actually equals \"+v),\n                None: () => Assert.False(true)\n            );\n        }\n\n        [Fact]\n        public void CollectionFunctions()\n        {\n            var queue = toQueue(Range(0,100));\n\n            Assert.True(exists(queue, v => v == 50));\n            Assert.True(length(queue) == 100);\n            Assert.True(length(takeWhile(queue, v => v != 90)) == 90);\n            Assert.True(length(take(queue, 10)) == 10);\n            Assert.True(head(take(queue, 1)) == 0);\n        }\n\n        [Fact]\n        public void RecursiveSumTest()\n        {\n            var values = toQueue(Range(1, 10));\n\n            var res = Sum(values);\n\n            Assert.True(res == sum(values));\n        }\n\n        public int Sum(Que<int> queue) =>\n            map( deq(queue), (newqueue, option) =>\n                match(option,\n                    Some: value => value + Sum(newqueue),\n                    None: ()    => 0\n                )\n            );\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/RangeTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class RangeTests\n{\n    [Fact]\n    public void IntRangeAsc()\n    {\n        var x = Range.fromMinMax(2, 5).ToLst();\n        Assert.True(x == List(2, 3, 4, 5));\n    }\n\n    [Fact]\n    public void IntRangeDesc()\n    {\n        var x = Range.fromMinMax(5, 2).ToLst();\n        Assert.True(x == List(5, 4, 3, 2));\n    }\n\n    [Fact]\n    public void IntCountAsc()\n    {\n        var x = Range.fromCount(2, 5, 2).ToLst();\n        Assert.True(x == List(2, 4, 6, 8, 10));\n    }\n\n    [Fact]\n    public void IntCountDesc()\n    {\n        var x = Range.fromCount(2, 5, -2).ToLst();\n        Assert.True(x == List(2, 0, -2, -4, -6));\n    }\n\n    [Fact]\n    public void CharCountAsc()\n    {\n        var x = Range.fromCount('a', (char)5).ToLst();\n        Assert.True(x == List('a', 'b', 'c', 'd', 'e'));\n    }\n\n    [Fact]\n    public void CharCountDesc()\n    {\n        var x = Range('e', 'a').ToLst();\n        Assert.True(x == List('e', 'd', 'c', 'b', 'a'));\n    }\n\n\n    [Fact]\n    public void CharRangeAsc()\n    {\n        var x = Range.fromMinMax('a', 'e').ToLst();\n        Assert.True(x == List('a', 'b', 'c', 'd', 'e'));\n    }\n\n    [Fact]\n    public void CharRangeDesc()\n    {\n        var x = Range.fromMinMax('e', 'a').ToLst();\n        Assert.True(x == List('e', 'd', 'c', 'b', 'a'));\n    }\n\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Read-Me.cs",
    "content": "﻿using LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests;\n\npublic class ReadMe\n{\n    public void ReadMeCode()\n    {\n        var abc   = ('a', 'b').Add('c');                 // ('a', 'b', 'c')\n        var abcd  = ('a', 'b').Add('c').Add('d');        // ('a', 'b', 'c', 'd')\n        var abcd5 = ('a', 'b').Add('c').Add('d').Add(5); // ('a', 'b', 'c', 'd', 5)\n\n        var sumA = (1, 2, 3).Sum<TInt, int>();                                   // 6\n        var sumB = (2, 4, 8).Product<TInt, int>();                               // 64\n        var flag = (\"one\", \"two\", \"three\").Contains<TString, string>(\"one\");     // true\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/RecordIgnoreBaseTests.cs",
    "content": "﻿using System;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    public class RecordIgnoreBaseTests\n    {\n        public class BaseClass\n        {\n            public readonly int X;\n\n            public BaseClass(int x) =>\n                X = x;\n        }\n\n        public class SubClass1 : BaseClass, IEquatable<SubClass1>, IComparable<SubClass1>\n        {\n            public readonly int Y;\n\n            public SubClass1(int x, int y) : base(x) =>\n                Y = y;\n\n            public int CompareTo(SubClass1? other) =>\n                RecordTypeIgnoreBase<SubClass1>.Compare(this, other);\n\n            public override bool Equals(object? obj) =>\n                RecordTypeIgnoreBase<SubClass1>.Equality(this, obj);\n\n            public bool Equals(SubClass1? other) =>\n                RecordTypeIgnoreBase<SubClass1>.EqualityTyped(this, other);\n\n            public override int GetHashCode() =>\n                RecordTypeIgnoreBase<SubClass1>.Hash(this);\n        }\n\n        [IgnoreBase]\n        public class SubClass2 : BaseClass, IEquatable<SubClass2>, IComparable<SubClass2>\n        {\n            public readonly int Y;\n\n            public SubClass2(int x, int y) : base(x) =>\n                Y = y;\n\n            public int CompareTo(SubClass2 other) =>\n                RecordType<SubClass2>.Compare(this, other);\n\n            public override bool Equals(object obj) =>\n                RecordType<SubClass2>.Equality(this, obj);\n\n            public bool Equals(SubClass2 other) =>\n                RecordType<SubClass2>.EqualityTyped(this, other);\n\n            public override int GetHashCode() =>\n                RecordType<SubClass2>.Hash(this);\n        }\n\n        public class SubClass3 : BaseClass, IEquatable<SubClass3>, IComparable<SubClass3>\n        {\n            public readonly int Y;\n\n            public SubClass3(int x, int y) : base(x) =>\n                Y = y;\n\n            public int CompareTo(SubClass3 other) =>\n                RecordType<SubClass3>.Compare(this, other);\n\n            public override bool Equals(object obj) =>\n                RecordType<SubClass3>.Equality(this, obj);\n\n            public bool Equals(SubClass3 other) =>\n                RecordType<SubClass3>.EqualityTyped(this, other);\n\n            public override int GetHashCode() =>\n                RecordType<SubClass3>.Hash(this);\n        }\n\n        public class FirstAttributeAttribute : Attribute { }\n\n        [FirstAttribute]\n        [IgnoreBase]\n        public class SubClass4 : BaseClass, IEquatable<SubClass4>, IComparable<SubClass4>\n        {\n            public readonly int Y;\n\n            public SubClass4(int x, int y) : base(x) =>\n                Y = y;\n\n            public int CompareTo(SubClass4 other) =>\n                RecordType<SubClass4>.Compare(this, other);\n\n            public override bool Equals(object obj) =>\n                RecordType<SubClass4>.Equality(this, obj);\n\n            public bool Equals(SubClass4 other) =>\n                RecordType<SubClass4>.EqualityTyped(this, other);\n\n            public override int GetHashCode() =>\n                RecordType<SubClass4>.Hash(this);\n        }\n\n        [Fact]\n        public void TestSubClass1Eq()\n        {\n            var a = new SubClass1(0, 1);\n            var b = new SubClass1(1, 1);\n\n            Assert.True(a.Equals(b));\n            Assert.True(a.GetHashCode() == b.GetHashCode());\n            Assert.True(a.CompareTo(b) == 0);\n        }\n\n        [Fact]\n        public void TestSubClass2Eq()\n        {\n            var a = new SubClass2(0, 1);\n            var b = new SubClass2(1, 1);\n\n            Assert.True(a.Equals(b));\n            Assert.True(a.GetHashCode() == b.GetHashCode());\n            Assert.True(a.CompareTo(b) == 0);\n        }\n\n        [Fact]\n        public void TestSubClass3NotEq()\n        {\n            var a = new SubClass3(0, 1);\n            var b = new SubClass3(1, 1);\n\n            Assert.False(a.Equals(b));\n            Assert.False(a.GetHashCode() == b.GetHashCode());\n            Assert.False(a.CompareTo(b) == 0);\n        }\n\n        [Fact]\n        public void TestSubClass4Eq()\n        {\n            var a = new SubClass4(0, 1);\n            var b = new SubClass4(1, 1);\n\n            Assert.True(a.Equals(b));\n            Assert.True(a.GetHashCode() == b.GetHashCode());\n            Assert.True(a.CompareTo(b) == 0);\n        }\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/RecordTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    public class RecordTests\n    {\n        /// <summary>\n        /// Cons type - singly linked list\n        /// </summary>\n        public class Cons<A> : Record<Cons<A>>\n        {\n            public readonly A Head;\n            public readonly Cons<A> Tail;\n\n            public Cons(A head, Cons<A> tail)\n            {\n                Head = head;\n                Tail = tail;\n            }\n        }\n\n        [Fact]\n        public void ConsTests()\n        {\n            var listA = new Cons<int>(1, new Cons<int>(2, new Cons<int>(3, new Cons<int>(4, null))));\n            var listB = new Cons<int>(1, new Cons<int>(2, new Cons<int>(3, new Cons<int>(4, null))));\n            var listC = new Cons<int>(1, new Cons<int>(2, new Cons<int>(3, null)));\n\n            Assert.True(listA == listB);\n            Assert.True(listB != listC);\n            Assert.True(listA != listC);\n        }\n\n        /// <summary>\n        /// Binary tree\n        /// </summary>\n        public class Tree<A> : Record<Tree<A>>\n        {\n            public readonly A Value;\n            public readonly Tree<A> Left;\n            public readonly Tree<A> Right;\n\n            public Tree(A value, Tree<A> left, Tree<A> right)\n            {\n                Value = value;\n                Left = left;\n                Right = right;\n            }\n        }\n\n        [Fact]\n        public void TreeTests()\n        {\n            var treeA = new Tree<int>(5, new Tree<int>(3, null, null), new Tree<int>(7, null, new Tree<int>(9, null, null)));\n            var treeB = new Tree<int>(5, new Tree<int>(3, null, null), new Tree<int>(7, null, new Tree<int>(9, null, null)));\n            var treeC = new Tree<int>(5, new Tree<int>(3, null, null), new Tree<int>(7, null, null));\n\n            Assert.True(treeA == treeB);\n            Assert.True(treeB != treeC);\n            Assert.True(treeA != treeC);\n\n            var str = treeA.ToString();\n        }\n\n\n        class Disorder : Record<Disorder>\n        {\n            public string Present = \"Here\";\n            public string Absent = null;\n        }\n\n        [Fact]\n        public void NullMemberEqualityTest()\n        {\n            var a = new Disorder();\n            var b = new Disorder();\n\n            Assert.True(a == b);\n            Assert.True(a.GetHashCode() == b.GetHashCode());\n            Assert.False(a != b);\n            Assert.False(a.GetHashCode() != b.GetHashCode());\n        }\n\n        [Fact]\n        public void NullMemberOrderingTest()\n        {\n            var a = new Disorder();\n            var b = new Disorder();\n\n            Assert.True(a.CompareTo(b) == 0);\n            Assert.True(b.CompareTo(a) == 0);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/RecordTypesTest.cs",
    "content": "﻿using LanguageExt.ClassInstances;\nusing LanguageExt.Traits;\nusing Newtonsoft.Json;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Runtime.Serialization;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    public class TestClass : Record<TestClass>\n    {\n        public readonly int X;\n        public readonly string Y;\n        public readonly Guid Z;\n\n        public TestClass(int x, string y, Guid z)\n        {\n            X = x;\n            Y = y;\n            Z = z;\n        }\n\n        TestClass(SerializationInfo info, StreamingContext context) \n            : base(info, context) { }\n    }\n\n    public class TestRecord : Record<TestRecord>\n    {\n        public readonly Option<int> Opt1;\n        public readonly Option<int> Opt2;\n\n        public TestRecord(Option<int> opt1, Option<int> opt2)\n        {\n            Opt1 = opt1;\n            Opt2 = opt2;\n        }\n    }\n\n    public class DerivedTestClass : TestClass\n    {\n        public readonly int Extra;\n\n        public DerivedTestClass(int x, string y, Guid z, int extra) : base(x, y, z)\n        {\n            Extra = extra;\n        }\n    }\n\n    public class TestClass2 : Record<TestClass2>\n    {\n        [NonEq]\n        public readonly int X;\n\n        [NonHash]\n        public readonly string Y;\n\n        [NonShow]\n        public readonly Guid Z;\n\n        public TestClass2(int x, string y, Guid z)\n        {\n            X = x;\n            Y = y;\n            Z = z;\n        }\n    }\n\n    public class TestClass3 : Record<TestClass3>\n    {\n        public readonly int X;\n        public readonly string Y;\n        public readonly Guid Z;\n        public TestClass W { get; }\n\n        public TestClass3(int x, string y, Guid z, TestClass w)\n        {\n            X = x;\n            Y = y;\n            Z = z;\n            W = w;\n        }\n\n        TestClass3(SerializationInfo info, StreamingContext context)\n            : base(info, context) { }\n    }\n\n    public class RecordTypeTests\n    {\n        static readonly Guid guid = Guid.Parse(\"{2ba1ec03-8309-46f6-a93e-5d6aada3a43c}\");\n\n        [Fact]\n        public void EqualityOfOriginTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new DerivedTestClass(1, \"Hello\", Guid.Empty, 1000);\n\n            Assert.False(x.Equals(y));  // Different types must not be equal\n            Assert.False(y.Equals(x));  // Different types must not be equal\n        }\n\n        [Fact]\n        public void DeepEqualityTestFieldsAndProperties()\n        {\n            var x1 = new TestClass(1, \"Hello\", Guid.Empty);\n            var x2 = new TestClass(1, \"Hello\", Guid.Empty);\n            var y1 = new TestClass3(1, \"Hello\", Guid.Empty, x1);\n            var y2 = new TestClass3(1, \"Hello\", Guid.Empty, x2);\n\n            Assert.True(y1 == y2);\n        }\n\n        [Fact]\n        public void DeepInEqualityTestFieldsAndProperties()\n        {\n            var x1 = new TestClass(1, \"Hello\", Guid.Empty);\n            var x2 = new TestClass(1, \"Hello\", guid);\n            var y1 = new TestClass3(1, \"Hello\", Guid.Empty, x1);\n            var y2 = new TestClass3(1, \"Hello\", Guid.Empty, x2);\n\n            Assert.True(y1 != y2);\n        }\n\n        [Fact]\n        public void SerialisationTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(1, \"Hello\", guid);\n\n            var x1 = JsonConvert.SerializeObject(x);\n            var y1 = JsonConvert.SerializeObject(y);\n\n            var x2 = JsonConvert.DeserializeObject<TestClass>(x1);\n            var y2 = JsonConvert.DeserializeObject<TestClass>(y1);\n\n            Assert.True(x == x2);\n            Assert.True(y == y2);\n        }\n\n        [Fact]\n        public void ToStringTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(1, \"Hello\", guid);\n\n            Assert.True(x.ToString() == \"TestClass(1, Hello, 00000000-0000-0000-0000-000000000000)\");\n            Assert.True(y.ToString() == \"TestClass(1, Hello, 2ba1ec03-8309-46f6-a93e-5d6aada3a43c)\");\n        }\n\n        [Fact]\n        public void EqualityOperatorTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(1, \"Hello\", Guid.Empty);\n\n            Assert.True(x == y);\n        }\n\n        [Fact]\n        public void EqualityMethodTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(1, \"Hello\", Guid.Empty);\n\n            Assert.True(x.Equals(y));\n        }\n\n        [Fact]\n        public void NullEqualityOperatorTest()\n        {\n            TestClass x = new TestClass(1, \"Hello\", Guid.Empty);\n            TestClass y = null;\n            TestClass z = null;\n\n            Assert.True(x != y);\n            Assert.True(y != x);\n            Assert.True(y == z);\n            Assert.True(z == y);\n        }\n\n        [Fact]\n        public void NullEqualityMethodTest()\n        {\n            TestClass x = new TestClass(1, \"Hello\", Guid.Empty);\n            TestClass y = null;\n\n            Assert.False(x.Equals(y));\n        }\n\n        [Fact]\n        public void InEqualityOperatorTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(2, \"Hello\", Guid.Empty);\n            var z = new TestClass(1, \"Hello!\", Guid.Empty);\n            var w = new TestClass(1, \"Hello\", guid);\n\n            Assert.True(x != y);\n            Assert.True(x != z);\n            Assert.True(x != w);\n        }\n\n        [Fact]\n        public void InEqualityMethodTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(2, \"Hello\", Guid.Empty);\n            var z = new TestClass(1, \"Hello!\", Guid.Empty);\n            var w = new TestClass(1, \"Hello\", guid);\n\n            Assert.False(x.Equals(y));\n            Assert.False(x.Equals(z));\n            Assert.False(x.Equals(w));\n        }\n\n        [Fact]\n        public void HashingTest()\n        {\n            var a = new TestClass(1, \"Hello\", Guid.Empty);\n            var b = new TestClass(1, \"Hello\", Guid.Empty);\n            var c = new TestClass(2, \"Hello\", Guid.Empty);\n            var d = new TestClass(1, \"Hello!\", Guid.Empty);\n            var e = new TestClass(1, \"Hello\", guid);\n\n            Assert.True(a.GetHashCode() == b.GetHashCode());\n            Assert.True(a.GetHashCode() != c.GetHashCode());\n            Assert.True(a.GetHashCode() != d.GetHashCode());\n            Assert.True(a.GetHashCode() != e.GetHashCode());\n        }\n\n\n        [Fact]\n        public void OrderingTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(1, \"Hello\", Guid.Empty);\n\n            Assert.True(x.CompareTo(y) == 0);\n        }\n\n        [Fact]\n        public void NullOrderingOperatorTest()\n        {\n            TestClass x = new TestClass(1, \"Hello\", Guid.Empty);\n            TestClass y = null;\n            TestClass z = null;\n\n            Assert.True(x > y);\n            Assert.True(x >= y);\n            Assert.True(y < x);\n            Assert.True(y <= x);\n            Assert.True(y == z);\n            Assert.True(z == y);\n        }\n\n        [Fact]\n        public void NullOrderingMethodTest()\n        {\n            TestClass x = new TestClass(1, \"Hello\", Guid.Empty);\n            TestClass y = null;\n\n            Assert.True(x.CompareTo(y) > 0);\n        }\n\n        [Fact]\n        public void OrderingOperatorTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(2, \"Hello\", Guid.Empty);\n            var z = new TestClass(1, \"Jello\", Guid.Empty);\n\n            Assert.True(x < y);\n            Assert.True(x <= y);\n            Assert.True(y > x);\n            Assert.True(y >= x);\n\n            Assert.True(x < z);\n            Assert.True(x <= z);\n            Assert.True(z > x);\n            Assert.True(z >= x);\n        }\n\n        [Fact]\n        public void OrderingMethodTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(2, \"Hello\", Guid.Empty);\n            var z = new TestClass(1, \"Jello\", Guid.Empty);\n\n            Assert.True(GenericCompare<OrdRecord<TestClass>, TestClass>(x, y) < 0);\n            Assert.True(GenericCompare<OrdRecord<TestClass>, TestClass>(x, y) <= 0);\n            Assert.True(GenericCompare<OrdRecord<TestClass>, TestClass>(y, x) > 0);\n            Assert.True(GenericCompare<OrdRecord<TestClass>, TestClass>(y, x) >= 0);\n\n            Assert.True(GenericCompare<OrdRecord<TestClass>, TestClass>(x, z) < 0);\n            Assert.True(GenericCompare<OrdRecord<TestClass>, TestClass>(x, z) <= 0);\n            Assert.True(GenericCompare<OrdRecord<TestClass>, TestClass>(z, x) > 0);\n            Assert.True(GenericCompare<OrdRecord<TestClass>, TestClass>(z, x) >= 0);\n        }\n\n        [Fact]\n        public void EqClassInstanceTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(1, \"Hello\", Guid.Empty);\n            var z = new TestClass(2, \"Hello\", Guid.Empty);\n\n            var resA = GenericEquals<EqRecord<TestClass>,TestClass>(x, y);\n            var resB = GenericEquals<EqRecord<TestClass>,TestClass>(x, z);\n\n            Assert.True(resA);\n            Assert.False(resB);\n        }\n\n\n        [Fact]\n        public void OrdClassInstanceTest()\n        {\n            var x = new TestClass(1, \"Hello\", Guid.Empty);\n            var y = new TestClass(2, \"Hello\", Guid.Empty);\n            var z = new TestClass(1, \"Jello\", Guid.Empty);\n\n            Assert.True(x.CompareTo(y) < 0);\n            Assert.True(x.CompareTo(y) <= 0);\n            Assert.True(y.CompareTo(x) > 0);\n            Assert.True(y.CompareTo(x) >= 0);\n\n            Assert.True(x.CompareTo(z) < 0);\n            Assert.True(x.CompareTo(z) <= 0);\n            Assert.True(z.CompareTo(x) > 0);\n            Assert.True(z.CompareTo(x) >= 0);\n        }\n\n        public bool GenericEquals<EqA, A>(A x, A y) where EqA : Eq<A> =>\n            EqA.Equals(x, y);\n\n        public int GenericCompare<OrdA, A>(A x, A y) where OrdA : Ord<A> =>\n            OrdA.Compare(x, y);\n\n        [Fact]\n        public void OptOutOfEqTest()\n        {\n            var x = new TestClass2(1, \"Hello\", Guid.Empty);\n            var y = new TestClass2(1, \"Hello\", Guid.Empty);\n            var z = new TestClass2(2, \"Hello\", Guid.Empty);\n\n            Assert.True(x == y);\n            Assert.True(x == z);\n        }\n\n        [Fact]\n        public void OptOutOfHashCodeTest()\n        {\n            var x = new TestClass2(1, \"Hello\", Guid.Empty);\n            var y = new TestClass2(1, \"Hello32543534\", Guid.Empty);\n            var z = new TestClass2(1, \"Hello\", Guid.Empty);\n\n            Assert.True(x.GetHashCode() == y.GetHashCode());\n            Assert.True(x.GetHashCode() == z.GetHashCode());\n        }\n\n        [Fact]\n        public void OptOutOfToString()\n        {\n            var x = new TestClass2(1, \"Hello\", Guid.Empty);\n            var y = new TestClass2(1, \"Hello\", Guid.NewGuid());\n\n            Assert.True(x.ToString() == y.ToString());\n        }\n\n        [Fact]\n        // https://github.com/louthy/language-ext/issues/560\n        public void EnsureHashingIsNotOnlyXoring()\n        {\n            var testRecord1 = new TestRecord(Option<int>.None, 2);\n            var testRecord2 = new TestRecord(2, Option<int>.None);\n\n            Assert.False(testRecord1.GetHashCode() == testRecord2.GetHashCode());\n\n            testRecord1 = new TestRecord(Option<int>.None, Option<int>.None);\n            testRecord2 = new TestRecord(1, 1);\n\n            Assert.False(testRecord1.GetHashCode() == testRecord2.GetHashCode());\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/RefTest.cs",
    "content": "﻿using System.Linq;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class Account\n{\n    public readonly int Balance;\n\n    Account(int balance) =>\n        Balance = balance;\n\n    public Account SetBalance(int value) =>\n        new Account(value);\n\n    public Account AddBalance(int value) =>\n        new Account(Balance + value);\n\n    public Account Deposit(int value) =>\n        new Account(Balance + value);\n\n    public static Ref<Account> New(int balance) =>\n        Ref(new Account(balance), Account.Validate);\n\n    public static bool Validate(Account a) =>\n        a.Balance >= 0;\n\n    public override string ToString() =>\n        Balance.ToString();\n}\n\npublic static class Transfer\n{\n    public static Unit Do(Ref<Account> from, Ref<Account> to, int amount) => \n        atomic(() =>\n               {\n                   from.Value = from.Value.AddBalance(-amount);\n                   to.Value   = to.Value.AddBalance(amount);\n               });\n}\n\n\npublic class RefTest\n{\n    [Fact]\n    public void BankBalanceChangeTest()\n    {\n        var accountA = Account.New(200);\n        var accountB = Account.New(0);\n\n        var stateA   = Option<Account>.None;\n        var stateB   = Option<Account>.None;\n        var changedA = 0;\n        var changedB = 0;\n        accountA.Change += v => { stateA = v; changedA++; };\n        accountB.Change += v => { stateB = v; changedB++; };\n\n        atomic(() =>\n               {\n                   accountA.Value = accountA.Value.AddBalance(-50);\n                   accountB.Value = accountB.Value.AddBalance(50);\n                   accountA.Value = accountA.Value.AddBalance(-5);\n                   accountB.Value = accountB.Value.AddBalance(5);\n\n                   Assert.Equal(None, stateA);\n                   Assert.Equal(None, stateB);\n               });\n\n        Assert.Equal(Some(accountA.Value), stateA);\n        Assert.Equal(Some(accountB.Value), stateB);\n        Assert.Equal(1, changedA);\n        Assert.Equal(1, changedB);\n    }\n\n    [Fact]\n    public void SimpleBankBalanceTest()\n    {\n        var accountA = Account.New(200);\n        var accountB = Account.New(0);\n\n        Transfer.Do(accountA, accountB, 100);\n\n        var (balanceA, balanceB) = atomic(() => (accountA.Value.Balance, accountB.Value.Balance));\n\n        Assert.True(balanceA == balanceB);\n    }\n\n    [Fact]\n    public void CommuteTest()\n    {\n        const int count = 1000;\n\n        static int inc(Ref<int> counter) => \n            atomic(() => commute(counter, static x => x + 1));\n\n        var num = Ref(0);\n\n        var res = Range(0, count).AsParallel()\n                                 .Select(_ => inc(num))\n                                 .AsIterable() \n                                 .ToSeq()\n                                 .Strict();\n\n        Assert.True(num == count);\n    }\n\n    [Fact]\n    static void DepositCommuteTest()\n    {\n        var bank = Account.New(0);\n\n        LogDeposit(bank, 100);\n        LogDeposit(bank, 50);\n\n        Assert.True(bank.Value.Balance == 150);\n\n        var bank2 = Account.New(0);\n\n        LogDeposit(bank2, 50);\n        LogDeposit(bank2, 100);\n\n        Assert.True(bank2.Value.Balance == 150);\n\n    }\n\n    static void LogDeposit(Ref<Account> account, int amount) =>\n        atomic(() => commute(account, a => a.Deposit(amount)));\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ReflectTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    public class ReflectTests\n    {\n        public class TestClass\n        {\n            public readonly string W;\n            public readonly string X;\n            public readonly string Y;\n            public readonly string Z;\n\n            public TestClass()\n            {\n            }\n\n            public TestClass(string w)\n            {\n                W = w;\n            }\n\n            public TestClass(string w, string x)\n            {\n                W = w;\n                X = x;\n            }\n\n            public TestClass(string w, bool x)\n            {\n                W = w;\n                X = x.ToString();\n            }\n\n            public TestClass(string w, string x, string y)\n            {\n                W = w;\n                X = x;\n                Y = y;\n            }\n\n            public TestClass(string w, string x, string y, string z)\n            {\n                W = w;\n                X = x;\n                Y = y;\n                Z = z;\n            }\n        }\n\n        [Fact]\n        public void CtorOfArity1Test()\n        {\n            var ctor = IL.Ctor<string, TestClass>();\n\n            var res = ctor(\"Hello\");\n\n            Assert.True(res.W == \"Hello\");\n        }\n\n        [Fact]\n        public void CtorOfArity2Test()\n        {\n            var ctor = IL.Ctor<string, string, TestClass>();\n\n            var res = ctor(\"Hello\", \"World\");\n\n            Assert.True(res.W == \"Hello\");\n            Assert.True(res.X == \"World\");\n        }\n\n        [Fact]\n        public void CtorOfArity2Test2()\n        {\n            var ctor = IL.Ctor<string, bool, TestClass>();\n\n            var res = ctor(\"Hello\", true);\n\n            Assert.True(res.W == \"Hello\");\n            Assert.True(res.X == \"True\");\n        }\n\n        [Fact]\n        public void CtorOfArity3Test()\n        {\n            var ctor = IL.Ctor<string, string, string, TestClass>();\n\n            var res = ctor(\"Roland\",\"TR\", \"909\");\n\n            Assert.True(res.W == \"Roland\");\n            Assert.True(res.X == \"TR\");\n            Assert.True(res.Y == \"909\");\n        }\n\n        [Fact]\n        public void CtorOfArity4Test()\n        {\n            var ctor = IL.Ctor<string, string, string, string, TestClass>();\n\n            var res = ctor(\"Chandler\", \"Curve\", \"Bender\", \"EQ\");\n\n            Assert.True(res.W == \"Chandler\");\n            Assert.True(res.X == \"Curve\");\n            Assert.True(res.Y == \"Bender\");\n            Assert.True(res.Z == \"EQ\");\n        }\n\n        [Fact]\n        public void DateConstructTest()\n        {\n            var ticks = new DateTime(2017, 1, 1).Ticks;\n            var ctor = IL.Ctor<long, DateTime>();\n\n            DateTime res = ctor(ticks);\n\n            Assert.True(res.Ticks == ticks);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ScheduleTest/EffTests1.cs",
    "content": "﻿using Xunit;\nusing System.IO;\nusing System.Text;\nusing LanguageExt.Sys;\nusing LanguageExt.Common;\nusing LanguageExt.Sys.Test;\nusing LanguageExt.Sys.Traits;\nusing System.Collections.Generic;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace LanguageExt.Tests.ScheduleTest;\n\npublic static class EffTests1\n{\n    static Schedule TestSchedule() => Schedule.fixedInterval(1 * ms) | Schedule.NoDelayOnFirst | Schedule.recurs(5);\n\n    [Fact]\n    public static void BailBeforeScheduleTest1()\n    {\n        const int counter = 0;\n        var       effect  = FailEff<int>((Error)\"Failed\");\n        var       result  = effect.RepeatIO(TestSchedule()).Run();\n        Assert.Equal(0, counter);\n        result.AssertFail(Error.New(\"Failed\"));\n    }\n\n    [Fact]\n    public static void BailBeforeScheduleTest2()\n    {\n        using var rt      = Runtime.New();\n        const int counter = 0;\n        var       effect  = FailEff<Runtime, int>((Error)\"Failed\");\n        var       result  = effect.RepeatIO(TestSchedule()).Run(rt, EnvIO.New());\n        Assert.Equal(0, counter);\n        result.AssertFail(Error.New(\"Failed\"));\n    }\n\n    [Fact]\n    public static void RepeatTest1()\n    {\n        var counter = 0;\n        var effect = liftEff(async () => await (++counter).AsValueTask());\n        var result = effect.RepeatIO(TestSchedule()).Run();\n        Assert.Equal(6, counter);\n        result.AssertSucc(6);\n    }\n\n    [Fact]\n    public static void RepeatTest2()\n    {\n        using var rt      = Runtime.New();\n        var       counter = 0;\n        var       effect  = liftEff<Runtime, int>(async _ => await (++counter).AsValueTask());\n        var       result  = effect.RepeatIO(TestSchedule()).Run(rt, EnvIO.New());\n        Assert.Equal(6, counter);\n        result.AssertSucc(6);\n    }\n\n    [Fact]\n    public static void RetryTest1()\n    {\n        var counter = 0;\n        var effect = liftEff<int>(\n            async () =>\n            {\n                await (++counter).AsValueTask();\n                return Error.New(\"Failed\");\n            });\n        var result = effect.RetryIO(TestSchedule()).Run();\n        Assert.Equal(6, counter);\n        result.AssertFail(Error.New(\"Failed\"));\n    }\n\n    [Fact]\n    public static void RetryTest2()\n    {\n        using var rt      = Runtime.New();\n        var       counter = 0;\n        var effect = liftEff<Runtime, int>(\n            async _ =>\n            {\n                await (++counter).AsValueTask();\n                return Error.New(\"Failed\");\n            });\n        var result = effect.RetryIO(TestSchedule()).Run(rt, EnvIO.New());\n        Assert.Equal(6, counter);\n        result.AssertFail(Error.New(\"Failed\"));\n    }\n\n    [Fact]\n    public static void RepeatWhileTest1()\n    {\n        var counter = 0;\n        var effect  = liftEff(async () => await (++counter).AsValueTask());\n        var result  = effect.RepeatWhileIO(TestSchedule(), static i => i < 3).Run();\n        Assert.Equal(3, counter);\n        result.AssertSucc(3);\n    }\n\n    [Fact]\n    public static void RepeatWhileTest2()\n    {\n        using var rt      = Runtime.New();\n        var       counter = 0;\n        var       effect  = liftEff<Runtime, int>(async _ => await (++counter).AsValueTask());\n        var       result  = effect.RepeatWhileIO(TestSchedule(), static i => i < 3).Run(rt, EnvIO.New());\n        Assert.Equal(3, counter);\n        result.AssertSucc(3);\n    }\n\n    [Fact]\n    public static void RetryWhileTest1()\n    {\n        var counter = 0;\n        var effect = liftEff<int>(\n            async () =>\n            {\n                await (++counter).AsValueTask();\n                return Error.New(counter.ToString());\n            });\n        var result = effect.RetryWhileIO(TestSchedule(), static e => (int)parseInt(e.Message) < 3).Run();\n        Assert.Equal(3, counter);\n        result.AssertFail(Error.New(\"3\"));\n    }\n\n    [Fact]\n    public static void RetryWhileTest2()\n    {\n        using var rt      = Runtime.New();\n        var       counter = 0;\n        var effect = liftEff<Runtime, int>(\n            async _ =>\n            {\n                await (++counter).AsValueTask();\n                return Error.New(counter.ToString());\n            });\n        var result = effect.RetryWhileIO(TestSchedule(), static e => (int)parseInt(e.Message) < 3).Run(rt, EnvIO.New());\n        Assert.Equal(3, counter);\n        result.AssertFail(Error.New(\"3\"));\n    }\n\n    [Fact]\n    public static void RepeatUntilTest1()\n    {\n        var counter = 0;\n        var effect  = liftEff(async () => await (++counter).AsValueTask());\n        var result  = effect.RepeatUntilIO(static i => i == 10).Run();\n        Assert.Equal(10, counter);\n        result.AssertSucc(10);\n    }\n\n    [Fact]\n    public static void RepeatUntilTest2()\n    {\n        using var rt      = Runtime.New();\n        var       counter = 0;\n        var       effect  = liftEff<Runtime, int>(async _ => await (++counter).AsValueTask());\n        var       result  = effect.RepeatUntilIO(static i => i == 10).Run(rt, EnvIO.New());\n        Assert.Equal(10, counter);\n        result.AssertSucc(10);\n    }\n\n    [Fact]\n    public static void RetryUntilTest1()\n    {\n        var counter = 0;\n        var effect = liftEff<int>(\n            async () =>\n            {\n                await (++counter).AsValueTask();\n                return Error.New(counter.ToString());\n            });\n        var result = effect.RetryUntilIO(static e => (int)parseInt(e.Message) == 10).Run();\n        Assert.Equal(10, counter);\n        result.AssertFail(Error.New(\"10\"));\n    }\n\n    [Fact]\n    public static void RetryUntilTest2()\n    {\n        using var rt      = Runtime.New();\n        var       counter = 0;\n        var effect = liftEff<Runtime, int>(\n            async _ =>\n            {\n                await (++counter).AsValueTask();\n                return Error.New(counter.ToString());\n            });\n        var result = effect.RetryUntilIO(static e => (int)parseInt(e.Message) == 10).Run(rt, EnvIO.New());\n        Assert.Equal(10, counter);\n        result.AssertFail(Error.New(\"10\"));\n    }\n\n    [Fact]\n    public static void FoldTest1()\n    {\n        var counter = 0;\n        var effect  = liftEff(async () => await (++counter).AsValueTask());\n        var result  = effect.FoldIO(TestSchedule(), 1, (i, j) => i + j).Run();\n        Assert.Equal(6, counter);\n        result.AssertSucc(22);\n    }\n\n    [Fact]\n    public static void FoldTest2()\n    {\n        using var rt      = Runtime.New();\n        var       counter = 0;\n        var       effect  = liftEff<Runtime, int>(async _ => await (++counter).AsValueTask());\n        var       result  = effect.FoldIO(TestSchedule(), 1, (i, j) => i + j).Run(rt, EnvIO.New());\n        Assert.Equal(6, counter);\n        result.AssertSucc(22);\n    }\n\n    [Fact]\n    public static void FoldWhileTest1()\n    {\n        var counter = 0;\n        var effect  = liftEff(async () => await (++counter).AsValueTask());\n        var result  = effect.FoldWhileIO(TestSchedule(), 1, (i, j) => i + j, valueIs: i => i < 3).Run();\n        Assert.Equal(3, counter);\n        result.AssertSucc(4);\n    }\n\n    [Fact]\n    public static void FoldWhileTest2()\n    {\n        using var rt = Runtime.New();\n        var counter = 0;\n        var effect  = liftEff<Runtime, int>(async _ => await (++counter).AsValueTask());\n        var result  = effect.FoldWhileIO(TestSchedule(), 1, (i, j) => i + j, valueIs: i => i < 3).Run(rt, EnvIO.New());\n        Assert.Equal(3, counter);\n        result.AssertSucc(4);\n    }\n\n    [Fact]\n    public static void FoldUntilTest1()\n    {\n        var counter = 0;\n        var effect  = liftEff(async () => await (++counter).AsValueTask());\n        var result  = effect.FoldUntilIO(TestSchedule(), 1, (i, j) => i + j, valueIs: i => i > 4).Run();\n        Assert.Equal(5, counter);\n        result.AssertSucc(16);\n    }\n\n    [Fact]\n    public static void FoldUntilTest2()\n    {\n        using var rt      = Runtime.New();\n        var       counter = 0;\n        var       effect  = liftEff<Runtime, int>(async _ => await (++counter).AsValueTask());\n        var result = effect.FoldUntilIO(TestSchedule(), 1, (i, j) => i + j, valueIs: i => i > 4)\n                           .Run(rt, EnvIO.New());\n        \n        Assert.Equal(5, counter);\n        result.AssertSucc(16);\n    }\n\n    [Fact]\n    public static void CancelTest()\n    {\n        using var rt = Runtime.New();\n        var counter = 0;\n        var envIO   = EnvIO.New();\n        var effect  = liftEff<Runtime, int>(async _ => await (++counter).AsValueTask()).RepeatIO(Schedule.Forever);\n        envIO.Source.Cancel();\n        var result = effect.Run(rt, envIO);\n        Assert.Equal(0, counter);\n        result.AssertFail(Errors.Cancelled);\n    }\n    \n    [Fact(DisplayName = \"Schedule Run against Aff<T> should not capture state\")]\n    public static void ShouldNotCaptureState1Test()\n    {\n        var content = Encoding.ASCII.GetBytes(\"test\\0test\\0test\\0\");\n        var memStream = new MemoryStream(100);\n        memStream.Write(content, 0, content.Length);\n        memStream.Seek(0, SeekOrigin.Begin);\n\n        Eff<Unit> AddToBuffer(ICollection<string> buffer, string value) =>\n            lift(() => { buffer.Add(value); return unit; });\n\n        Eff<Unit> CreateEffect(ICollection<string> buffer) =>\n            repeat(from ln in (from data in liftEff(() => memStream.ReadByte().AsTask())\n                               from _ in guard(data != -1, Errors.Cancelled)\n                               select data)\n                              .FoldUntilIO(string.Empty, (s, ch) => s + (char)ch, ch => ch == '\\0')\n                   from _0 in AddToBuffer(buffer,ln)\n                   select unit).As()\n            | @catch(error => AddToBuffer(buffer,error.Message));\n\n        var buffer = new List<string>();\n        var effect = CreateEffect(buffer);\n\n        effect.Run(EnvIO.New()).Ignore();\n\n        Assert.True(toSeq(buffer) == Seq(\"test\\0\", \"test\\0\", \"test\\0\", \"cancelled\"));\n    }\n\n    [Fact(DisplayName = \"Schedule Run against Aff<RT,T> should not capture state\")]\n    public static void ShouldNotCaptureState2Test()\n    {\n        var content = Encoding.ASCII.GetBytes(\"test\\0test\\0test\\0\");\n        var memStream = new MemoryStream(100);\n        memStream.Write(content, 0, content.Length);\n        memStream.Seek(0, SeekOrigin.Begin);\n\n        Eff<RT, Unit> CreateEffect<RT>() where RT : Has<Eff<RT>, ConsoleIO> =>\n            repeat(from ln in (from data in liftEff(() => memStream.ReadByte().AsTask())\n                               from _ in guard(data != -1, Errors.Cancelled)\n                               select data)\n                              .FoldUntilIO(string.Empty, (s, ch) => s + (char)ch, ch => ch == '\\0')\n                              .As()\n                   from _0 in Console<RT>.writeLine(ln)\n                   select unit).As()\n            | @catch(error => Console<RT>.writeLine(error.Message));\n\n        using var runtime = Runtime.New();\n        var effect = CreateEffect<Runtime>();\n\n        effect.Run(runtime, EnvIO.New()).Ignore();\n\n        Assert.True(toSeq(runtime.Env.Console) == Seq(\"test\\0\", \"test\\0\", \"test\\0\", \"cancelled\"));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ScheduleTest/PositiveDurationTests.cs",
    "content": "﻿using Xunit;\n\nnamespace LanguageExt.Tests.ScheduleTest;\n\npublic static class PositiveDurationTests\n{\n    [Fact]\n    public static void EqualsTest() =>\n        Assert.True(new Duration(2) == new Duration(2));\n\n    [Fact]\n    public static void NotEqualsTest() =>\n        Assert.True(new Duration(2) != new Duration(4));\n\n    [Fact]\n    public static void GreaterThanTest() =>\n        Assert.True(new Duration(4) > new Duration(2));\n\n    [Fact]\n    public static void GreaterThanEqualToTest() =>\n        Assert.True(new Duration(4) >= new Duration(4));\n\n    [Fact]\n    public static void GreaterThanEqualToTest2() =>\n        Assert.False(new Duration(2) >= new Duration(4));\n\n    [Fact]\n    public static void LessThanTest() =>\n        Assert.True(new Duration(2) < new Duration(4));\n\n    [Fact]\n    public static void GreaterLessThanOrEqualToTest() =>\n        Assert.True(new Duration(2) <= new Duration(2));\n\n    [Fact]\n    public static void GreaterLessThanOrEqualToTest2() =>\n        Assert.False(new Duration(5) <= new Duration(2));\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ScheduleTest/ScheduleTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing System.Linq;\nusing FluentAssertions;\nusing static LanguageExt.Prelude;\nusing System.Diagnostics.Contracts;\nusing LanguageExt.UnsafeValueAccess;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace LanguageExt.Tests.ScheduleTest;\n\npublic sealed class ScheduleTests\n{\n    [Fact]\n    public static void ForeverTest()\n    {\n        var result = Schedule.Forever;\n        result\n           .Run()\n           .Take(10)\n           .AsEnumerable() \n           .Should()\n           .HaveCount(10)\n           .And\n           .OnlyContain(x => x == Duration.Zero);\n    }\n\n    [Fact]\n    public static void NeverTest()\n    {\n        var result = Schedule.Never;\n        result\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .BeEmpty();\n    }\n\n    [Fact]\n    public static void OnceTest()\n    {\n        var result = Schedule.Once;\n        result\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .ContainSingle(x => x == Duration.Zero);\n    }\n\n    [Fact]\n    public static void FromDurationsTest()\n    {\n        var result = Schedule.TimeSeries(1 * sec, 2 * sec, 3 * sec);\n        result\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .Equal(1 * sec, 2 * sec, 3 * sec);\n    }\n\n    [Fact]\n    public static void FromDurationsTest2()\n    {\n        var result = Schedule.TimeSeries(\n            Seq(1, 2, 3, 4, 5)\n               .Filter(x => x % 2 == 0)\n               .Map<Duration>(x => x * seconds));\n        result\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .Equal(2 * sec, 4 * sec);\n    }\n\n    [Fact]\n    public static void RecursTest()\n    {\n        var results = Schedule.recurs(5) | Schedule.Forever;\n        results\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .HaveCount(5)\n           .And\n           .Contain(x => x == Duration.Zero);\n    }\n\n    [Fact]\n    public static void SpacedTest()\n    {\n        var results = Schedule.spaced(5 * sec);\n        results\n           .Run()\n           .Take(5)\n           .AsEnumerable() \n           .Should()\n           .HaveCount(5)\n           .And\n           .OnlyContain(x => x == 5 * sec);\n    }\n\n    [Fact]\n    public static void LinearTest()\n    {\n        var results = Schedule.linear(1 * sec);\n        results\n           .Run()\n           .Take(5)\n           .AsEnumerable() \n           .Should()\n           .Equal(1 * sec, 2 * sec, 3 * sec, 4 * sec, 5 * sec);\n    }\n\n    [Fact]\n    public static void LinearTest2()\n    {\n        var results = Schedule.linear(100 * ms, 2);\n        results\n           .Run()\n           .Take(5)\n           .AsEnumerable() \n           .Should()\n           .Equal(100, 300, 500, 700, 900);\n    }\n\n    [Fact]\n    public static void ExponentialTest()\n    {\n        var results = Schedule.exponential(1 * sec);\n        results\n           .Run()\n           .Take(5)\n           .AsEnumerable() \n           .Should()\n           .Equal(1 * sec, 2 * sec, 4 * sec, 8 * sec, 16 * sec);\n    }\n\n    [Fact]\n    public static void ExponentialTest2()\n    {\n        var results = Schedule.exponential(1 * sec, 3);\n        results\n           .Run()\n           .Take(5)\n           .AsEnumerable() \n           .Should()\n           .Equal(1 * sec, 3 * sec, 9 * sec, 27 * sec, 81 * sec);\n    }\n\n    [Fact]\n    public static void FibonacciTest()\n    {\n        var results = Schedule.fibonacci(1 * sec);\n        results\n           .Run()\n           .Take(6)\n           .AsEnumerable() \n           .Should()\n           .Equal(1 * sec, 1 * sec, 2 * sec, 3 * sec, 5 * sec, 8 * sec);\n    }\n\n    [Fact]\n    public static void NoDelayOnFirstTest()\n    {\n        var transformer = Schedule.NoDelayOnFirst;\n        var results     = transformer.Apply(Schedule.spaced(10 * sec));\n        results\n           .Run()\n           .Take(5)\n           .AsEnumerable() \n           .Should()\n           .Equal(0 * sec, 10 * sec, 10 * sec, 10 * sec, 10 * sec);\n    }\n\n    [Fact]\n    public static void MaxDelayTest()\n    {\n        var transformer = Schedule.maxDelay(25 * sec);\n        var results     = transformer.Apply(Schedule.linear(10 * sec));\n        results\n           .Run()\n           .Take(5)\n           .Max().ValueUnsafe()\n           .Should().Be(25 * sec);\n    }\n\n    [Fact]\n    public static void MaxCumulativeDelayTest()\n    {\n        var transformer = Schedule.maxCumulativeDelay(40 * sec);\n        var results     = transformer.Apply(Schedule.linear(10 * sec)).Run().ToSeq();\n        \n        Assert.True(results.Count == 3);\n        Assert.True(results.Max().ValueUnsafe() == 30 * sec);\n    }\n\n    [Fact]\n    public static void UnionTest()\n    {\n        var results = Schedule.spaced(5 * sec).Union(Schedule.exponential(1 * sec));\n        results\n           .Run()\n           .Take(5)\n           .AsEnumerable() \n           .Should()\n           .Equal(1 * sec, 2 * sec, 4 * sec, 5 * sec, 5 * sec);\n    }\n\n    [Fact]\n    public static void IntersectTest()\n    {\n        var results = Schedule.spaced(5 * sec).Intersect(Schedule.exponential(1 * sec));\n        results\n           .Run()\n           .Take(5)\n           .AsEnumerable() \n           .Should()\n           .Equal(5 * sec, 5 * sec, 5 * sec, 8 * sec, 16 * sec);\n    }\n\n    [Fact]\n    public static void AppendTest()\n    {\n        var results =\n            Schedule.TimeSeries(1 * sec, 2 * sec, 3 * sec) +\n            Schedule.TimeSeries(4 * sec, 5 * sec, 6 * sec);\n        results\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .Equal(1 * sec, 2 * sec, 3 * sec, 4 * sec, 5 * sec, 6 * sec);\n    }\n\n    [Pure]\n    static Seq<DateTime> FromDuration(Duration duration)\n    {\n        var now = DateTime.Now;\n        return IterableExtensions.AsIterable(Range(0, (int)((TimeSpan)duration).TotalSeconds))\n                                 .Map(i => now + TimeSpan.FromSeconds(i))\n                                 .ToSeq();\n    }\n\n    [Pure]\n    static Seq<DateTime> FromDurations(Seq<Duration> durations) =>\n        durations.Fold(Seq(DateTime.Now), (times, duration) =>\n                                           {\n                                               var last = times.Head;\n                                               return times.Add(last.ValueUnsafe() + (TimeSpan)duration);\n                                           });\n\n    [Pure]\n    static Func<DateTime> FromDates(Seq<DateTime> dates) =>\n        () =>\n        {\n            var date = dates.Head.IfNone(() => DateTime.Now);\n            dates = dates.Tail;\n            return date;\n        };\n\n    [Fact]\n    public static void UpToTest()\n    {\n        var results = Schedule.upto(5 * sec, FromDates(FromDuration(2 * min)));\n        results\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .Equal(0, 0, 0, 0);\n    }\n\n    [Fact]\n    public static void FixedTest()\n    {\n        var results = Schedule.fixedInterval(5 * sec, FromDates(FromDurations(Seq<Duration>(\n                                                                                  6 * sec,\n                                                                                  1 * sec,\n                                                                                  4 * sec\n                                                                              ))));\n        results\n           .Run()\n           .Take(3)\n           .AsEnumerable() \n           .Should()\n           .Equal(0, 4 * sec, 1 * sec);\n    }\n\n    [Fact]\n    public static void WindowedTest()\n    {\n        var results = Schedule.windowed(5 * sec, FromDates(FromDurations(Seq<Duration>(\n                                                                             6 * sec,\n                                                                             1 * sec,\n                                                                             7 * sec\n                                                                         ))));\n        results\n           .Run()\n           .Take(3)\n           .AsEnumerable() \n           .Should()\n           .Equal(4 * sec, 4 * sec, 3 * sec);\n    }\n\n    [Fact]\n    public static void SecondOfMinuteTest()\n    {\n        var results = Schedule.secondOfMinute(3, FromDates(Seq(\n                                                               new DateTime(2022, 1, 1, 1, 1, 26),\n                                                               new DateTime(2022, 1, 1, 1, 1, 1),\n                                                               new DateTime(2022, 1, 1, 1, 1, 47)\n                                                           )));\n        results\n           .Run()\n           .Take(3)\n           .AsEnumerable() \n           .Should()\n           .Equal(37 * sec, 2 * sec, 16 * sec);\n    }\n\n    [Fact]\n    public static void MinuteOfHourTest()\n    {\n        var results = Schedule.minuteOfHour(3, FromDates(Seq(\n                                                             new DateTime(2022, 1, 1, 1, 26, 0),\n                                                             new DateTime(2022, 1, 1, 1, 1, 0),\n                                                             new DateTime(2022, 1, 1, 1, 47, 0)\n                                                         )));\n        results\n           .Run()\n           .Take(3)\n           .AsEnumerable() \n           .Should()\n           .Equal(37 * min, 2 * min, 16 * min);\n    }\n\n    [Fact]\n    public static void HourOfDayTest()\n    {\n        var results = Schedule.hourOfDay(3, FromDates(Seq(\n                                                          new DateTime(2022, 1, 1, 1, 0, 0),\n                                                          new DateTime(2022, 1, 1, 4, 0, 0),\n                                                          new DateTime(2022, 1, 1, 6, 0, 0),\n                                                          new DateTime(2022, 1, 1, 3, 0, 0)\n                                                      )));\n        results\n           .Run()\n           .Take(4)\n           .AsEnumerable() \n           .Should()\n           .Equal(2 * hours, 23 * hours, 21 * hour, 24 * hours);\n    }\n\n    [Fact]\n    public static void DayOfWeekTest()\n    {\n        var results = Schedule.dayOfWeek(DayOfWeek.Wednesday, FromDates(Seq(\n                                                                            new DateTime(2022, 1, 1, 0, 0, 0), // Saturday\n                                                                            new DateTime(2022, 1, 3, 0, 0, 0), // Monday\n                                                                            new DateTime(2022, 1, 7, 0, 0, 0), // Friday\n                                                                            new DateTime(2022, 1, 5, 0, 0, 0) // Wednesday\n                                                                        )));\n        results\n           .Run()\n           .Take(4)\n           .AsEnumerable() \n           .Should()\n           .Equal(4 * days, 2 * days, 5 * days, 7 * days);\n    }\n\n    const int Seed = 98192732;\n\n    [Fact]\n    public static void JitterTest1()\n    {\n        var noJitter = (\n                           Schedule.linear(10 * seconds)\n                         & Schedule.recurs(5)).Run().ToSeq();\n        var withJitter = (\n                             Schedule.linear(10 * seconds)\n                           & Schedule.recurs(5)\n                           & Schedule.jitter(1 * ms, 10 * ms)).Run().ToSeq();\n\n        var res = withJitter.ToArray();\n        Assert.True(res.Length == 5);\n        Assert.True(res.Zip(noJitter)\n                       .AsIterable()\n                       .Filter(p => p.Item1 > p.Item2 && p.Item1 - p.Item2 <= 100)\n                       .Any());\n    }\n\n    [Fact]\n    public static void JitterTest2()\n    {\n        var noJitter = (\n                           Schedule.linear(10 * seconds)\n                         & Schedule.recurs(5)).Run().ToSeq();\n        var withJitter = (\n                             Schedule.linear(10 * seconds)\n                           & Schedule.recurs(5)\n                           & Schedule.jitter(1.5)).Run().ToSeq();\n        \n        var res = withJitter.ToArray();\n        Assert.True(res.Length == 5);\n        Assert.True(res.Zip(noJitter)\n                       .AsIterable()\n                       .Filter(p => p.Item1 > p.Item2 && p.Item1 - p.Item2 <= p.Item2 * 1.5)\n                       .Any());\n    }\n\n    [Fact]\n    public static void DecorrelatedTest()\n    {\n        var schedule = Schedule.linear(10 * sec) | Schedule.decorrelate(seed: Seed);\n        var result   = schedule.Take(5).Run().ToSeq();\n        Assert.True(result.Zip(result.Skip(1)).Filter(x => x.First > x.Second).Any());\n    }\n\n    [Fact]\n    public static void ResetAfterTest()\n    {\n        var results =\n            Schedule.linear(10     * sec)\n          | Schedule.resetAfter(25 * sec);\n        results\n           .Run()\n           .Take(4)\n           .AsEnumerable() \n           .Should()\n           .Equal(10 * sec, 20 * sec, 10 * sec, 20 * sec);\n    }\n\n    [Fact]\n    public static void RepeatForeverTest()\n    {\n        var results = Schedule.TimeSeries(1 * sec, 5 * sec, 20 * sec) | Schedule.RepeatForever;\n            \n        results\n           .Run()\n           .Take(12)\n           .AsEnumerable() \n           .Should()\n           .Equal(1 * sec, 5 * sec, 20 * sec,\n                  1 * sec, 5 * sec, 20 * sec,\n                  1 * sec, 5 * sec, 20 * sec,\n                  1 * sec, 5 * sec, 20 * sec);\n    }\n\n    [Fact]\n    public static void RepeatTest()\n    {\n        var results = Schedule.TimeSeries(1 * sec, 5 * sec, 20 * sec) | Schedule.repeat(3);\n            \n        results\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .HaveCount(9)\n           .And\n           .Equal(1 * sec, 5 * sec, 20 * sec,\n                  1 * sec, 5 * sec, 20 * sec,\n                  1 * sec, 5 * sec, 20 * sec);\n    }\n\n    [Fact]\n    public static void IntersperseTest()\n    {\n        var results = Schedule.TimeSeries(1 * sec, 5 * sec, 20 * sec) | Schedule.intersperse(2 * sec);\n            \n        results\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .HaveCount(6)\n           .And\n           .Equal(1 * sec, 2 * sec, 5 * sec, 2 * sec, 20 * sec, 2 * sec);\n    }\n\n    [Fact]\n    public static void InterleaveTest()\n    {\n        var schedule1 = Schedule.TimeSeries(1 * sec, 5 * sec, 20 * sec);\n        var schedule2 = Schedule.TimeSeries(2 * sec, 7 * sec, 25 * sec);\n\n        var results = schedule1.Interleave(schedule2);\n        results\n           .Run()\n           .AsEnumerable() \n           .Should()\n           .HaveCount(6)\n           .And\n           .Equal(1 * sec, 2 * sec, 5 * sec, 7 * sec, 20 * sec, 25 * sec);\n    }\n\n    [Fact]\n    public static void RandomDurationTest()\n    {\n        var schedule1 =\n            Schedule.linear(Duration.random(10 * ms, 50 * ms))\n          | Schedule.decorrelate()\n          | Schedule.recurs(5);\n        var schedule2 =\n            Schedule.linear(Duration.random(10 * ms, 50 * ms))\n          | Schedule.decorrelate()\n          | Schedule.recurs(5);\n        var schedule3 =\n            Schedule.linear(Duration.random(10 * ms, 50 * ms))\n          | Schedule.decorrelate()\n          | Schedule.recurs(5);\n\n        schedule1.Run().AsEnumerable()\n                 .Should().HaveCount(5);\n        schedule2.Run().AsEnumerable()\n                 .Should().HaveCount(5);\n        schedule3.Run().AsEnumerable()\n                 .Should().HaveCount(5);\n    }\n\n    [Fact]\n    public static void MapTest()\n    {\n        var schedule = Schedule.linear(1 * ms).Map((x, i) => x % 2 == 0 ? x + i : x - i).Take(4);\n        schedule.Run()\n                .AsEnumerable() \n                .Should().Equal(1 * ms, 3 * ms, 1 * ms, 7 * ms);\n    }\n\n    [Fact]\n    public static void FilterTest()\n    {\n        var schedule = Schedule.linear(1 * ms).Filter(x => x % 2 == 0).Take(4);\n        schedule.Run().AsEnumerable()\n                .Should().Equal(2 * ms, 4 * ms, 6 * ms, 8 * ms);\n    }\n\n    [Fact]\n    public static void BindTest1()\n    {\n        var schedule =\n            Schedule\n               .linear(1 * ms)\n               .Filter(x => x % 2 == 0)\n               .Take(2)\n               .Bind(even =>\n                         Schedule\n                            .linear(1 * ms)\n                            .Filter(x => x % 2 != 0)\n                            .Take(2)\n                            .Bind(odd => Schedule.TimeSeries(even, odd)));\n\n        schedule.Run()\n                .AsEnumerable()\n                .Should()\n                .Equal(2 * ms, 1 * ms,\n                       2 * ms, 3 * ms,\n                       4 * ms, 1 * ms,\n                       4 * ms, 3 * ms);\n    }\n\n    [Fact]\n    public static void BindTest2()\n    {\n        var schedule =\n            from even in Schedule\n                        .linear(1 * ms)\n                        .Filter(x => x % 2 == 0)\n                        .Take(2)\n            from odd in Schedule\n                       .linear(1 * ms)\n                       .Filter(x => x % 2 != 0)\n                       .Take(2)\n            select Math.Pow(even, odd);\n\n        schedule.Run().AsEnumerable()\n                .Should().Equal(2 * ms, 8 * ms, 4 * ms, 64 * ms);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/Seq.Arr.Tests.cs",
    "content": "﻿using System;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class SeqArrTests\n{\n    [Fact]\n    public void TestEmpty()\n    {\n        var arr = Arr.empty<int>();\n\n        var seq = toSeq(arr);\n\n        Assert.True(seq.IsEmpty);\n        Assert.True(seq.Tail.IsEmpty);\n        Assert.True(seq.Tail.Tail.IsEmpty);\n        Assert.True(seq.Head.IsNone);\n        Assert.True(seq.Count == 0);\n\n        var res1 = seq.Match(\n            ()      => true,\n            (x, xs) => false);\n\n        var res2 = seq.Match(\n            ()      => true,\n            x       => false,\n            (x, xs) => false);\n\n        Assert.True(res1);\n        Assert.True(res2);\n\n        var skipped = seq.Skip(1);\n        Assert.True(skipped.IsEmpty);\n        Assert.True(skipped.Count   == 0);\n        Assert.True(skipped.Head.IsNone);\n    }\n\n    [Fact]\n    public void TestGetHashCodeEmpty()\n    {\n        var seq = Arr.empty<int>();\n\n        // check that GetHashCode won't throw\n        _ = seq.GetHashCode();\n    }\n\n    [Fact]\n    public void TestGetHashCodeDefault()\n    {\n        Arr<int> seq = default;\n\n        // check that GetHashCode won't throw\n        _ = seq.GetHashCode();\n    }\n\n    [Fact]\n    public void TestGetHashCodeDefaultCtor()\n    {\n        var seq = new Arr<int>();\n\n        // check that GetHashCode won't throw\n        _ = seq.GetHashCode();\n    }\n    \n    [Fact]\n    public void TestGetHashCodePartOfContainer()\n    {\n        var container = new Arr<int>[1];\n\n        // check that GetHashCode won't throw\n        _ = container[0].GetHashCode();\n    }\n    \n    [Fact]\n    public void TestGetHashCodeEmptyVsDefault()\n    {\n        var emptySeq = Arr.empty<int>();\n        Arr<int> defaultSeq = default;\n\n        var emptyHash = emptySeq.GetHashCode();\n        var defaultHash = defaultSeq.GetHashCode();\n        Assert.Equal(emptyHash, defaultHash);\n    }\n\n\n    [Fact]\n    public void TestOne()\n    {\n        var arr = Arr.create(1);\n\n        var seq = toSeq(arr);\n\n        Assert.True(seq.Head == 1);\n        Assert.True(seq.Tail.IsEmpty);\n        Assert.True(seq.Tail.Tail.IsEmpty);\n        Assert.True(seq.Count == 1);\n\n        var res1 = seq.Match(\n            ()      => false,\n            (x, xs) => x == 1 && xs.IsEmpty);\n\n        var res2 = seq.Match(\n            ()      => false,\n            x       => x == 1,\n            (x, xs) => false);\n\n        Assert.True(res1);\n        Assert.True(res2);\n\n        var skipped = seq.Skip(1);\n        Assert.True(skipped.IsEmpty);\n        Assert.True(skipped.Count == 0);\n        Assert.True(skipped.Head.IsNone);\n    }\n        \n    static int Sum(Seq<int> seq) =>\n        seq.Match(\n            ()      => 0,\n            x       => x,\n            (x, xs) => x + Sum(xs));\n\n    [Fact]\n    public void TestMore()\n    {\n        var arr = Arr.create(1, 2, 3, 4, 5);\n\n        var seq = toSeq(arr);\n\n        Assert.True(seq.Head                     == 1);\n        Assert.True(seq.Tail.Head                == 2);\n        Assert.True(seq.Tail.Tail.Head           == 3);\n        Assert.True(seq.Tail.Tail.Tail.Head      == 4);\n        Assert.True(seq.Tail.Tail.Tail.Tail.Head == 5);\n\n        Assert.True(seq.Tail.Tail.Tail.Tail.Tail.IsEmpty);\n\n        Assert.True(seq.Count                     == 5);\n        Assert.True(seq.Tail.Count                == 4);\n        Assert.True(seq.Tail.Tail.Count           == 3);\n        Assert.True(seq.Tail.Tail.Tail.Count      == 2);\n        Assert.True(seq.Tail.Tail.Tail.Tail.Count == 1);\n\n        var res = Sum(seq);\n\n        Assert.True(res == 15);\n\n        var skipped1 = seq.Skip(1);\n        Assert.True(skipped1.Head  == 2);\n        Assert.True(skipped1.Count == 4);\n\n        var skipped2 = seq.Skip(2);\n        Assert.True(skipped2.Head  == 3);\n        Assert.True(skipped2.Count == 3);\n\n        var skipped3 = seq.Skip(3);\n        Assert.True(skipped3.Head  == 4);\n        Assert.True(skipped3.Count == 2);\n\n        var skipped4 = seq.Skip(4);\n        Assert.True(skipped4.Head  == 5);\n        Assert.True(skipped4.Count == 1);\n\n        var skipped5 = seq.Skip(5);\n        Assert.True(skipped5.IsEmpty);\n        Assert.True(skipped5.Count == 0);\n    }\n\n    [Fact]\n    public void MapTest()\n    {\n        var arr = Arr.create(1, 2, 3, 4, 5);\n\n        var Seq  = toSeq(arr);\n        var seq2 = Seq.Map(x => x    * 2);\n        var seq3 = Seq.Select(x => x * 2);\n        var seq4 = from x in Seq\n                   select x * 2;\n\n        var expected = toSeq(Arr.create(2, 4, 6, 8, 10));\n\n        Assert.True(expected == seq2);\n        Assert.True(expected == seq3);\n        Assert.True(expected == seq4);\n    }\n\n    [Fact]\n    public void FilterTest()\n    {\n        var arr = Arr.create(1, 2, 3, 4, 5);\n\n        var Seq  = toSeq(arr);\n        var seq2 = Seq.Filter(x => x % 2 == 0);\n        var seq3 = Seq.Where(x => x  % 2 == 0);\n        var seq4 = from x in Seq\n                   where x % 2 == 0\n                   select x;\n\n        var expected = toSeq(Arr.create(2, 4));\n\n        Assert.True(expected == seq2);\n        Assert.True(expected == seq3);\n        Assert.True(expected == seq4);\n    }\n\n    [Fact]\n    public void BindTest()\n    {\n        var seq1 = toSeq(Arr.create(10, 100));\n        var seq2 = toSeq(Arr.create(1, 2, 3, 4, 5));\n\n        var seq3 = seq1.Bind(x => seq2.Map(y => x * y));\n\n        var expected = Seq(10, 20, 30, 40, 50, 100, 200, 300, 400, 500);\n\n        Assert.True(seq3 == expected);\n    }\n\n    [Fact]\n    public void FoldTest1()\n    {\n        var seq = toSeq(Arr.create(1, 2, 3, 4, 5));\n\n        var res1 = seq.Fold(1, (s, x) => s     * x);\n        var res2 = seq.FoldBack(1, (s, x) => s * x);\n\n        Assert.True(res1 == 120);\n        Assert.True(res2 == 120);\n    }\n\n    [Fact]\n    public void FoldTest2()\n    {\n        var seq = toSeq(Arr.create(\"a\", \"b\", \"c\", \"d\", \"e\"));\n\n        var res1 = seq.Fold(\"\", (s, x) => s     + x);\n        var res2 = seq.FoldBack(\"\", (s, x) => s + x);\n\n        Assert.True(res1 == \"abcde\");\n        Assert.True(res2 == \"edcba\");\n    }\n\n    [Fact]\n    public void Existential()\n    {\n        var Seq  = toSeq(Arr.create('a', 'b', 'c', 'd', 'e'));\n        var seq2 = toSeq(Arr.create('a', 'b', 'c', '_', 'e'));\n\n        var ex1 = Seq.Exists(x => x  == 'd');\n        var ex2 = seq2.Exists(x => x == 'd');\n\n        var fa1 = Seq.ForAll(Char.IsLetter);\n        var fa2 = seq2.ForAll(Char.IsLetter);\n\n        Assert.True(ex1);\n        Assert.False(ex2);\n\n        Assert.True(fa1);\n        Assert.False(fa2);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/Seq.Cons.Tests.cs",
    "content": "﻿using System;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class SeqConsTests\n    {\n        [Fact]\n        public void TestEmpty()\n        {\n            var arr = Seq<int>.Empty;\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.IsEmpty);\n            Assert.True(seq.Tail.IsEmpty);\n            Assert.True(seq.Tail.Tail.IsEmpty);\n            Assert.True(seq.Head.IsNone);\n            Assert.True(seq.Count == 0);\n\n            var res1 = seq.Match(\n                ()      => true,\n                (x, xs) => false);\n\n            var res2 = seq.Match(\n                ()      => true,\n                x       => false,\n                (x, xs) => false);\n\n            Assert.True(res1);\n            Assert.True(res2);\n\n            var skipped = seq.Skip(1);\n            Assert.True(skipped.IsEmpty);\n            Assert.True(skipped.Count == 0);\n            Assert.True(skipped.Head.IsNone);\n        }\n\n        [Fact]\n        public void TestOne()\n        {\n            var arr = 1.Cons();\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.Head == 1);\n            Assert.True(seq.Tail.IsEmpty);\n            Assert.True(seq.Tail.Tail.IsEmpty);\n            Assert.True(seq.Count == 1);\n\n            var res1 = seq.Match(\n                ()      => false,\n                (x, xs) => x == 1 && xs.IsEmpty);\n\n            var res2 = seq.Match(\n                ()      => false,\n                x       => x == 1,\n                (x, xs) => false);\n\n            Assert.True(res1);\n            Assert.True(res2);\n\n            var skipped = seq.Skip(1);\n            Assert.True(skipped.IsEmpty);\n            Assert.True(skipped.Count == 0);\n            Assert.True(skipped.Head.IsNone);\n        }\n        \n        static int Sum(Seq<int> seq) =>\n            seq.Match(\n                ()      => 0,\n                x       => x,\n                (x, xs) => x + Sum(xs));\n\n        [Fact]\n        public void TestMore()\n        {\n            var arr = 1.Cons(2.Cons(3.Cons(4.Cons(5.Cons()))));\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.Head == 1);\n            Assert.True(seq.Tail.Head == 2);\n            Assert.True(seq.Tail.Tail.Head == 3);\n            Assert.True(seq.Tail.Tail.Tail.Head == 4);\n            Assert.True(seq.Tail.Tail.Tail.Tail.Head == 5);\n\n            Assert.True(seq.Tail.Tail.Tail.Tail.Tail.IsEmpty);\n\n            Assert.True(seq.Count == 5);\n            Assert.True(seq.Tail.Count == 4);\n            Assert.True(seq.Tail.Tail.Count == 3);\n            Assert.True(seq.Tail.Tail.Tail.Count == 2);\n            Assert.True(seq.Tail.Tail.Tail.Tail.Count == 1);\n\n            var res = Sum(seq);\n\n            Assert.True(res == 15);\n\n            var skipped1 = seq.Skip(1);\n            Assert.True(skipped1.Head == 2);\n            Assert.True(skipped1.Count == 4);\n\n            var skipped2 = seq.Skip(2);\n            Assert.True(skipped2.Head == 3);\n            Assert.True(skipped2.Count == 3);\n\n            var skipped3 = seq.Skip(3);\n            Assert.True(skipped3.Head == 4);\n            Assert.True(skipped3.Count == 2);\n\n            var skipped4 = seq.Skip(4);\n            Assert.True(skipped4.Head == 5);\n            Assert.True(skipped4.Count == 1);\n\n            var skipped5 = seq.Skip(5);\n            Assert.True(skipped5.IsEmpty);\n            Assert.True(skipped5.Count == 0);\n        }\n\n        [Fact]\n        public void MapTest()\n        {\n            var arr = 1.Cons(2.Cons(3.Cons(4.Cons(5.Cons()))));\n\n            var seq1 = toSeq(arr);\n            var seq2 = seq1.Map(x => x * 2);\n            var seq3 = seq1.Select(x => x * 2);\n            var seq4 = from x in seq1\n                       select x * 2;\n\n            var expected = Seq(2, 4, 6, 8, 10);\n\n            Assert.True(expected == seq2);\n            Assert.True(expected == seq3);\n            Assert.True(expected == seq4);\n        }\n\n        [Fact]\n        public void FilterTest()\n        {\n            var arr = 1.Cons(2.Cons(3.Cons(4.Cons(5.Cons()))));\n\n            var seq1 = toSeq(arr);\n            var seq2 = seq1.Filter(x => x % 2 == 0);\n            var seq3 = seq1.Where(x => x % 2 == 0);\n            var seq4 = from x in seq1\n                       where x % 2 == 0\n                       select x;\n\n            var expected = Seq(2, 4);\n\n            Assert.True(expected == seq2);\n            Assert.True(expected == seq3);\n            Assert.True(expected == seq4);\n        }\n\n        [Fact]\n        public void BindTest()\n        {\n            var seq1 = 10.Cons(100.Cons());\n            var seq2 = 1.Cons(2.Cons(3.Cons(4.Cons(5.Cons()))));\n\n            var seq3 = seq1.Bind(x => seq2.Map(y => x * y));\n\n            var expected = Seq(10, 20, 30, 40, 50, 100, 200, 300, 400, 500);\n\n            Assert.True(seq3 == expected);\n        }\n\n        [Fact]\n        public void FoldTest1()\n        {\n            var seq = 1.Cons(2.Cons(3.Cons(4.Cons(5.Cons()))));\n\n            var res1 = seq.Fold(1, (s, x) => s * x);\n            var res2 = seq.FoldBack(1, (s, x) => s * x);\n\n            Assert.True(res1 == 120);\n            Assert.True(res2 == 120);\n        }\n\n        [Fact]\n        public void FoldTest2()\n        {\n            var seq = \"a\".Cons(\"b\".Cons(\"c\".Cons(\"d\".Cons(\"e\".Cons()))));\n\n            var res1 = seq.Fold(\"\", (s, x) => s + x);\n            var res2 = seq.FoldBack(\"\", (s, x) => s + x);\n\n            Assert.True(res1 == \"abcde\");\n            Assert.True(res2 == \"edcba\");\n        }\n\n        [Fact]\n        public void Existential()\n        {\n            var Seq = 'a'.Cons('b'.Cons('c'.Cons('d'.Cons('e'.Cons()))));\n            var seq2 = 'a'.Cons('b'.Cons('c'.Cons('_'.Cons('e'.Cons()))));\n\n            var ex1 = Seq.Exists(x => x == 'd');\n            var ex2 = seq2.Exists(x => x == 'd');\n\n            var fa1 = Seq.ForAll(Char.IsLetter);\n            var fa2 = seq2.ForAll(Char.IsLetter);\n\n            Assert.True(ex1);\n            Assert.False(ex2);\n\n            Assert.True(fa1);\n            Assert.False(fa2);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/Seq.Enumerable.Tests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class SeqEnumerableTests\n    {\n        IEnumerable<int> EmptyList = new int[0];\n        IEnumerable<int> OneItem = new int[] { 1 };\n        IEnumerable<int> FiveItems = new int[] { 1, 2, 3, 4, 5 };\n        IEnumerable<int> TenHundred = new int[] { 10, 100 };\n        IEnumerable<int> DoubleFiveItems = new int[] { 2, 4, 6, 8, 10 };\n        IEnumerable<int> EvenItems = new int[] { 2, 4 };\n        IEnumerable<int> BoundItems = new int[] { 10, 20, 30, 40, 50, 100, 200, 300, 400, 500 };\n        IEnumerable<char> abcdeChars = new char[] { 'a', 'b', 'c', 'd', 'e' };\n        IEnumerable<char> abc_eChars = new char[] { 'a', 'b', 'c', '_', 'e' };\n        IEnumerable<char> edcbaChars = new char[] { 'e', 'd', 'c', 'b', 'a' };\n        IEnumerable<string> abcdeStrs = new string[] { \"a\", \"b\", \"c\", \"d\", \"e\" };\n        IEnumerable<string> edcbaStrs = new string[] { \"e\", \"d\", \"c\", \"b\", \"a\" };\n\n        [Fact]\n        public void TestEmpty()\n        {\n            var arr = EmptyList;\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.IsEmpty);\n            Assert.True(seq.Tail.IsEmpty);\n            Assert.True(seq.Tail.Tail.IsEmpty);\n            Assert.True(seq.Head.IsNone);\n            Assert.True(seq.Count == 0);\n            Assert.True(seq.Count() == 0);\n\n            var res1 = seq.Match(\n                ()      => true,\n                (x, xs) => false);\n\n            var res2 = seq.Match(\n                ()      => true,\n                x       => false,\n                (x, xs) => false);\n\n            Assert.True(res1);\n            Assert.True(res2);\n\n            var skipped = seq.Skip(1);\n            Assert.True(skipped.IsEmpty);\n            Assert.True(skipped.Count == 0);\n            Assert.True(skipped.Count() == 0);\n            Assert.True(skipped.Head.IsNone);\n        }\n\n        [Fact]\n        public void TestOne()\n        {\n            var arr = OneItem;\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.Head == 1);\n            Assert.True(seq.Tail.IsEmpty);\n            Assert.True(seq.Tail.Tail.IsEmpty);\n\n            Assert.True(seq.Count == 1);\n            Assert.True(seq.Count() == 1);\n\n            var res1 = seq.Match(\n                ()      => false,\n                (x, xs) => x == 1 && xs.IsEmpty);\n\n            var res2 = seq.Match(\n                ()      => false,\n                x       => x == 1,\n                (x, xs) => false);\n\n            Assert.True(res1);\n            Assert.True(res2);\n\n            var skipped = seq.Skip(1);\n            Assert.True(skipped.IsEmpty);\n            Assert.True(skipped.Count == 0);\n            Assert.True(skipped.Count() == 0);\n            Assert.True(skipped.Head.IsNone);\n        }\n        \n        static int Sum(Seq<int> seq) =>\n            seq.Match(\n                ()      => 0,\n                x       => x,\n                (x, xs) => x + Sum(xs));\n\n        [Fact]\n        public void TestMore()\n        {\n            var arr = FiveItems;\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.Head == 1);\n            Assert.True(seq.Tail.Head == 2);\n            Assert.True(seq.Tail.Tail.Head == 3);\n            Assert.True(seq.Tail.Tail.Tail.Head == 4);\n            Assert.True(seq.Tail.Tail.Tail.Tail.Head == 5);\n\n            Assert.True(seq.Tail.Tail.Tail.Tail.Tail.IsEmpty);\n\n            Assert.True(seq.Count == 5);\n            Assert.True(seq.Count() == 5);\n\n            Assert.True(seq.Tail.Count == 4);\n            Assert.True(seq.Tail.Count() == 4);\n\n            Assert.True(seq.Tail.Tail.Count == 3);\n            Assert.True(seq.Tail.Tail.Count() == 3);\n\n            Assert.True(seq.Tail.Tail.Tail.Count == 2);\n            Assert.True(seq.Tail.Tail.Tail.Count() == 2);\n\n            Assert.True(seq.Tail.Tail.Tail.Tail.Count == 1);\n            Assert.True(seq.Tail.Tail.Tail.Tail.Count() == 1);\n\n            var res = Sum(seq);\n\n            Assert.True(res == 15);\n\n            var skipped1 = seq.Skip(1);\n            Assert.True(skipped1.Head == 2);\n            Assert.True(skipped1.Count == 4);\n            Assert.True(skipped1.Count() == 4);\n\n            var skipped2 = seq.Skip(2);\n            Assert.True(skipped2.Head == 3);\n            Assert.True(skipped2.Count == 3);\n            Assert.True(skipped2.Count() == 3);\n\n            var skipped3 = seq.Skip(3);\n            Assert.True(skipped3.Head == 4);\n            Assert.True(skipped3.Count == 2);\n            Assert.True(skipped3.Count() == 2);\n\n            var skipped4 = seq.Skip(4);\n            Assert.True(skipped4.Head == 5);\n            Assert.True(skipped4.Count == 1);\n            Assert.True(skipped4.Count() == 1);\n\n            var skipped5 = seq.Skip(5);\n            Assert.True(skipped5.IsEmpty);\n            Assert.True(skipped5.Count == 0);\n            Assert.True(skipped5.Count() == 0);\n        }\n\n        [Fact]\n        public void MapTest()\n        {\n            var arr = FiveItems;\n\n            var seq1 = toSeq(arr);\n            var seq2 = seq1.Map(x => x * 2);\n            var seq3 = seq1.Select(x => x * 2);\n            var seq4 = from x in seq1\n                       select x * 2;\n\n            var expected = toSeq(DoubleFiveItems);\n\n            Assert.True(expected == seq2);\n            Assert.True(expected == seq3);\n            Assert.True(expected == seq4);\n        }\n\n        [Fact]\n        public void FilterTest()\n        {\n            var arr = FiveItems;\n\n            var seq1 = toSeq(arr);\n            var seq2 = seq1.Filter(x => x % 2 == 0);\n            var seq3 = seq1.Where(x => x % 2 == 0);\n            var seq4 = from x in seq1\n                       where x % 2 == 0\n                       select x;\n\n            var expected = toSeq(EvenItems);\n\n            Assert.True(expected == seq2);\n            Assert.True(expected == seq3);\n            Assert.True(expected == seq4);\n        }\n\n        [Fact]\n        public void BindTest()\n        {\n            var seq1 = toSeq(TenHundred);\n            var seq2 = toSeq(FiveItems);\n\n            var seq3 = seq1.Bind(x => seq2.Map(y => x * y));\n\n            var expected = toSeq(BoundItems);\n\n            Assert.True(seq3 == expected);\n        }\n\n        [Fact]\n        public void FoldTest1()\n        {\n            var seq = toSeq(FiveItems);\n\n            var res1 = seq.Fold(1, (s, x) => s * x);\n            var res2 = seq.FoldBack(1, (s, x) => s * x);\n\n            Assert.True(res1 == 120);\n            Assert.True(res2 == 120);\n        }\n\n        [Fact]\n        public void FoldTest2()\n        {\n            var seq = toSeq(abcdeStrs);\n\n            var res1 = seq.Fold(\"\", (s, x) => s + x);\n            var res2 = seq.FoldBack(\"\", (s, x) => s + x);\n\n            Assert.True(res1 == \"abcde\");\n            Assert.True(res2 == \"edcba\");\n        }\n\n        [Fact]\n        public void Existential()\n        {\n            var Seq  = toSeq(abcdeChars);\n            var seq2 = toSeq(abc_eChars);\n\n            var ex1 = Seq.Exists(x => x == 'd');\n            var ex2 = seq2.Exists(x => x == 'd');\n\n            var fa1 = Seq.ForAll(Char.IsLetter);\n            var fa2 = seq2.ForAll(Char.IsLetter);\n\n            Assert.True(ex1);\n            Assert.False(ex2);\n\n            Assert.True(fa1);\n            Assert.False(fa2);\n        }\n\n        [Fact]\n        public void TestQueryableCount() =>\n            Assert.True(Seq(1, 2, 3).AsQueryable().Count() == 3);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/Seq.IList.Tests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class SeqIListTests\n    {\n        [Fact]\n        public void TestEmpty()\n        {\n            var arr = toSeq(new List<int>());\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.IsEmpty);\n            Assert.True(seq.Tail.IsEmpty);\n            Assert.True(seq.Tail.Tail.IsEmpty);\n            Assert.True(seq.Head.IsNone);\n            Assert.True(seq.Count == 0);\n\n            var res1 = seq.Match(\n                ()      => true,\n                (x, xs) => false);\n\n            var res2 = seq.Match(\n                ()      => true,\n                x       => false,\n                (x, xs) => false);\n\n            Assert.True(res1);\n            Assert.True(res2);\n\n            var skipped = seq.Skip(1);\n            Assert.True(skipped.IsEmpty);\n            Assert.True(skipped.Count == 0);\n            Assert.True(skipped.Head.IsNone);\n        }\n\n        [Fact]\n        public void TestOne()\n        {\n            var arr = toSeq(new List<int>() { 1 });\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.Head == 1);\n            Assert.True(seq.Tail.IsEmpty);\n            Assert.True(seq.Tail.Tail.IsEmpty);\n\n            Assert.True(seq.Count == 1);\n\n            var res1 = seq.Match(\n                ()      => false,\n                (x, xs) => x == 1 && xs.IsEmpty);\n\n            var res2 = seq.Match(\n                ()      => false,\n                x       => x == 1,\n                (x, xs) => false);\n\n            Assert.True(res1);\n            Assert.True(res2);\n\n            var skipped = seq.Skip(1);\n            Assert.True(skipped.IsEmpty);\n            Assert.True(skipped.Count == 0);\n            Assert.True(skipped.Head.IsNone);\n        }\n        \n        static int Sum(Seq<int> seq) =>\n            seq.Match(\n                ()      => 0,\n                x       => x,\n                (x, xs) => x + Sum(xs));\n\n        [Fact]\n        public void TestMore()\n        {\n            var arr = toSeq(new List<int>() { 1, 2, 3, 4, 5 });\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.Head == 1);\n            Assert.True(seq.Tail.Head == 2);\n            Assert.True(seq.Tail.Tail.Head == 3);\n            Assert.True(seq.Tail.Tail.Tail.Head == 4);\n            Assert.True(seq.Tail.Tail.Tail.Tail.Head == 5);\n\n            Assert.True(seq.Tail.Tail.Tail.Tail.Tail.IsEmpty);\n\n            Assert.True(seq.Count == 5);\n            Assert.True(seq.Tail.Count == 4);\n            Assert.True(seq.Tail.Tail.Count == 3);\n            Assert.True(seq.Tail.Tail.Tail.Count == 2);\n            Assert.True(seq.Tail.Tail.Tail.Tail.Count == 1);\n\n            var res = Sum(seq);\n\n            Assert.True(res == 15);\n\n            var skipped1 = seq.Skip(1);\n            Assert.True(skipped1.Head == 2);\n            Assert.True(skipped1.Count == 4);\n\n            var skipped2 = seq.Skip(2);\n            Assert.True(skipped2.Head == 3);\n            Assert.True(skipped2.Count == 3);\n\n            var skipped3 = seq.Skip(3);\n            Assert.True(skipped3.Head == 4);\n            Assert.True(skipped3.Count == 2);\n\n            var skipped4 = seq.Skip(4);\n            Assert.True(skipped4.Head == 5);\n            Assert.True(skipped4.Count == 1);\n\n            var skipped5 = seq.Skip(5);\n            Assert.True(skipped5.IsEmpty);\n            Assert.True(skipped5.Count == 0);\n        }\n\n        [Fact]\n        public void MapTest()\n        {\n            var arr = toSeq(new List<int>() { 1, 2, 3, 4, 5 });\n\n            var seq1  = toSeq(arr);\n            var seq2 = seq1.Map(x => x * 2);\n            var seq3 = seq1.Select(x => x * 2);\n            var seq4 = from x in seq1\n                       select x * 2;\n\n            var expected = toSeq(List.create(2, 4, 6, 8, 10));\n\n            Assert.True(expected == seq2);\n            Assert.True(expected == seq3);\n            Assert.True(expected == seq4);\n        }\n\n        [Fact]\n        public void FilterTest()\n        {\n            var arr = toSeq(new List<int>() { 1, 2, 3, 4, 5 });\n\n            var seq1 = toSeq(arr);\n            var seq2 = seq1.Filter(x => x % 2 == 0);\n            var seq3 = seq1.Where(x => x % 2 == 0);\n            var seq4 = from x in seq1\n                       where x % 2 == 0\n                       select x;\n\n            var expected = toSeq(List.create(2, 4));\n\n            Assert.True(expected == seq2);\n            Assert.True(expected == seq3);\n            Assert.True(expected == seq4);\n        }\n\n        [Fact]\n        public void BindTest()\n        {\n            var seq1 = toSeq(new List<int>() { 10, 100 });\n            var seq2 = toSeq(new List<int>() { 1, 2, 3, 4, 5 });\n\n            var seq3 = seq1.Bind(x => seq2.Map(y => x * y));\n\n            var expected = Seq(10, 20, 30, 40, 50, 100, 200, 300, 400, 500);\n\n            Assert.True(seq3 == expected);\n        }\n\n        [Fact]\n        public void FoldTest1()\n        {\n            var seq = toSeq(new List<int>() { 1, 2, 3, 4, 5 });\n\n            var res1 = seq.Fold(1, (s, x) => s * x);\n            var res2 = seq.FoldBack(1, (s, x) => s * x);\n\n            Assert.True(res1 == 120);\n            Assert.True(res2 == 120);\n        }\n\n        [Fact]\n        public void FoldTest2()\n        {\n            var seq = toSeq(new List<string>() { \"a\", \"b\", \"c\", \"d\", \"e\" });\n\n            var res1 = seq.Fold(\"\", (s, x) => s + x);\n            var res2 = seq.FoldBack(\"\", (s, x) => s + x);\n\n            Assert.True(res1 == \"abcde\");\n            Assert.True(res2 == \"edcba\");\n        }\n\n        [Fact]\n        public void Existential()\n        {\n            var Seq  = toSeq(new List<char>() { 'a', 'b', 'c', 'd', 'e' });\n            var seq2 = toSeq(new List<char>() { 'a', 'b', 'c', '_', 'e' });\n\n            var ex1 = Seq.Exists(x => x == 'd');\n            var ex2 = seq2.Exists(x => x == 'd');\n\n            var fa1 = Seq.ForAll(Char.IsLetter);\n            var fa2 = seq2.ForAll(Char.IsLetter);\n\n            Assert.True(ex1);\n            Assert.False(ex2);\n\n            Assert.True(fa1);\n            Assert.False(fa2);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/Seq.Lazy.Tests.cs",
    "content": "using System;\nusing Xunit;\n\nnamespace LanguageExt.Tests.SeqTypes;\n\npublic class Seq_Lazy_Tests\n{\n    [Theory]\n    [InlineData(0)]\n    [InlineData(1)]\n    [InlineData(2)]\n    [InlineData(3)]\n    [InlineData(5)]\n    [InlineData(8)]\n    [InlineData(13)]\n    [InlineData(21)]\n    [InlineData(34)]\n    [InlineData(55)]\n    [InlineData(89)]\n    [InlineData(99)]\n    public void BeginIndexTests(int index)\n    {\n        Index ix    = index; \n        var   seq   = toSeq(Range(0, 100));\n        var   value = seq[ix];\n        Assert.True(value == index);\n    }\n    \n    [Theory]\n    [InlineData(0)]\n    [InlineData(1)]\n    [InlineData(2)]\n    [InlineData(3)]\n    [InlineData(5)]\n    [InlineData(8)]\n    [InlineData(13)]\n    [InlineData(21)]\n    [InlineData(34)]\n    [InlineData(55)]\n    [InlineData(89)]\n    [InlineData(99)]\n    public void EndIndexTests(int index)\n    {\n        index++;\n        var ix    = Index.FromEnd(index); \n        var seq   = toSeq(Range(0, 100));\n        var value = seq[ix];\n        Assert.True(value == 100 - index);\n    }\n    \n    [Theory]\n    [InlineData(0)]\n    [InlineData(1)]\n    [InlineData(2)]\n    [InlineData(3)]\n    [InlineData(5)]\n    [InlineData(8)]\n    [InlineData(13)]\n    [InlineData(21)]\n    [InlineData(34)]\n    [InlineData(55)]\n    [InlineData(89)]\n    [InlineData(99)]\n    public void PreConcatBeginIndexTests(int index)\n    {\n        Index ix  = index; \n        var   pre = toSeq(Range(0, 50));\n        var   seq = pre + toSeq(Range(50, 50));\n        var   value = seq[ix];\n        Assert.True(value == index);\n    }\n    \n    [Theory]\n    [InlineData(0)]\n    [InlineData(1)]\n    [InlineData(2)]\n    [InlineData(3)]\n    [InlineData(5)]\n    [InlineData(8)]\n    [InlineData(13)]\n    [InlineData(21)]\n    [InlineData(34)]\n    [InlineData(55)]\n    [InlineData(89)]\n    [InlineData(99)]\n    public void PreConcatEndIndexTests(int index)\n    {\n        index++;\n        var ix  = Index.FromEnd(index); \n        var pre = toSeq(Range(0, 50));\n        var seq = pre + toSeq(Range(50, 50));\n        var value = seq[ix];\n        Assert.True(value == 100 - index);\n    }    \n    \n    [Theory]\n    [InlineData(0)]\n    [InlineData(1)]\n    [InlineData(2)]\n    [InlineData(3)]\n    [InlineData(5)]\n    [InlineData(8)]\n    [InlineData(13)]\n    [InlineData(21)]\n    [InlineData(34)]\n    [InlineData(55)]\n    [InlineData(89)]\n    [InlineData(99)]\n    public void PostConcatBeginIndexTests(int index)\n    {\n        Index ix   = index; \n        var   post = toSeq(Range(50, 50));\n        var   seq  = toSeq(Range(0, 50)) + post;\n        var   value = seq[ix];\n        Assert.True(value == index);\n    }\n    \n    [Theory]\n    [InlineData(0)]\n    [InlineData(1)]\n    [InlineData(2)]\n    [InlineData(3)]\n    [InlineData(5)]\n    [InlineData(8)]\n    [InlineData(13)]\n    [InlineData(21)]\n    [InlineData(34)]\n    [InlineData(55)]\n    [InlineData(89)]\n    [InlineData(99)]\n    public void PostConcatEndIndexTests(int index)\n    {\n        index++;\n        var ix   = Index.FromEnd(index); \n        var post = toSeq(Range(50, 50));\n        var seq  = toSeq(Range(0, 50)) + post;\n        var value = seq[ix];\n        Assert.True(value == 100 - index);\n    }     \n    \n    [Theory]\n    [InlineData(0, 50)]\n    [InlineData(1, 99)]\n    [InlineData(2, 89)]\n    [InlineData(3, 55)]\n    [InlineData(5, 34)]\n    [InlineData(8, 21)]\n    [InlineData(13, 13)]\n    [InlineData(21, 8)]\n    [InlineData(34, 5)]\n    [InlineData(55, 3)]\n    [InlineData(89, 2)]\n    [InlineData(99, 1)]\n    public void MemoisedBeginIndexTests(int index, int load)\n    {\n        Index ix    = index; \n        var   seq   = toSeq(Range(0, 100));\n        Enum(seq, load);\n        var   value = seq[ix];\n        Assert.True(value == index);\n    }\n    \n    [Theory]\n    [InlineData(0, 50)]\n    [InlineData(1, 99)]\n    [InlineData(2, 89)]\n    [InlineData(3, 55)]\n    [InlineData(5, 34)]\n    [InlineData(8, 21)]\n    [InlineData(13, 13)]\n    [InlineData(21, 8)]\n    [InlineData(34, 5)]\n    [InlineData(55, 3)]\n    [InlineData(89, 2)]\n    [InlineData(99, 1)]\n    public void MemoisedEndIndexTests(int index, int load)\n    {\n        index++;\n        var ix    = Index.FromEnd(index); \n        var seq   = toSeq(Range(0, 100));\n        Enum(seq, load);\n        var value = seq[ix];\n        Assert.True(value == 100 - index);\n    }\n    \n    [Theory]\n    [InlineData(0, 50)]\n    [InlineData(1, 99)]\n    [InlineData(2, 89)]\n    [InlineData(3, 55)]\n    [InlineData(5, 34)]\n    [InlineData(8, 21)]\n    [InlineData(13, 13)]\n    [InlineData(21, 8)]\n    [InlineData(34, 5)]\n    [InlineData(55, 3)]\n    [InlineData(89, 2)]\n    [InlineData(99, 1)]\n    public void PreConcatMemoisedBeginIndexTests(int index, int load)\n    {\n        Index ix  = index; \n        var   pre = toSeq(Range(0, 50));\n        var   seq = pre + toSeq(Range(50, 50));\n        Enum(seq, load);\n        var   value = seq[ix];\n        Assert.True(value == index);\n    }\n    \n    [Theory]\n    [InlineData(0, 50)]\n    [InlineData(1, 99)]\n    [InlineData(2, 89)]\n    [InlineData(3, 55)]\n    [InlineData(5, 34)]\n    [InlineData(8, 21)]\n    [InlineData(13, 13)]\n    [InlineData(21, 8)]\n    [InlineData(34, 5)]\n    [InlineData(55, 3)]\n    [InlineData(89, 2)]\n    [InlineData(99, 1)]\n    public void PreConcatMemoisedEndIndexTests(int index, int load)\n    {\n        index++;\n        var ix  = Index.FromEnd(index); \n        var pre = toSeq(Range(0, 50));\n        var seq = pre + toSeq(Range(50, 50));\n        Enum(seq, load);\n        var value = seq[ix];\n        Assert.True(value == 100 - index);\n    }    \n    \n    [Theory]\n    [InlineData(0, 50)]\n    [InlineData(1, 99)]\n    [InlineData(2, 89)]\n    [InlineData(3, 55)]\n    [InlineData(5, 34)]\n    [InlineData(8, 21)]\n    [InlineData(13, 13)]\n    [InlineData(21, 8)]\n    [InlineData(34, 5)]\n    [InlineData(55, 3)]\n    [InlineData(89, 2)]\n    [InlineData(99, 1)]\n    public void PostConcatMemoisedBeginIndexTests(int index, int load)\n    {\n        Index ix   = index; \n        var   post = toSeq(Range(50, 50));\n        var   seq  = toSeq(Range(0, 50)) + post;\n        Enum(seq, load);\n        var   value = seq[ix];\n        Assert.True(value == index);\n    }\n    \n    [Theory]\n    [InlineData(0, 50)]\n    [InlineData(1, 99)]\n    [InlineData(2, 89)]\n    [InlineData(3, 55)]\n    [InlineData(5, 34)]\n    [InlineData(8, 21)]\n    [InlineData(13, 13)]\n    [InlineData(21, 8)]\n    [InlineData(34, 5)]\n    [InlineData(55, 3)]\n    [InlineData(89, 2)]\n    [InlineData(99, 1)]\n    public void PostConcatMemoisedEndIndexTests(int index, int load)\n    {\n        index++;\n        var ix   = Index.FromEnd(index); \n        var post = toSeq(Range(50, 50));\n        var seq  = toSeq(Range(0, 50)) + post;\n        Enum(seq, load);\n        var value = seq[ix];\n        Assert.True(value == 100 - index);\n    }    \n\n    static void Enum(Seq<int> seq, int amount)\n    {\n        foreach(var x in seq)\n        {\n            amount--;\n            if (amount == 0) return;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/Seq.Lst.Tests.cs",
    "content": "﻿using System;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class SeqLstTests\n    {\n        [Fact]\n        public void TestEmpty()\n        {\n            var arr = List.empty<int>();\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.IsEmpty);\n            Assert.True(seq.Tail.IsEmpty);\n            Assert.True(seq.Tail.Tail.IsEmpty);\n            Assert.True(seq.Head.IsNone);\n            Assert.True(seq.Count == 0);\n\n            var res1 = seq.Match(\n                ()      => true,\n                (x, xs) => false);\n\n            var res2 = seq.Match(\n                ()      => true,\n                x       => false,\n                (x, xs) => false);\n\n            Assert.True(res1);\n            Assert.True(res2);\n\n            var skipped = seq.Skip(1);\n            Assert.True(skipped.IsEmpty);\n            Assert.True(skipped.Count == 0);\n            Assert.True(skipped.Head.IsNone);\n        }\n\n        [Fact]\n        public void TestOne()\n        {\n            var arr = List.create(1);\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.Head == 1);\n            Assert.True(seq.Tail.IsEmpty);\n            Assert.True(seq.Tail.Tail.IsEmpty);\n            Assert.True(seq.Count == 1);\n\n            var res1 = seq.Match(\n                ()      => false,\n                (x, xs) => x == 1 && xs.IsEmpty);\n\n            var res2 = seq.Match(\n                ()      => false,\n                x       => x == 1,\n                (x, xs) => false);\n\n            Assert.True(res1);\n            Assert.True(res2);\n\n            var skipped = seq.Skip(1);\n            Assert.True(skipped.IsEmpty);\n            Assert.True(skipped.Count == 0);\n            Assert.True(skipped.Head.IsNone);\n        }\n        \n        static int Sum(Seq<int> seq) =>\n            seq.Match(\n                ()      => 0,\n                x       => x,\n                (x, xs) => x + Sum(xs));\n\n        [Fact]\n        public void TestMore()\n        {\n            var arr = List.create(1, 2, 3, 4, 5);\n\n            var seq = toSeq(arr);\n\n            Assert.True(seq.Head == 1);\n            Assert.True(seq.Tail.Head == 2);\n            Assert.True(seq.Tail.Tail.Head == 3);\n            Assert.True(seq.Tail.Tail.Tail.Head == 4);\n            Assert.True(seq.Tail.Tail.Tail.Tail.Head == 5);\n\n            Assert.True(seq.Tail.Tail.Tail.Tail.Tail.IsEmpty);\n\n            Assert.True(seq.Count == 5);\n            Assert.True(seq.Tail.Count == 4);\n            Assert.True(seq.Tail.Tail.Count == 3);\n            Assert.True(seq.Tail.Tail.Tail.Count == 2);\n            Assert.True(seq.Tail.Tail.Tail.Tail.Count == 1);\n\n            var res = Sum(seq);\n\n            Assert.True(res == 15);\n\n            var skipped1 = seq.Skip(1);\n            Assert.True(skipped1.Head == 2);\n            Assert.True(skipped1.Count == 4);\n\n            var skipped2 = seq.Skip(2);\n            Assert.True(skipped2.Head == 3);\n            Assert.True(skipped2.Count == 3);\n\n            var skipped3 = seq.Skip(3);\n            Assert.True(skipped3.Head == 4);\n            Assert.True(skipped3.Count == 2);\n\n            var skipped4 = seq.Skip(4);\n            Assert.True(skipped4.Head == 5);\n            Assert.True(skipped4.Count == 1);\n\n            var skipped5 = seq.Skip(5);\n            Assert.True(skipped5.IsEmpty);\n            Assert.True(skipped5.Count == 0);\n        }\n\n        [Fact]\n        public void MapTest()\n        {\n            var arr = List.create(1, 2, 3, 4, 5);\n\n            var Seq  = toSeq(arr);\n            var seq2 = Seq.Map(x => x * 2);\n            var seq3 = Seq.Select(x => x * 2);\n            var seq4 = from x in Seq\n                       select x * 2;\n\n            var expected = toSeq(List.create(2, 4, 6, 8, 10));\n\n            Assert.True(expected == seq2);\n            Assert.True(expected == seq3);\n            Assert.True(expected == seq4);\n        }\n\n        [Fact]\n        public void FilterTest()\n        {\n            var arr = List.create(1, 2, 3, 4, 5);\n\n            var Seq  = toSeq(arr);\n            var seq2 = Seq.Filter(x => x % 2 == 0);\n            var seq3 = Seq.Where(x => x % 2 == 0);\n            var seq4 = from x in Seq\n                       where x % 2 == 0\n                       select x;\n\n            var expected = toSeq(List.create(2, 4));\n\n            Assert.True(expected == seq2);\n            Assert.True(expected == seq3);\n            Assert.True(expected == seq4);\n        }\n\n        [Fact]\n        public void BindTest()\n        {\n            var seq1 = toSeq(List.create(10, 100));\n            var seq2 = toSeq(List.create(1, 2, 3, 4, 5));\n\n            var seq3 = seq1.Bind(x => seq2.Map(y => x * y));\n\n            var expected = Seq(10, 20, 30, 40, 50, 100, 200, 300, 400, 500);\n\n            Assert.True(seq3 == expected);\n        }\n\n        [Fact]\n        public void FoldTest1()\n        {\n            var seq = toSeq(List.create(1, 2, 3, 4, 5));\n\n            var res1 = seq.Fold(1, (s, x) => s * x);\n            var res2 = seq.FoldBack(1, (s, x) => s * x);\n\n            Assert.True(res1 == 120);\n            Assert.True(res2 == 120);\n        }\n\n        [Fact]\n        public void FoldTest2()\n        {\n            var seq = toSeq(List.create(\"a\", \"b\", \"c\", \"d\", \"e\"));\n\n            var res1 = seq.Fold(\"\", (s, x) => s + x);\n            var res2 = seq.FoldBack(\"\", (s, x) => s + x);\n\n            Assert.True(res1 == \"abcde\");\n            Assert.True(res2 == \"edcba\");\n        }\n\n        [Fact]\n        public void Existential()\n        {\n            var Seq  = toSeq(List.create('a', 'b', 'c', 'd', 'e'));\n            var seq2 = toSeq(List.create('a', 'b', 'c', '_', 'e'));\n\n            var ex1 = Seq.Exists(x => x == 'd');\n            var ex2 = seq2.Exists(x => x == 'd');\n\n            var fa1 = Seq.ForAll(Char.IsLetter);\n            var fa2 = seq2.ForAll(Char.IsLetter);\n\n            Assert.True(ex1);\n            Assert.False(ex2);\n\n            Assert.True(fa1);\n            Assert.False(fa2);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/Seq.Module.Tests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class SeqModuleTests\n{\n    [Fact]\n    public void EmptyTest()\n    {\n        Assert.True(Seq.empty<int>().IsEmpty);\n    }\n\n    [Fact]\n    public void CreateTest()\n    {\n        Assert.True(Seq.create<int>().IsEmpty);\n\n        var seq = Seq.create(1, 2, 3, 4, 5);\n\n        Assert.True(seq.Head                     == 1);\n        Assert.True(seq.Tail.Head                == 2);\n        Assert.True(seq.Tail.Tail.Head           == 3);\n        Assert.True(seq.Tail.Tail.Tail.Head      == 4);\n        Assert.True(seq.Tail.Tail.Tail.Tail.Head == 5);\n\n        var seqr = Seq.createRange(new[] { 1, 2, 3, 4, 5 });\n\n        Assert.True(seqr.Head                     == 1);\n        Assert.True(seqr.Tail.Head                == 2);\n        Assert.True(seqr.Tail.Tail.Head           == 3);\n        Assert.True(seqr.Tail.Tail.Tail.Head      == 4);\n        Assert.True(seqr.Tail.Tail.Tail.Tail.Head == 5);\n    }\n\n    [Fact]\n    public void InitTest()\n    {\n        int            counter = 0;\n        Func<int, int> run     = x => { counter++; return x; };\n\n        var seq = Seq.generate(5, x => run((x + 1) * 2));\n\n        var fst = seq.Take(1).Head;\n\n        Assert.True(counter == 1);\n        Assert.True(fst     == 2);\n\n        var snd = seq.Skip(1).Take(1).Head;\n\n        Assert.True(counter == 2);\n        Assert.True(snd     == 4);\n\n        var thd = seq.Skip(2).Take(1).Head;\n\n        Assert.True(counter == 3);\n        Assert.True(thd     == 6);\n\n        var fth = seq.Skip(3).Take(1).Head;\n\n        Assert.True(counter == 4);\n        Assert.True(fth     == 8);\n\n        var fit = seq.Skip(4).Take(1).Head;\n\n        Assert.True(counter == 5);\n        Assert.True(fit     == 10);\n\n        var sum = seq.Sum();\n\n        Assert.True(counter == 5);\n        Assert.True(sum     == 30);\n    }\n\n    [Fact]\n    public void EquivalentOfTheInitTestWithIEnumerable()\n    {\n        int            counter = 0;\n        Func<int, int> run     = x => { counter++; return x; };\n\n        var seq = List.generate(5, x => run((x + 1) * 2));\n\n        var fst = seq.Take(1).First();\n\n        Assert.True(counter == 1);\n        Assert.True(fst     == 2);\n\n        var snd = seq.Skip(1).Take(1).First();\n\n        // Assert.True(counter == 2);  equals 3 by this point\n        Assert.True(snd == 4);\n\n        var thd = seq.Skip(2).Take(1).First();\n\n        // Assert.True(counter == 3);   equals 6 by this point\n        Assert.True(thd == 6);\n\n        var fth = seq.Skip(3).Take(1).First();\n\n        // Assert.True(counter == 4);   equals 10 by this point (double what the InitTest needs!)\n        Assert.True(fth == 8);\n\n        var fit = seq.Skip(4).Take(1).First();\n\n        //Assert.True(counter == 5);    equals 15 by this point (treble what the InitTest needs!)\n        Assert.True(fit == 10);\n\n        var sum = seq.Sum();\n\n        // Assert.True(counter == 5);   equals 20 by this point(four times what the InitTest needs!!!)\n        Assert.True(sum == 30);\n    }\n\n    [Fact]\n    public void TailsTestIterative()\n    {\n        var seq = Seq(1, 2, 3, 4, 5);\n\n        var seqs = Seq.tails(seq);\n\n        Assert.True(seqs.Head                     == Seq(1, 2, 3, 4, 5));\n        Assert.True(seqs.Tail.Head                == Seq(2, 3, 4, 5));\n        Assert.True(seqs.Tail.Tail.Head           == Seq(3, 4, 5));\n        Assert.True(seqs.Tail.Tail.Tail.Head      == Seq(4, 5));\n        Assert.True(seqs.Tail.Tail.Tail.Tail.Head == Seq.create(5));\n        Assert.True(seqs.Tail.Tail.Tail.Tail.Tail.IsEmpty);\n    }\n\n    [Fact]\n    public void TailsTestRecursive()\n    {\n        var seq = Seq(1, 2, 3, 4, 5);\n\n        var seqs = Seq.tailsr(seq);\n\n        Assert.True(seqs.Head                     == Seq(1, 2, 3, 4, 5));\n        Assert.True(seqs.Tail.Head                == Seq(2, 3, 4, 5));\n        Assert.True(seqs.Tail.Tail.Head           == Seq(3, 4, 5));\n        Assert.True(seqs.Tail.Tail.Tail.Head      == Seq(4, 5));\n        Assert.True(seqs.Tail.Tail.Tail.Tail.Head == Seq.create(5));\n        Assert.True(seqs.Tail.Tail.Tail.Tail.Tail.IsEmpty);\n    }\n\n    [Fact]\n    public void CountTests()\n    {\n        int            counter = 0;\n        Func<int, int> run     = x => { counter++; return x; };\n\n        var seq1 = Seq.generate(5, x => run((x + 1) * 2));\n        var seq2 = 1.Cons(seq1);\n\n        var cnt1 = seq1.Count;\n        var cnt2 = seq2.Count;\n\n        Assert.True(counter == 5);\n        Assert.True(cnt1    == 5);\n        Assert.True(cnt2    == 6);\n\n        var seq3 = Seq.generate(5, x => run((x + 1) * 2));\n        var seq4 = 1.Cons(seq3);\n\n        var cnt3 = seq4.Count;\n        var cnt4 = seq3.Count;\n\n        Assert.True(counter == 10);\n        Assert.True(cnt4    == 5);\n        Assert.True(cnt3    == 6);\n    }\n\n    /// <summary>\n    /// Runs 1000 tasks that sums the same lazy Seq to\n    /// make sure we get the same result as a synchronous\n    /// sum.\n    /// </summary>\n    [Fact]\n    public async Task ParallelTests()\n    {\n        var sum = Range(1, 10000).Sum();\n\n        var seq = toSeq(Range(1, 10000));\n\n        var tasks = new List<Task<int>>();\n        foreach(var x in Range(1, 1000))\n        {\n            tasks.Add(Task.Run(() => seq.Sum()));\n        }\n\n        await Task.WhenAll(tasks.ToArray());\n\n        var results = tasks.Select(t => t.Result).ToArray();\n\n        seq.Iter((i, x) => Assert.True(x != 0, $\"Invalid value in the sequence at index {i}\"));\n\n        foreach (var task in tasks)\n        {\n            Assert.True(task.Result == sum, $\"Result is {task.Result}, should be: {sum}\");\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/SeqListTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.SeqTypes\n{\n    public class SeqListTests\n    {\n        [Fact]\n        public void Take_ZeroFromNonempty_Empty()\n        {\n            var seq    = toSeq(new List<int> { 0 });\n            var actual = seq.Take(0);\n            Assert.Equal(actual, SeqEmpty.Default);\n        }\n\n        [Fact]\n        public void Take_NegativeFromNonempty_Empty()\n        {\n            var seq    = toSeq(new List<int> { 0 });\n            var actual = seq.Take(-1);\n            Assert.Equal(actual, SeqEmpty.Default);\n        }\n\n        [Fact]\n        public void Skip_NegativeFromNonempty_Unchanged()\n        {\n            var expected = toSeq(new List<int> { 0 });\n            var actual   = expected.Skip(-1);\n            Assert.Equal(actual, expected);\n        }\n\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SeqTypes/SeqTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing static LanguageExt.Seq;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class SeqTests\n{\n    [Fact]\n    public void ObjectExists()\n    {\n        var x = \"test\";\n\n        Assert.True(Seq(x).Count() == 1);\n        Assert.True(Seq(x).Head    == x);\n    }\n\n    [Fact]\n    public void ObjectNull()\n    {\n        string? x = null;\n\n        Assert.Equal(0, toSeq(x).Count());\n    }\n\n    [Fact]\n    public void EnumerableExists()\n    {\n        var x = new[] { \"a\", \"b\", \"c\" };\n\n        var y = toSeq(x);\n\n        var res = toSeq(x).Tail().AsEnumerable().ToList();\n\n\n        Assert.True(toSeq(x).Count          == 3);\n        Assert.True(toSeq(x).Head           == \"a\");\n        Assert.True(toSeq(x).Tail.Head      == \"b\");\n        Assert.True(toSeq(x).Tail.Tail.Head == \"c\");\n    }\n\n    [Fact]\n    public void EnumerableNull()\n    {\n        string[]? x = null;\n\n        Assert.True(toSeq(x).Count == 0);\n    }\n\n    [Fact]\n    public void TakeTest()\n    {\n        IEnumerable<int> Numbers()\n        {\n            for (int i = 0; i < 100; i++)\n            {\n                yield return i;\n            }\n        }\n\n        var seq = Numbers().AsIterable().ToSeq();\n\n        var a = seq.Take(5).Sum();\n        Assert.True(a == 10);\n\n        var b = seq.Skip(5).Take(5).Sum();\n        Assert.True(b == 35);\n\n    }\n\n    [Fact]\n    public void FoldTest()\n    {\n        var input   = Seq(1, 2, 3, 4, 5);\n        var output1 = Foldable.fold((s, x) => s + x, \"\", input);\n        Assert.Equal(\"12345\", output1);\n    }\n\n    [Fact]\n    public void FoldBackTest()\n    {\n        var input   = Seq(1, 2, 3, 4, 5);\n        var output1 = Foldable.foldBack((s, x) => s + x, \"\", input);\n        Assert.Equal(\"54321\", output1);\n    }\n\n    [Fact]\n    public void FoldWhileTest()\n    {\n        var input = Seq(10, 20, 30, 40, 50);\n\n        var output1 = Foldable.foldWhile((s, x) => s + x, x => x.Value < 40, \"\", input);\n        Assert.Equal(\"102030\", output1);\n\n        var output2 = Foldable.foldWhile((s, x) => s + x, s => s.State.Length < 6, \"\", input);\n        Assert.Equal(\"102030\", output2);\n\n        var output3 = Foldable.foldWhile((s, x) => s + x, x => x.Value < 40, 0, input);\n        Assert.Equal(60, output3);\n\n        var output4 = Foldable.foldWhile((s, x) => s + x, s => s.State < 60, 0, input);\n        Assert.Equal(60, output4);\n    }\n\n    [Fact]\n    public void FoldBackWhileTest()\n    {\n        var input = Seq(10, 20, 30, 40, 50);\n\n        var output1 = Foldable.foldBackWhile((s, x) => s + x, x => x.Value >= 40, \"\", input);\n        Assert.Equal(\"5040\", output1);\n\n        var output2 = Foldable.foldBackWhile((s, x) => s + x, s => s.State.Length < 4, \"\", input);\n        Assert.Equal(\"5040\", output2);\n\n        var output3 = Foldable.foldBackWhile((s, x) => s + x, x => x.Value >= 40, 0, input);\n        Assert.Equal(90, output3);\n\n        var output4 = Foldable.foldBackWhile((s, x) => s + x, s => s.State < 90, 0, input);\n        Assert.Equal(90, output4);\n    }\n\n    [Fact]\n    public void FoldUntilTest()\n    {\n        var input = Seq(10, 20, 30, 40, 50);\n\n        var output1 = Foldable.foldUntil((s, x) => s + x, x => x.Value >= 40, \"\", input);\n        Assert.Equal(\"102030\", output1);\n\n        var output2 = Foldable.foldUntil((s, x) => s + x, s => s.State.Length >= 6, \"\", input);\n        Assert.Equal(\"102030\", output2);\n\n        var output3 = Foldable.foldUntil((s, x) => s + x, x => x.Value >= 40, 0, input);\n        Assert.Equal(60, output3);\n\n        var output4 = Foldable.foldUntil((s, x) => s + x, s => s.State >= 60, 0, input);\n        Assert.Equal(60, output4);\n    }\n\n    [Fact]\n    public void FoldBackUntilTest()\n    {\n        var input = Seq(10, 20, 30, 40, 50);\n\n        var output1 = Foldable.foldBackUntil((s, x) => s + x, x => x.Value < 40, \"\", input);\n        Assert.Equal(\"5040\", output1);\n\n        var output2 = Foldable.foldBackUntil((s, x) => s + x, s => s.State.Length >= 4, \"\", input);\n        Assert.Equal(\"5040\", output2);\n\n        var output3 = Foldable.foldBackUntil((s, x) => s + x, x => x.Value < 40, 0, input);\n        Assert.Equal(90, output3);\n\n        var output4 = Foldable.foldBackUntil((s, x) => s + x, s => s.State >= 90, 0, input);\n        Assert.Equal(90, output4);\n    }\n\n    [Fact]\n    public void EqualityTest_BothNull()\n    {\n        Seq<int> x = default;\n        Seq<int> y = default;\n\n        var eq = x == y;\n\n        Assert.True(eq);\n    }\n\n    [Fact]\n    public void EqualityTest_LeftNull()\n    {\n        Seq<int> x = default;\n        Seq<int> y = Seq(1, 2, 3);\n\n        var eq = x == y;\n\n        Assert.False(eq);\n    }\n\n    [Fact]\n    public void EqualityTest_RightNull()\n    {\n        Seq<int> x = Seq(1, 2, 3);\n        Seq<int> y = default;\n\n        var eq = x == y;\n\n        Assert.False(eq);\n    }\n\n    [Fact]\n    public void EqualityTest()\n    {\n        Seq<int> x = Seq(1, 2, 3);\n        Seq<int> y = Seq(1, 2, 3);\n\n        var eq = x == y;\n\n        Assert.True(eq);\n    }\n\n    /// <summary>\n    /// Test ensures that lazily evaluated Seq returns the same as strictly evaluated when multiple enumerations occur\n    /// </summary>\n    [Fact]\n    public void GetEnumeratorTest()\n    {           \n        var res1 = empty<int>();\n        var res2 = empty<int>();\n\n        var a = new List<int> { 1, 2, 3, 4 }.AsIterable();\n\n        var s1 = a.ToSeq();\n        var s2 = a.ToSeq().Strict();\n\n        foreach (var s in s1)\n        {\n            if (s == 2)\n            {\n                s1.FoldWhile(\"\", (x, y) => \"\", x => x.Value != 3);\n            }\n            res1 = res1.Add(s);\n        }\n\n        foreach (var s in s2)\n        {\n            if (s == 2)\n            {\n                s2.FoldWhile(\"\", (x, y) => \"\", x => x.Value != 3);\n            }\n            res2 = res2.Add(s);\n        }\n\n        var eq = res1 == res2;\n\n        Assert.True(eq);\n    }\n\n    [Fact]\n    public void AddTest()\n    {\n        var a = Seq(\"a\");\n\n        var b = a.Add(\"b\");\n\n        var c = a.Add(\"c\");\n\n        Assert.Equal(\"a\", string.Join(\"|\", a));\n        Assert.Equal(\"a|b\", string.Join(\"|\", b));\n        Assert.Equal(\"a|c\", string.Join(\"|\", c));\n\n    }\n\n    [Fact]\n    public void ConsTest()\n    {\n        var a = Seq1(\"a\");\n\n        var b = \"b\".Cons(a);\n\n        var c = \"c\".Cons(a);\n\n        Assert.Equal(\"a\", string.Join(\"|\", a));\n        Assert.Equal(\"b|a\", string.Join(\"|\", b));\n        Assert.Equal(\"c|a\", string.Join(\"|\", c));\n\n    }\n\n    [Fact]\n    public void InitStrictTest()\n    {\n        var sa = Seq(1, 2, 3, 4, 5);\n\n        var sb = sa.Init; // [1,2,3,4]\n        var sc = sb.Init; // [1,2,3]\n        var sd = sc.Init; // [1,2]\n        var se = sd.Init; // [1]\n        var sf = se.Init; // []\n\n        Assert.True(sb == Seq(1, 2, 3, 4));\n        Assert.True(sc == Seq(1, 2, 3));\n        Assert.True(sd == Seq(1, 2));\n        Assert.True(se == Seq(1));\n        Assert.True(sf == Empty);\n    }\n\n    [Fact]\n    public void InitLazyTest()\n    {\n        var sa = toSeq(Range(1, 5));\n\n        var sb = sa.Init; // [1,2,3,4]\n        var sc = sb.Init; // [1,2,3]\n        var sd = sc.Init; // [1,2]\n        var se = sd.Init; // [1]\n        var sf = se.Init; // []\n\n        Assert.True(sb == Seq(1, 2, 3, 4));\n        Assert.True(sc == Seq(1, 2, 3));\n        Assert.True(sd == Seq(1, 2));\n        Assert.True(se == Seq(1));\n        Assert.True(sf == Empty);\n    }\n\n    [Fact]\n    public void InitConcatTest()\n    {\n        var sa = toSeq(Range(1, 2)) + toSeq(Range(3, 3));\n\n        var sb = sa.Init; // [1,2,3,4]\n        var sc = sb.Init; // [1,2,3]\n        var sd = sc.Init; // [1,2]\n        var se = sd.Init; // [1]\n        var sf = se.Init; // []\n\n        Assert.True(sb == Seq(1, 2, 3, 4));\n        Assert.True(sc == Seq(1, 2, 3));\n        Assert.True(sd == Seq(1, 2));\n        Assert.True(se == Seq(1));\n        Assert.True(sf == Empty);\n    }\n\n    [Fact]\n    public void HashTest()\n    {\n        var s1 = Seq(\"test\");\n        var s2 = Seq(\"test\");\n\n        Assert.True(s1.GetHashCode() == s2.GetHashCode());\n    }\n        \n    [Fact]\n    public void TakeWhileTest()\n    {\n        var str = \"                          <p>The</p>\".AsIterable();\n        Assert.Equal(\"                          \",\n                     String.Join(\"\", str.ToSeq().TakeWhile(ch => ch == ' ')));\n    }\n\n    [Fact]\n    public void TakeWhileIndex()\n    {\n        var str = \"                          <p>The</p>\".AsIterable();\n        Assert.Equal(\"                          \",\n                     String.Join(\"\", str.ToSeq().TakeWhile((ch, index) => index != 26)));\n    }\n\n    [Fact]\n    public void TakeWhile_HalfDefaultCapacityTest()\n    {\n        var str = \"1234\".AsIterable();\n        Assert.Equal(\"1234\", String.Join(\"\", str.ToSeq().TakeWhile(ch => true)));\n    }\n\n    [Fact]\n    public void TakeWhileIndex_HalfDefaultCapacityTest()\n    {\n        var str = \"1234\".AsIterable();\n        Assert.Equal(\"1234\", String.Join(\"\", str.ToSeq().TakeWhile((ch, index) => true)));\n    }\n        \n    [Fact]\n    public void GeneratingZeroGivesEmptySequence()\n    {\n        var actual = generate(0, _ => unit);\n        Assert.Equal(Seq<Unit>(), actual);\n    }\n\n    [Fact]\n    public void TakingOneAfterGeneratingZeroGivesEmptySequence()\n    {\n        var actual = generate(0, _ => unit).Take(1);\n        Assert.Equal(Seq<Unit>(), actual);\n    }\n\n    [Theory]\n    [InlineData(0, 1)]\n    [InlineData(1, 2)]\n    [InlineData(2, 3)]\n    [InlineData(3, 4)]\n    [InlineData(4, 5)]\n    [InlineData(5, 6)]\n    [InlineData(6, 7)]\n    [InlineData(7, 8)]\n    [InlineData(8, 9)]\n    [InlineData(9, 10)]\n    [InlineData(10, 20)]\n    [InlineData(100, 1000)]\n    [InlineData(1000, 10000)]\n    public void TakingNAfterGeneratingMoreThanNGivesLengthNSequence(int actualLength, int tryToTake)\n    {\n        var expect = toSeq(generate(actualLength, identity)).Strict();\n            \n        var actual = generate(actualLength, identity).Take(tryToTake);\n        Assert.Equal(expect, actual);\n    }\n        \n    [Fact]\n    public void SeqConcatTest()\n    {\n        var seq1 = (from x in new[] { 1 }.AsIterable()\n                    select x).ToSeq();\n\n        var seq2 = (from x in new[] { 2 }.AsIterable()\n                    select x).ToSeq();\n\n\n        var seq3 = (from x in new[] { 3 }.AsIterable()\n                    select x).ToSeq();\n\n        Assert.Equal(\n            Seq(1, 2, 3),\n            seq1\n               .Concat(seq2)\n               .Concat(seq3));\n    }\n\n    [Fact]\n    public void Concat_strict_and_strict_then_index_test()\n    {\n        var s1 = Seq(1, 2, 3);\n        var s2 = Seq(4, 5, 6);\n        var s3 = s1.Concat(s2);\n        Assert.Equal(1, s3[0]);\n        Assert.Equal(2, s3[1]);\n        Assert.Equal(3, s3[2]);\n        Assert.Equal(4, s3[3]);\n        Assert.Equal(5, s3[4]);\n        Assert.Equal(6, s3[5]);\n    }\n\n    [Fact]\n    public void Concat_lazy_and_strict_then_index_test_1()\n    {\n        var s1 = Range(1, 3).ToSeq();\n        var s2 = Seq(4, 5, 6);\n        var s3 = s1.Concat(s2);\n        Assert.Equal(1, s3[0]);\n        Assert.Equal(2, s3[1]);\n        Assert.Equal(3, s3[2]);\n        Assert.Equal(4, s3[3]);\n        Assert.Equal(5, s3[4]);\n        Assert.Equal(6, s3[5]);\n    }\n\n    [Fact]\n    public void Concat_lazy_and_strict_then_index_test_2()\n    {\n        var s1 = Range(1, 3).ToSeq();\n        var s2 = Seq(4, 5, 6);\n        var s3 = s1.Concat(s2);\n        Assert.Equal(6, s3[5]);\n        Assert.Equal(5, s3[4]);\n        Assert.Equal(4, s3[3]);\n        Assert.Equal(3, s3[2]);\n        Assert.Equal(2, s3[1]);\n        Assert.Equal(1, s3[0]);\n    }\n        \n    [Fact]\n    public void Concat_lazy_and_lazy_then_index_test_1()\n    {\n        var s1 = Range(1, 3).ToSeq();\n        var s2 = Range(4, 3).ToSeq();\n        var s3 = s1.Concat(s2);\n        Assert.Equal(1, s3[0]);\n        Assert.Equal(2, s3[1]);\n        Assert.Equal(3, s3[2]);\n        Assert.Equal(4, s3[3]);\n        Assert.Equal(5, s3[4]);\n        Assert.Equal(6, s3[5]);\n    }\n\n    [Fact]\n    public void Concat_lazy_and_lazy_then_index_test_2()\n    {\n        var s1 = Range(1, 3).ToSeq();\n        var s2 = Range(4, 3).ToSeq();\n        var s3 = s1.Concat(s2);\n        Assert.Equal(6, s3[5]);\n        Assert.Equal(5, s3[4]);\n        Assert.Equal(4, s3[3]);\n        Assert.Equal(3, s3[2]);\n        Assert.Equal(2, s3[1]);\n        Assert.Equal(1, s3[0]);\n    }\n\n    [Fact]\n    public void CheckItems()\n    {\n        var xs = Seq<int>();\n        Assert.True(xs.Count == 0);\n            \n        xs = Seq(0);\n        Assert.True(xs.Count == 1);\n        Assert.True(xs[0]    == 0);\n            \n        xs = Seq(0, 1);\n        Assert.True(xs.Count == 2);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n            \n        xs = Seq(0, 1, 2);\n        Assert.True(xs.Count == 3);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n            \n        xs = Seq(0, 1, 2, 3);\n        Assert.True(xs.Count == 4);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n            \n        xs = Seq(0, 1, 2, 3, 4);\n        Assert.True(xs.Count == 5);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n            \n        xs = Seq(0, 1, 2, 3, 4, 5);\n        Assert.True(xs.Count == 6);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n        Assert.True(xs[5]    == 5);\n            \n        xs = Seq(0, 1, 2, 3, 4, 5, 6);\n        Assert.True(xs.Count == 7);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n        Assert.True(xs[5]    == 5);\n        Assert.True(xs[6]    == 6);\n            \n        xs = Seq(0, 1, 2, 3, 4, 5, 6, 7);\n        Assert.True(xs.Count == 8);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n        Assert.True(xs[5]    == 5);\n        Assert.True(xs[6]    == 6);\n        Assert.True(xs[7]    == 7);\n            \n        xs = Seq(0, 1, 2, 3, 4, 5, 6, 7, 8);\n        Assert.True(xs.Count == 9);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n        Assert.True(xs[5]    == 5);\n        Assert.True(xs[6]    == 6);\n        Assert.True(xs[7]    == 7);\n        Assert.True(xs[8]    == 8);\n            \n        xs = Seq(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);\n        Assert.True(xs.Count == 10);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n        Assert.True(xs[5]    == 5);\n        Assert.True(xs[6]    == 6);\n        Assert.True(xs[7]    == 7);\n        Assert.True(xs[8]    == 8);\n        Assert.True(xs[9]    == 9);\n            \n        xs = Seq(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n        Assert.True(xs.Count == 11);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n        Assert.True(xs[5]    == 5);\n        Assert.True(xs[6]    == 6);\n        Assert.True(xs[7]    == 7);\n        Assert.True(xs[8]    == 8);\n        Assert.True(xs[9]    == 9);\n        Assert.True(xs[10]   == 10);\n            \n        xs = Seq(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);\n        Assert.True(xs.Count == 12);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n        Assert.True(xs[5]    == 5);\n        Assert.True(xs[6]    == 6);\n        Assert.True(xs[7]    == 7);\n        Assert.True(xs[8]    == 8);\n        Assert.True(xs[9]    == 9);\n        Assert.True(xs[10]   == 10);\n        Assert.True(xs[11]   == 11);\n            \n        xs = Seq(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);\n        Assert.True(xs.Count == 13);\n        Assert.True(xs[0]    == 0);\n        Assert.True(xs[1]    == 1);\n        Assert.True(xs[2]    == 2);\n        Assert.True(xs[3]    == 3);\n        Assert.True(xs[4]    == 4);\n        Assert.True(xs[5]    == 5);\n        Assert.True(xs[6]    == 6);\n        Assert.True(xs[7]    == 7);\n        Assert.True(xs[8]    == 8);\n        Assert.True(xs[9]    == 9);\n        Assert.True(xs[10]   == 10);\n        Assert.True(xs[11]   == 11);\n        Assert.True(xs[12]   == 12);\n    }\n\n    [Fact]\n    void SeqHashCodeRegression()\n    {\n        // GetHashCode is internally used to compare Seq values => has to be equal irrespective of creation method \n\n        var originalStrictTail = Seq(2, 3);\n        var lazyTailSeq        = Set(1, 2, 3).Tail().ToSeq();\n        var lazySeqTail        = Set(1, 2, 3).ToSeq().Tail;\n        var lazyPattern        = Set(1, 2, 3).Case is (int _, Seq<int> tail) ? tail : throw new (\"invalid\");\n            \n        Assert.Equal(originalStrictTail.GetHashCode(), lazyTailSeq.GetHashCode());\n        Assert.Equal(originalStrictTail, lazyTailSeq);\n        Assert.Equal(originalStrictTail.GetHashCode(), lazySeqTail.GetHashCode());\n        Assert.Equal(originalStrictTail, lazySeqTail);\n        Assert.Equal(originalStrictTail.GetHashCode(), lazyPattern.GetHashCode());\n        Assert.Equal(originalStrictTail, lazyPattern);\n    }\n        \n    [Fact]\n    public void SequenceParallelRandomDelayTest()\n    {\n        var input = Seq(1, 2, 3, 2, 5, 1, 1, 2, 3, 2, 1, 2, 4, 2, 1, 5, 6, 1, 3, 6, 2);\n\t\n        var ma = input.Select(DoDelay).Traverse(identity).As();\n\n        var res = from v in ma.Run().As()\n                  select v switch\n                         {\n                             Either<string, Seq<int>>.Right (var seq) => seq.SequenceEqual(input),\n                             _                                        => false\n                         };\n\n        Assert.True(res.Run());\n    }\n\n    static EitherT<string, IO, int> DoDelay(int seconds)\n    {\n        return liftIO(async () => await F(seconds));\n        static async ValueTask<Either<string, int>> F(int seconds)\n        {\n            await Task.Delay(seconds * 100);\n            return seconds;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SerialisationTests.cs",
    "content": "﻿using System;\nusing Xunit;\nusing Newtonsoft.Json;\nusing System.Runtime.Serialization;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests\n{\n    \n    public class SerialisationTests\n    {\n        [Fact]\n        public void SetTest()\n        {\n            var set = Set(\"test5\", \"test2\", \"test1\", \"test3\", \"test4\");\n\n            var json = JsonConvert.SerializeObject(set);\n\n            set = JsonConvert.DeserializeObject<Set<string>>(json);\n            var lst = JsonConvert.DeserializeObject<Lst<string>>(json);\n\n            Assert.True(set.Count == 5);\n            Assert.True(set.Contains(\"test1\"));\n            Assert.True(set.Contains(\"test2\"));\n            Assert.True(set.Contains(\"test3\"));\n            Assert.True(set.Contains(\"test4\"));\n            Assert.True(set.Contains(\"test5\"));\n        }\n\n        [Fact]\n        public void LstTest()\n        {\n            var list = List(\"test5\", \"test2\", \"test1\", \"test3\", \"test4\");\n\n            var json = JsonConvert.SerializeObject(list);\n\n            list = JsonConvert.DeserializeObject<Lst<string>>(json);\n\n            Assert.True(list.Count == 5);\n            Assert.True(list[0] == \"test5\");\n            Assert.True(list[1] == \"test2\");\n            Assert.True(list[2] == \"test1\");\n            Assert.True(list[3] == \"test3\");\n            Assert.True(list[4] == \"test4\");\n        }\n\n        [Fact]\n        public void SeqTest()\n        {\n            var seq = Seq(\"test5\", \"test2\", \"test1\", \"test3\", \"test4\");\n\n            var json = JsonConvert.SerializeObject(seq);\n\n            seq = JsonConvert.DeserializeObject<Seq<string>>(json);\n\n            Assert.True(seq.Count == 5);\n            Assert.True(seq[0] == \"test5\");\n            Assert.True(seq[1] == \"test2\");\n            Assert.True(seq[2] == \"test1\");\n            Assert.True(seq[3] == \"test3\");\n            Assert.True(seq[4] == \"test4\");\n        }\n\n        [Fact]\n        public void OptionTest()\n        {\n            var some = Some(\"test\");\n            var none = Option<string>.None;\n\n            var someText = JsonConvert.SerializeObject(some);\n            var noneText = JsonConvert.SerializeObject(none);\n\n            var some2 = JsonConvert.DeserializeObject<Option<string>>(someText);\n            var none2 = JsonConvert.DeserializeObject<Option<string>>(noneText);\n\n            Assert.True(some == some2);\n            Assert.True(none == none2);\n        }\n        \n        [Fact]\n        public void ActionTypeTest()\n        {\n            var x = new ActionType(\"Test1\");\n            var y = new ActionType(\"Test2\");\n            var z = new ActionType(\"Test3\");\n\n            Assert.False(x == y);\n            Assert.True(x != y);\n        }\n\n        [Serializable]\n        public record ActionType(string Value);\n\n        [Fact]\n        public void ErrorSerialisationTest()\n        {\n            var settings = new JsonSerializerSettings\n            {\n                TypeNameHandling = TypeNameHandling.Objects\n            };\n            var error = Error.New(\"Test\");\n            var json = JsonConvert.SerializeObject(error, settings);\n            var error1 = JsonConvert.DeserializeObject<Error>(json, settings);\n\n            Assert.True(error == error1);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/SetTests.cs",
    "content": "﻿using L = LanguageExt;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Map;\nusing Xunit;\nusing System;\nusing System.Linq;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests\n{\n    public class SetTests\n    {\n        [Fact]\n        public void SetKeyTypeTests()\n        {\n            var set = Set<OrdStringOrdinalIgnoreCase, string>(\"one\", \"two\", \"three\");\n\n            Assert.True(set.Contains(\"one\"));\n            Assert.True(set.Contains(\"ONE\"));\n\n            Assert.True(set.Contains(\"two\"));\n            Assert.True(set.Contains(\"Two\"));\n\n            Assert.True(set.Contains(\"three\"));\n            Assert.True(set.Contains(\"thREE\"));\n        }\n\n\n        [Fact]\n        public void EqualsTest()\n        {\n            var a = Set(1, 2);\n            var b = Set(1, 2, 3);\n\n            Assert.False(Set(1, 2, 3).Equals(Set<int>()));\n            Assert.False(Set<int>().Equals(Set(1, 2, 3)));\n            Assert.True(Set<int>().Equals(Set<int>()));\n            Assert.True(Set(1).Equals(Set(1)));\n            Assert.True(Set(1, 2).Equals(Set(1, 2)));\n            Assert.False(Set(1, 2).Equals(Set(1, 2, 3)));\n            Assert.False(Set(1, 2, 3).Equals(Set(1, 2)));\n        }\n\n        [Fact]\n        public void SetGeneratorTest()\n        {\n            var m1 = Set<int>();\n            m1 = m1.Add(100);\n            Assert.True(m1.Count == 1 && m1.Contains(100));\n        }\n\n        [Fact]\n        public void SetAddInOrderTest()\n        {\n            var m = Set(1);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n\n            m = Set(1, 2);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n\n            m = Set(1, 2, 3);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n\n            m = Set(1, 2, 3, 4);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n\n            m = Set(1, 2, 3, 4, 5);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n        }\n\n        [Fact]\n        public void SetAddInReverseOrderTest()\n        {\n            var m = Set(2, 1);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n\n            m = Set(3, 2, 1);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n\n            m = Set(4, 3, 2, 1);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n\n            m = Set(5, 4, 3, 2, 1);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n        }\n\n        [Fact]\n        public void MapAddInMixedOrderTest()\n        {\n            var m = Set(5, 1, 3, 2, 4);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n\n            m = Set(1, 3, 5, 2, 4);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(4).IfNone(() => failwith<int>(\"Broken\"));\n            m.Find(5).IfNone(() => failwith<int>(\"Broken\"));\n        }\n\n\n        [Fact]\n        public void SetRemoveTest()\n        {\n            var m = Set(1, 3, 5, 2, 4);\n\n            m.Find(1).IfNone(() => failwith<int>(\"Broken 1\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken 2\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken 3\"));\n            m.Find(4).IfNone(() => failwith<int>(\"Broken 4\"));\n            m.Find(5).IfNone(() => failwith<int>(\"Broken 5\"));\n\n            Assert.True(m.Count == 5);\n\n            m = m.Remove(4);\n            Assert.True(m.Count == 4);\n            Assert.True(m.Find(4).IsNone);\n            m.Find(1).IfNone(() => failwith<int>(\"Broken 1\"));\n            m.Find(2).IfNone(() => failwith<int>(\"Broken 2\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken 3\"));\n            m.Find(5).IfNone(() => failwith<int>(\"Broken 5\"));\n\n            m = m.Remove(1);\n            Assert.True(m.Count == 3);\n            Assert.True(m.Find(1).IsNone);\n            m.Find(2).IfNone(() => failwith<int>(\"Broken 2\"));\n            m.Find(3).IfNone(() => failwith<int>(\"Broken 3\"));\n            m.Find(5).IfNone(() => failwith<int>(\"Broken 5\"));\n\n            m = m.Remove(2);\n            Assert.True(m.Count == 2);\n            Assert.True(m.Find(2).IsNone);\n            m.Find(3).IfNone(() => failwith<int>(\"Broken 3\"));\n            m.Find(5).IfNone(() => failwith<int>(\"Broken 5\"));\n\n            m = m.Remove(3);\n            Assert.True(m.Count == 1);\n            Assert.True(m.Find(3).IsNone);\n            m.Find(5).IfNone(() => failwith<int>(\"Broken 5\"));\n\n            m = m.Remove(5);\n            Assert.True(m.Count == 0);\n            Assert.True(m.Find(5).IsNone);\n        }\n\n        [Fact]\n        public void MassAddRemoveTest()\n        {\n            int max = 100000;\n\n            var items = IterableExtensions.AsIterable(Range(1, max)).Map(_ => Guid.NewGuid()).ToLst();\n\n            var m = toSet(items);\n            Assert.True(m.Count == max);\n            foreach (var item in items)\n            {\n                Assert.True(m.Contains(item));\n                m = m.Remove(item);\n                Assert.False(m.Contains(item));\n                max--;\n                Assert.True(m.Count == max);\n            }\n        }\n        \n        [Fact]\n        public void SetOrdSumTest()\n        {\n            var m1 = Set<OrdStringOrdinalIgnoreCase, string>(\"one\", \"two\");\n            var m2 = Set<OrdStringOrdinalIgnoreCase, string>(\"three\");\n\n            var sum = m1 + m2;\n            \n            Assert.Equal(sum, m1.AddRange(m2));\n            Assert.Equal(m2, sum.Clear() + m2);\n        }\n\n        [Fact]\n        public void SetUnionTest1()\n        {\n            var x = Set((1, 1), (2, 2), (3, 3));\n            var y = Set((1, 1), (2, 2), (3, 3));\n\n            var z = Set.union(x, y);\n\n            Assert.True(z == Set((1, 1), (2, 2), (3, 3)));\n        }\n\n        [Fact]\n        public void SetUnionTest2()\n        {\n            var x = Set((1, 1), (2, 2), (3, 3));\n            var y = Set((4, 4), (5, 5), (6, 6));\n\n            var z = Set.union(x, y);\n\n            Assert.True(z == Set((1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)));\n        }\n\n        [Fact]\n        public void SetIntesectTest1()\n        {\n            var x = Set((2, 2), (3, 3));\n            var y = Set((1, 1), (2, 2));\n\n            var z = Set.intersect(x, y);\n\n            Assert.True(z == Set((2, 2)));\n        }\n\n        [Fact]\n        public void SetExceptTest()\n        {\n            var x = Set((1, 1), (2, 2), (3, 3));\n            var y = Set((1, 1));\n\n            var z = Set.except(x, y);\n\n            Assert.True(z == Set((2, 2), (3, 3)));\n        }\n\n        [Fact]\n        public void SetSymmetricExceptTest()\n        {\n            var x = Set((1, 1), (2, 2), (3, 3));\n            var y = Set((1, 1), (3, 3));\n\n            var z = Set.symmetricExcept(x, y);\n\n            Assert.True(z == Set((2, 2)));\n        }\n\n\n        [Fact]\n        public void SliceTest()\n        {\n            var m = Set(1, 2, 3, 4, 5);\n\n            var x = m.Slice(1, 2);\n\n            Assert.True(x.Count == 2);\n            Assert.True(x.Contains(1));\n            Assert.True(x.Contains(2));\n\n            var y = m.Slice(2, 4);\n\n            Assert.True(y.Count == 3);\n            Assert.True(y.Contains(2));\n            Assert.True(y.Contains(3));\n            Assert.True(y.Contains(4));\n\n            var z = m.Slice(4, 5);\n\n            Assert.True(z.Count == 2);\n            Assert.True(z.Contains(4));\n            Assert.True(z.Contains(5));\n        }\n\n        [Fact]\n        public void MinMaxTest()\n        {\n            var m = Set(1, 2, 3, 4, 5);\n\n            Assert.True(m.Min == 1);\n            Assert.True(m.Max == 5);\n\n            var me = Set<int>();\n\n            Assert.True(me.Min == None);\n            Assert.True(me.Max == None);\n        }\n\n        [Fact]\n        public void FindPredecessorWhenKeyExistsTest()\n        {\n            var m = Set(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);\n\n            Assert.True(m.FindPredecessor(1) == None);\n            Assert.True(m.FindPredecessor(2) == 1);\n            Assert.True(m.FindPredecessor(3) == 2);\n            Assert.True(m.FindPredecessor(4) == 3);\n            Assert.True(m.FindPredecessor(5) == 4);\n            Assert.True(m.FindPredecessor(6) == 5);\n            Assert.True(m.FindPredecessor(7) == 6);\n            Assert.True(m.FindPredecessor(8) == 7);\n            Assert.True(m.FindPredecessor(9) == 8);\n            Assert.True(m.FindPredecessor(10) == 9);\n            Assert.True(m.FindPredecessor(11) == 10);\n            Assert.True(m.FindPredecessor(12) == 11);\n            Assert.True(m.FindPredecessor(13) == 12);\n            Assert.True(m.FindPredecessor(14) == 13);\n            Assert.True(m.FindPredecessor(15) == 14);\n        }\n\n        [Fact]\n        public void FindPredecessorWhenKeyNotExistsTest()\n        {\n            var m = Set(1, 3, 5, 7, 9, 11, 13, 15);\n\n            Assert.True(m.FindPredecessor(1) == None);\n            Assert.True(m.FindPredecessor(2) == 1);\n            Assert.True(m.FindPredecessor(3) == 1);\n            Assert.True(m.FindPredecessor(4) == 3);\n            Assert.True(m.FindPredecessor(5) == 3);\n            Assert.True(m.FindPredecessor(6) == 5);\n            Assert.True(m.FindPredecessor(7) == 5);\n            Assert.True(m.FindPredecessor(8) == 7);\n            Assert.True(m.FindPredecessor(9) == 7);\n            Assert.True(m.FindPredecessor(10) == 9);\n            Assert.True(m.FindPredecessor(11) == 9);\n            Assert.True(m.FindPredecessor(12) == 11);\n            Assert.True(m.FindPredecessor(13) == 11);\n            Assert.True(m.FindPredecessor(14) == 13);\n            Assert.True(m.FindPredecessor(15) == 13);\n        }\n\n        [Fact]\n        public void FindExactOrPredecessorWhenKeyExistsTest()\n        {\n            var m = Set(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);\n\n            Assert.True(m.FindExactOrPredecessor(1) == 1);\n            Assert.True(m.FindExactOrPredecessor(2) == 2);\n            Assert.True(m.FindExactOrPredecessor(3) == 3);\n            Assert.True(m.FindExactOrPredecessor(4) == 4);\n            Assert.True(m.FindExactOrPredecessor(5) == 5);\n            Assert.True(m.FindExactOrPredecessor(6) == 6);\n            Assert.True(m.FindExactOrPredecessor(7) == 7);\n            Assert.True(m.FindExactOrPredecessor(8) == 8);\n            Assert.True(m.FindExactOrPredecessor(9) == 9);\n            Assert.True(m.FindExactOrPredecessor(10) == 10);\n            Assert.True(m.FindExactOrPredecessor(11) == 11);\n            Assert.True(m.FindExactOrPredecessor(12) == 12);\n            Assert.True(m.FindExactOrPredecessor(13) == 13);\n            Assert.True(m.FindExactOrPredecessor(14) == 14);\n            Assert.True(m.FindExactOrPredecessor(15) == 15);\n        }\n\n        [Fact]\n        public void FindExactOrPredecessorWhenKeySometimesExistsTest()\n        {\n            var m = Set(1, 3, 5, 7, 9, 11, 13, 15);\n\n            Assert.True(m.FindExactOrPredecessor(1) == 1);\n            Assert.True(m.FindExactOrPredecessor(2) == 1);\n            Assert.True(m.FindExactOrPredecessor(3) == 3);\n            Assert.True(m.FindExactOrPredecessor(4) == 3);\n            Assert.True(m.FindExactOrPredecessor(5) == 5);\n            Assert.True(m.FindExactOrPredecessor(6) == 5);\n            Assert.True(m.FindExactOrPredecessor(7) == 7);\n            Assert.True(m.FindExactOrPredecessor(8) == 7);\n            Assert.True(m.FindExactOrPredecessor(9) == 9);\n            Assert.True(m.FindExactOrPredecessor(10) == 9);\n            Assert.True(m.FindExactOrPredecessor(11) == 11);\n            Assert.True(m.FindExactOrPredecessor(12) == 11);\n            Assert.True(m.FindExactOrPredecessor(13) == 13);\n            Assert.True(m.FindExactOrPredecessor(14) == 13);\n            Assert.True(m.FindExactOrPredecessor(15) == 15);\n        }\n\n        [Fact]\n        public void FindSuccessorWhenKeyExistsTest()\n        {\n            var m = Set(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);\n\n            Assert.True(m.FindSuccessor(1) == 2);\n            Assert.True(m.FindSuccessor(2) == 3);\n            Assert.True(m.FindSuccessor(3) == 4);\n            Assert.True(m.FindSuccessor(4) == 5);\n            Assert.True(m.FindSuccessor(5) == 6);\n            Assert.True(m.FindSuccessor(6) == 7);\n            Assert.True(m.FindSuccessor(7) == 8);\n            Assert.True(m.FindSuccessor(8) == 9);\n            Assert.True(m.FindSuccessor(9) == 10);\n            Assert.True(m.FindSuccessor(10) == 11);\n            Assert.True(m.FindSuccessor(11) == 12);\n            Assert.True(m.FindSuccessor(12) == 13);\n            Assert.True(m.FindSuccessor(13) == 14);\n            Assert.True(m.FindSuccessor(14) == 15);\n            Assert.True(m.FindSuccessor(15) == None);\n        }\n\n        [Fact]\n        public void FindSuccessorWhenKeyNotExistsTest()\n        {\n            var m = Set(1, 3, 5, 7, 9, 11, 13, 15);\n\n            Assert.True(m.FindSuccessor(1) == 3);\n            Assert.True(m.FindSuccessor(2) == 3);\n            Assert.True(m.FindSuccessor(3) == 5);\n            Assert.True(m.FindSuccessor(4) == 5);\n            Assert.True(m.FindSuccessor(5) == 7);\n            Assert.True(m.FindSuccessor(6) == 7);\n            Assert.True(m.FindSuccessor(7) == 9);\n            Assert.True(m.FindSuccessor(8) == 9);\n            Assert.True(m.FindSuccessor(9) == 11);\n            Assert.True(m.FindSuccessor(10) == 11);\n            Assert.True(m.FindSuccessor(11) == 13);\n            Assert.True(m.FindSuccessor(12) == 13);\n            Assert.True(m.FindSuccessor(13) == 15);\n            Assert.True(m.FindSuccessor(14) == 15);\n            Assert.True(m.FindSuccessor(15) == None);\n        }\n\n        [Fact]\n        public void FindExactOrSuccessorWhenKeyExistsTest()\n        {\n            var m = Set(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);\n\n            Assert.True(m.FindExactOrSuccessor(1) == 1);\n            Assert.True(m.FindExactOrSuccessor(2) == 2);\n            Assert.True(m.FindExactOrSuccessor(3) == 3);\n            Assert.True(m.FindExactOrSuccessor(4) == 4);\n            Assert.True(m.FindExactOrSuccessor(5) == 5);\n            Assert.True(m.FindExactOrSuccessor(6) == 6);\n            Assert.True(m.FindExactOrSuccessor(7) == 7);\n            Assert.True(m.FindExactOrSuccessor(8) == 8);\n            Assert.True(m.FindExactOrSuccessor(9) == 9);\n            Assert.True(m.FindExactOrSuccessor(10) == 10);\n            Assert.True(m.FindExactOrSuccessor(11) == 11);\n            Assert.True(m.FindExactOrSuccessor(12) == 12);\n            Assert.True(m.FindExactOrSuccessor(13) == 13);\n            Assert.True(m.FindExactOrSuccessor(14) == 14);\n            Assert.True(m.FindExactOrSuccessor(15) == 15);\n        }\n\n        [Fact]\n        public void FindExactOrSuccessorWhenKeySometimesExistsTest()\n        {\n            var m = Set(1, 3, 5, 7, 9, 11, 13, 15);\n\n            Assert.True(m.FindExactOrSuccessor(1) == 1);\n            Assert.True(m.FindExactOrSuccessor(2) == 3);\n            Assert.True(m.FindExactOrSuccessor(3) == 3);\n            Assert.True(m.FindExactOrSuccessor(4) == 5);\n            Assert.True(m.FindExactOrSuccessor(5) == 5);\n            Assert.True(m.FindExactOrSuccessor(6) == 7);\n            Assert.True(m.FindExactOrSuccessor(7) == 7);\n            Assert.True(m.FindExactOrSuccessor(8) == 9);\n            Assert.True(m.FindExactOrSuccessor(9) == 9);\n            Assert.True(m.FindExactOrSuccessor(10) == 11);\n            Assert.True(m.FindExactOrSuccessor(11) == 11);\n            Assert.True(m.FindExactOrSuccessor(12) == 13);\n            Assert.True(m.FindExactOrSuccessor(13) == 13);\n            Assert.True(m.FindExactOrSuccessor(14) == 15);\n            Assert.True(m.FindExactOrSuccessor(15) == 15);\n        }\n\n        [Fact]\n        public void CaseTest()\n        {\n            // seq1 tests here just for reference\n            { Assert.True(Seq<int>().Case is not var (_, _) and not {} ); }\n            { Assert.True(Seq1<int>(1).Case is not var (_, _) and 1); }\n            { Assert.True(Seq<int>(1, 2).Case is (1, Seq<int> xs) && xs == Seq1(2)); }\n\n            { Assert.True(Set<int>().Case is not var (_, _) and not {} ); }\n            { Assert.True(Set<int>(1).Case is not var (_, _) and 1); }\n            { Assert.True(Set<int>(1, 2).Case is (1, Seq<int> xs) && xs == Seq1(2)); }\n\n            { Assert.True(Set<OrdInt, int>().Case is not var (_, _) and not {} ); }\n            { Assert.True(Set<OrdInt, int>(1).Case is not var (_, _) and 1); }\n            { Assert.True(Set<OrdInt, int>(1, 2).Case is (1, Seq<int> xs) && xs == Seq1(2)); }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/StackTests.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing static LanguageExt.List;\nusing static LanguageExt.Stack;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    \n    public class StackTests\n    {\n        [Fact]\n        public void EmptyStackPeek()\n        {\n            var test = Stack<int>();\n            var res = trypeek(test);\n\n            Assert.True(res.IsNone);\n        }\n\n        [Fact]\n        public void EmptyStackPop()\n        {\n            var test = Stack<int>();\n            var res = map(trypop(test), (stack, value) => value);\n\n            Assert.True(res.IsNone);\n        }\n\n        [Fact]\n        public void Popping1()\n        {\n            var test = Stack(1, 2, 3, 4, 5);\n            Popping5(test);\n        }\n\n        [Fact]\n        public void Popping2()\n        {\n            var test = Stack<int>();\n\n            test = push(test, 1);\n            test = push(test, 2);\n            test = push(test, 3);\n            test = push(test, 4);\n            test = push(test, 5);\n\n            Popping5(test);\n        }\n\n        void Popping5(Stck<int> test)\n        {\n            test = map(trypop(test), (stack, value) => { Assert.True(value.IsSome); return stack; });\n            test = map(trypop(test), (stack, value) => { Assert.True(value.IsSome); return stack; });\n            test = map(trypop(test), (stack, value) => { Assert.True(value.IsSome); return stack; });\n            test = map(trypop(test), (stack, value) => { Assert.True(value.IsSome); return stack; });\n            peek(test,\n                Some: v => Assert.True(v == 1),\n                None: () => Assert.False(true)\n            );\n        }\n\n        [Fact]\n        public void CollectionFunctions()\n        {\n            var stack = toStack(Range(1,100));\n\n            Assert.True(exists(stack, v => v == 50));\n            Assert.True(length(stack) == 100);\n            Assert.True(length(takeWhile(stack, v => v != 10)) == 90);\n            Assert.True(length(take(stack, 10)) == 10);\n            Assert.True(head(take(stack, 1)) == 100);\n        }\n\n        [Fact]\n        public void RecursiveSumTest()\n        {\n            var values = toStack(Range(1, 10));\n\n            var res = Sum(values);\n\n            Assert.True(res == sum(values));\n        }\n\n        public int Sum(Stck<int> stack) =>\n            pop(stack, \n                Some: (newstack, value) => value + Sum(newstack),\n                None: ()                => 0\n                );\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Streaming/Source.Tests.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt.Tests.Streaming;\n\npublic class SourceTests\n{\n    [Fact]\n    public void Empty_source_should_not_produce_values()\n    {\n        // Arrange\n        var source = Source.empty<int>();\n        var value  = source.FoldReduce(0, (s, _) => s + 1).Run();\n        Assert.Equal(0, value);\n    }\n    \n    [Fact]\n    public void Pure_source_should_produce_single_value()\n    {\n        // Arrange\n        var value  = 42;\n        var source = Source.pure(value);\n        var output = source.Collect().Run();\n\n        // Act and Assert\n        Assert.True(output == [42]);\n    }\n\n    [Fact]\n    public void Map_should_transform_values()\n    {\n        // Arrange\n        var source = Source.pure(42).Map(x => x * 2);\n        var output = source.Collect().Run();\n\n        // Act and Assert\n        Assert.True(output == [84]);\n    }\n    \n    [Fact]\n    public void Where_should_filter_values()\n    {\n        // Arrange\n        var source = Source.pure(42).Where(x => x > 50);\n        var output = source.Collect().Run();\n\n        // Act and Assert\n        Assert.True(output == []);\n    }\n\n    [Fact]\n    public void Add_should_concatenate_sources()\n    {\n        // Arrange\n        var source1 = Source.pure(1);\n        var source2 = Source.pure(2);\n\n        // Act\n        var concat = source1 + source2;\n        var output = concat.Collect().Run();\n\n        // Assert\n        Assert.Equal(2, output.Count);\n        Assert.True(output == [1, 2]);\n    }\n    \n    [Fact]\n    public void Zip_should_combine_two_sources()\n    {\n        // Arrange\n        var source1 = Source.pure(1);\n        var source2 = Source.pure(\"A\");\n\n        // Act\n        var zipped = source1.Zip(source2);\n        var output = zipped.Collect().Run();\n\n        // Assert\n        Assert.True(output == [(1, \"A\")]);\n    }\n    \n    [Fact]\n    public void Or_operator_should_merge_two_sources()\n    {\n        // Arrange\n        var source1 = Source.lift([1, 2, 3]);\n        var source2 = Source.lift([10, 20, 30]);\n\n        // Act\n        var merged = source1 | source2;\n        var output = merged.Collect().Run();\n\n        // Assert that the output has 3 items lower than 10\n        Assert.True(output.Filter(x => x < 10).Count  == 3);\n\n        // Assert that the output has 3 items greater than 10\n        Assert.True(output.Filter(x => x >= 10).Count == 3);\n\n        // Assert that the output has the lower items in-order\n        Assert.True(output.Filter(x => x < 10)        == [1, 2, 3]);\n        \n        // Assert that the output has the upper items in-order\n        Assert.True(output.Filter(x => x >= 10)       == [10, 20, 30]);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Tests/Streaming/SourceT.Tests.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt.Tests.Streaming;\n\npublic class SourceTTests\n{\n    [Fact]\n    public void Empty_source_should_not_produce_values()\n    {\n        // Arrange\n        var source = SourceT.empty<IO, int>();\n        var value  = source.FoldReduce(0, (s, _) => s + 1).Run();\n        Assert.Equal(0, value);\n    }\n    \n    [Fact]\n    public void Pure_source_should_produce_single_value()\n    {\n        // Arrange\n        var value  = 42;\n        var source = SourceT.pure<IO, int>(value);\n        var output = source.Collect().Run();\n\n        // Act and Assert\n        Assert.True(output == [42]);\n    }\n\n    [Fact]\n    public void Map_should_transform_values()\n    {\n        // Arrange\n        var source = SourceT.pure<IO, int>(42).Map(x => x * 2);\n        var output = source.Collect().Run();\n\n        // Act and Assert\n        Assert.True(output == [84]);\n    }\n    \n    [Fact]\n    public void Where_should_filter_values()\n    {\n        // Arrange\n        var source = SourceT.pure<IO, int>(42).Where(x => x > 50);\n        var output = source.Collect().Run();\n\n        // Act and Assert\n        Assert.True(output == []);\n    }\n\n    [Fact]\n    public void Add_should_concatenate_sources()\n    {\n        // Arrange\n        var source1 = SourceT.pure<IO, int>(1);\n        var source2 = SourceT.pure<IO, int>(2);\n\n        // Act\n        var concat = source1 + source2;\n        var output = concat.Collect().Run();\n\n        // Assert\n        Assert.Equal(2, output.Count);\n        Assert.True(output == [1, 2]);\n    }\n    \n    [Fact]\n    public void Zip_should_combine_two_sources()\n    {\n        // Arrange\n        var source1 = SourceT.pure<IO, int>(1);\n        var source2 = SourceT.pure<IO, string>(\"A\");\n\n        // Act\n        var zipped = source1.Zip(source2);\n        var output = zipped.Collect().Run();\n\n        // Assert\n        Assert.True(output == [(1, \"A\")]);\n    }\n    \n    [Fact]\n    public void Or_operator_should_merge_two_sources()\n    {\n        // Arrange\n        var source1 = SourceT.lift<IO, int>([1, 2, 3]);\n        var source2 = SourceT.lift<IO, int>([10, 20, 30]);\n\n        // Act\n        var merged = source1 | source2;\n        var output = merged.Collect().Run();\n\n        // Assert that the output has 3 items lower than 10\n        Assert.True(output.Filter(x => x < 10).Count  == 3);\n\n        // Assert that the output has 3 items greater than 10\n        Assert.True(output.Filter(x => x >= 10).Count == 3);\n\n        // Assert that the output has the lower items in-order\n        Assert.True(output.Filter(x => x < 10)        == [1, 2, 3]);\n        \n        // Assert that the output has the upper items in-order\n        Assert.True(output.Filter(x => x >= 10)       == [10, 20, 30]);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Tests/Sys/Diag/ActivityTests.cs",
    "content": "﻿using Xunit;\nusing System;\nusing System.Threading.Tasks;\nusing LanguageExt.Sys.Diag;\nusing LanguageExt.Sys.Test;\nusing System.Diagnostics;\nusing FluentAssertions;\nusing LanguageExt.Common;\nusing LanguageExt.UnsafeValueAccess;\n\nnamespace LanguageExt.Tests.Sys.Diag;\n\nusing A = Activity<Runtime>;\n\npublic static class ActivityTests\n{\n    static readonly ActivitySource Source = new(nameof(ActivityTests));\n    \n    static ActivityTests() =>\n        ActivitySource.AddActivityListener(\n            new ActivityListener\n            {\n                ShouldListenTo = source => source.Name == nameof(ActivityTests),\n                Sample = (ref ActivityCreationOptions<ActivityContext> _) =>\n                             ActivitySamplingResult.AllData\n            });\n\n    static T ArrangeAndAct<T>(this K<Eff<Runtime>, T> effect)\n    {\n        using var rt = Runtime.New();\n        var rt1 = rt with { Env = rt.Env with { Activity = new ActivityEnv(Source, default, default) } };\n        return effect.As().Run(rt1, EnvIO.New()).ThrowIfFail();\n    }\n\n    [Fact(DisplayName = \"An activity span can be created and effect run within\")]\n    public static void Case1() =>\n        A.span(\"test\", SuccessEff<Runtime, string>(\"a\")).ArrangeAndAct().Should().Be(\"a\");\n\n    [Fact(DisplayName = \"The trace state can be read\")]\n    public static void Case2()\n    {\n        var result = A.span(\"test\", from _ in A.setTraceState(\"test\") from r in A.traceState select r)\n            .ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n        result.Case.Should().Be(\"test\");\n    }\n\n    [Fact(DisplayName = \"The trace id state can be read\")]\n    public static void Case3()\n    {\n        var result = A.span(\"test\", A.traceId)\n            .ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n        result.Case.Should().NotBeNull();\n    }\n\n    [Fact(DisplayName = \"The baggage can be set and read\")]\n    public static void Case4()\n    {\n        var baggage = A.span(\n                \"test\",\n                from _ in A.addBaggage(\"a\", \"b\")\n                from result in A.baggage\n                select result\n            )\n            .ArrangeAndAct();\n        \n        Assert.True(baggage.Find(\"a\").ForAll(v => v == \"b\"));\n    }\n\n    [Fact(DisplayName = \"The tags can be set and read\")]\n    public static void Case5()\n    {\n        var baggage = A.span(\n                \"test\",\n                from _1 in A.addTag(\"a\", \"b\")\n                from result in A.tags\n                select result)\n            .ArrangeAndAct();\n        \n        Assert.True(baggage.Find(\"a\").ForAll(v => v == \"b\"));\n    }\n\n    [Fact(DisplayName = \"The tag objects can be read\")]\n    public static void Case6()\n    {\n        var baggage = A.span(\n                \"test\",\n                from _ in A.addTag(\"a\", 1)\n                from result in A.tagObjects\n                select result)\n            .ArrangeAndAct();\n        \n        Assert.True(baggage.Find(\"a\").ForAll(v => v is 1));\n    }\n\n    [Fact(DisplayName = \"The context can be read\")]\n    public static void Case7()\n    {\n        var result = A.span(\"test\", A.context).ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The duration can be read\")]\n    public static void Case8()\n    {\n        var result = A.span(\"test\", A.duration).ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    static readonly ActivityEvent TestEvent = new(\"some event\");\n\n    [Fact(DisplayName = \"The events can be read\")]\n    public static void Case9()\n    {\n        var events = A.span(\"test\", from _ in A.addEvent(TestEvent) from result in A.events select result)\n            .ArrangeAndAct();\n        Assert.False(events.IsEmpty);\n        events.AsIterable().Head.ValueUnsafe().Should().Be(TestEvent);\n    }\n\n    [Fact(DisplayName = \"The id can be read\")]\n    public static void Case10()\n    {\n        var result = A.span(\"test\", A.id).ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The kind can be read\")]\n    public static void Case11()\n    {\n        var result = A.span(\"test\", ActivityKind.Consumer, A.kind)\n            .ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n        result.Case.Should().Be(ActivityKind.Consumer);\n    }\n\n    [Fact(DisplayName = \"The links can be read\")]\n    public static void Case12()\n    {\n        var r = A.span(\n                \"a\",\n                from co in A.context.As()\n                from context in co.ToEff((Error)\"context should be set\")\n                from result in A.span(\n                    \"b\",\n                    ActivityKind.Consumer,\n                    context,\n                    default,\n                    Seq(new ActivityLink(context)),\n                    DateTimeOffset.Now,\n                    A.links\n                )\n                select result\n            )\n            .ArrangeAndAct();\n        Assert.False(r.IsEmpty);\n    }\n\n    [Fact(DisplayName = \"The current can be read and is not None in a span\")]\n    public static void Case13()\n    {\n        var result = A.span(\"test\", A.current).ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The current can be read and is None outside a span\")]\n    public static void Case14()\n    {\n        var result = A.current.ArrangeAndAct();\n        result.IsNone.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The parent id can be read and is not None in a nested span\")]\n    public static void Case15()\n    {\n        var id = A.span(\n                \"a\",\n                from co in A.context.As()\n                from context in co.ToEff((Error)\"context should be set\")\n                from result in A.span(\n                    \"b\",\n                    ActivityKind.Client,\n                    context,\n                    default,\n                    default,\n                    default,\n                    A.parentId\n                )\n                select result\n            )\n            .ArrangeAndAct();\n        id.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The parent id can be read and is None in a single level span\")]\n    public static void Case16()\n    {\n        var id = A.span(\"a\", A.parentId).ArrangeAndAct();\n        id.IsNone.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The parent span id can be read and is not None in a nested span\")]\n    public static void Case17()\n    {\n        var id = A.span(\n                \"a\",\n                from co in A.context.As()\n                from context in co.ToEff((Error)\"context should be set\")\n                from result in A.span(\n                    \"b\",\n                    ActivityKind.Client,\n                    context,\n                    default,\n                    default,\n                    default,\n                    A.parentSpanId\n                )\n                select result\n            )\n            .ArrangeAndAct();\n        id.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The recorded can be read\")]\n    public static void Case18()\n    {\n        var result = A.span(\"test\", A.recorded).ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The display name can be read\")]\n    public static void Case19()\n    {\n        var result = A.span(\"test\", A.displayName).ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The operation name can be read\")]\n    public static void Case20()\n    {\n        var result = A.span(\"test\", A.operationName)\n            .ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The root id can be read\")]\n    public static void Case21()\n    {\n        var result = A.span(\"test\", A.rootId).ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The span id can be read\")]\n    public static void Case22()\n    {\n        var result = A.span(\"test\", A.spanId).ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"The state time can be read\")]\n    public static void Case23()\n    {\n        var result = A.span(\"test\", A.startTimeUTC)\n            .ArrangeAndAct();\n        result.IsSome.Should().BeTrue();\n    }\n\n    [Fact(DisplayName = \"Test span overload 1\")]\n    public static void Case24()\n    {\n        var (kind, tags) = A.span(\n                \"test\",\n                ActivityKind.Client,\n                HashMap((\"1\", \"a\" as object), (\"2\", \"b\")),\n                A.kind.Zip(A.tags))\n            .ArrangeAndAct();\n        kind.IsSome.Should().BeTrue();\n        kind.Case.Should().Be(ActivityKind.Client);\n        \n        Assert.True(tags.Find(\"1\").ForAll(v => v is \"a\"));\n        Assert.True(tags.Find(\"2\").ForAll(v => v is \"b\"));\n    }\n\n    [Fact(DisplayName = \"Test span overload 2\")]\n    public static void Case25() =>\n        A.span(\"test\", SuccessEff<Runtime, Unit>(unit)).ArrangeAndAct();\n\n    [Fact(DisplayName = \"Test span overload 3\")]\n    public static void Case26()\n    {\n        var result = A.span(\"test\", ActivityKind.Consumer, A.kind.As()).ArrangeAndAct();\n        result.Case.Should().Be(ActivityKind.Consumer);\n    }\n\n    [Fact(DisplayName = \"Test span overload 4\")]\n    public static void Case27()\n    {\n        var (kind, tags) = A.span(\"test\",\n                                  ActivityKind.Client,\n                                  HashMap((\"1\", \"a\" as object), (\"2\", \"b\")),\n                                  A.kind.Zip(A.tags))\n                            .ArrangeAndAct();\n        \n        Assert.True(kind.IsSome);\n        Assert.Equal(ActivityKind.Client, kind.Case);\n       \n        Assert.True(tags.Find(\"1\").ForAll(v => v is \"a\"));\n        Assert.True(tags.Find(\"2\").ForAll(v => v is \"b\"));\n    }\n\n    [Fact(DisplayName = \"Test span overload 5\")]\n    public static void Case28()\n    {\n        var (kind, tags) = A.span(\n                \"A\",\n                from co in A.context.As()\n                from context in co.ToEff((Error)\"context should be set\")\n                from result in A.span(\n                    \"B\",\n                    ActivityKind.Client,\n                    context,\n                    HashMap((\"1\", \"a\" as object), (\"2\", \"b\")),\n                    Seq<ActivityLink>.Empty,\n                    DateTimeOffset.Now,\n                    A.kind.Zip(A.tags))\n                select result\n            )\n            .ArrangeAndAct();\n        kind.IsSome.Should().BeTrue();\n        kind.Case.Should().Be(ActivityKind.Client);\n        \n        Assert.True(tags.Find(\"1\").ForAll(v => v is \"a\"));\n        Assert.True(tags.Find(\"2\").ForAll(v => v is \"b\"));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Sys/IO/DirectoryTests.cs",
    "content": "using System.IO;\nusing System.Threading.Tasks;\nusing LanguageExt.Sys.IO;\nusing Xunit;\nusing Runtime = LanguageExt.Sys.Test.Runtime;\n\nnamespace LanguageExt.Tests.Sys.IO;\n\npublic class DirectoryTests\n{\n    [Fact]\n    public async Task EnumerateFilesTest()\n    {\n        using var rt = Runtime.New();\n        var path     = Path.Combine(Path.GetTempPath(), \"subdir\");\n        var expected = Path.Combine(path, \"file\");\n        \n        var computation =\n            from dir   in Directory<Runtime>.create(path)\n            from file  in File<Runtime>.writeAllText(expected, string.Empty)\n            from files in Directory<Runtime>.enumerateFiles(path)\n            select files;\n\n        var actual = (await computation.RunAsync(rt)).ThrowIfFail();\n\n        Assert.True(actual == Seq(expected));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/TESTING.cs",
    "content": "// TODO: Delete this or turn it into some real tests\n\nusing System;\nusing System.IO;\nusing System.Threading.Tasks;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static class Testing\n{\n    public static void Test1()\n    {\n        var m1 = ReaderT<string>.lift(Some(123));\n        var m2 = ReaderT<string>.lift(Some(123));\n        var mt = ReaderT<string>.lift(Some(unit));\n                \n        var m0 = from w in Pure(123)\n                 from x in m1\n                 from _ in unless(true, mt)\n                 from y in m2\n                 from z in asks((string env) => env.Length)\n                 from e in ask<string>()\n                 from n in ReaderT<string, Option, string>.Lift(Some(\"Paul\"))\n                 select $\"{e} {n}: {w + x + y + z}\";\n\n        var m3 = from w in Pure(123)\n                 from x in m1\n                 from y in m2\n                 from z in Some(100)\n                 from e in ask<string>()\n                 select $\"{e}: {w + x + y + z}\";\n\n        var r1 = m3.As().Run(\"Hello\");\n        \n        var m4 = from x in m1\n                 from y in m2\n                 from e in ask<string>()\n                 select $\"{e}: {x + y}\";\n\n        var r2 = m4.As().Run(\"Hello\").As();\n    }\n    \n    public static void Test2()\n    {\n        var m1 = Reader<string, int>.Pure(123);\n        var m2 = Reader<string, int>.Pure(123);\n        \n        var m3 = from x in m1\n                 from y in m2\n                 from e in ask<string>()\n                 select $\"{e}: {x + y}\";\n        \n        var m4 = from x in m1\n                 from y in m2\n                 from e in ask<string>()\n                 from z in Pure(234)\n                 select $\"{e}: {x + y}\";\n    }\n    \n    public static void Test3()\n    {\n        var m1 = ReaderT<string>.lift(Right<string, int>(123));\n        var m2 = ReaderT<string>.lift(Right<string, int>(123));\n        \n        var m3 = from w in Pure(123)\n                 from x in m1\n                 from y in m2\n                 from z in Right(100)\n                 from e in ask<string>()\n                 select $\"{e}: {w + x + y + z}\";\n\n        var r1 = m3.Run(\"Hello\");\n        \n        var m4 = from x in m1\n                 from y in m2\n                 from z in Left<string, int>(\"fail\")\n                 from e in ask<string>()\n                 select $\"{e}: {x + y + z}\";\n\n        var r2 = m4.Run(\"Hello\");        \n    }\n    \n    \n    public static void Test4()\n    {\n        var m1 = App.Pure(123);\n        var m2 = App.Pure(123);\n        var m3 = App.Fail<int>(Error.New(\"fail\"));\n        \n        var m4 = from w in Pure(234)\n                 from x in m1\n                 from y in m2\n                 from z in m3\n                 from r in App.rootFolder\n                 from t in liftIO(async () => await File.ReadAllTextAsync($\"{r}\\\\test.txt\"))\n                 select $\"{t}: {w + x + y + z}\";\n\n        var r1 = m4.Run(new AppConfig(\"\", \"\")).As();\n    }\n   \n    public static void Test6()\n    {\n        var m1 = ReaderT<string>.lift(IdentityT.lift(IO.pure(123)));\n        var m2 = ReaderT<string>.lift(IdentityT.lift(IO.pure(123)));\n                \n        var m0 = from w in Pure(123)\n                 from p in ReaderT.ask<IdentityT<IO>, string>()\n                 from x in IO.pure(\"Hello\")\n                 from i in ReaderT<string, IdentityT<IO>>.liftIO(IO.pure(\"Hello\"))\n                 from j in IO.pure(\"Hello\").Fork()\n                 from r in envIO \n                 from y in m2\n                 select $\"{p} {y} {j}\";\n\n        var value = m0.Run(\"Hello\").As().Value.As().Run(EnvIO.New());\n    }\n   \n    public static void Test7()\n    {\n        var m1 = ReaderT<string>.lift(IO.pure(123));\n        var m2 = ReaderT<string>.lift(IO.pure(123));\n                \n        var m0 = from w in Pure(123)\n                 from q in m1\n                 from f in use(() => File.Open(\"c:\\\\test.txt\", FileMode.Open))\n                 from p in ReaderT.ask<IO, string>()\n                 from x in IO.pure(\"Hello\")\n                 from i in ReaderT<string, IO>.liftIO(IO.pure(\"Hello\"))\n                 from j in IO.pure(\"Hello\").Fork()\n                 from r in envIO \n                 from y in m2\n                 select $\"{p} {y} {j}\";\n\n        var value = m0.Run(\"Hello\").As();\n    }\n   \n    public static void Test8()\n    {\n        var m1 = OptionT.lift(ReaderT<string>.lift(IO.pure(123)));\n        var m2 = OptionT.lift(ReaderT<string>.lift(IO.pure(123)));\n\n        var m0 = from w in Pure(123)\n                 from q in m1\n                 from f in use(() => File.Open(\"c:\\\\test.txt\", FileMode.Open))\n                 from p in ask<string>()\n                 from i in liftIO(IO.pure(\"Hello\"))\n                 from j in IO.pure(\"Hello\").Fork()\n                 from r in envIO\n                 from _ in release(f)\n                 from y in m2\n                 select $\"{w} {f} {i}\";\n\n        var value = m0.Match(Some: v => $\"foo {v}\",\n                             None: () => \"bar\").As()\n                      .Run(\"Paul\").As()\n                      .Run();\n\n        OptionT<ReaderT<Env, IO>, Env> ask<Env>() =>\n            OptionT.lift(ReaderT.ask<IO, Env>());\n        \n        OptionT<ReaderT<string, IO>, A> liftIO<A>(IO<A> ma) =>\n            OptionT.liftIO<ReaderT<string, IO>, A>(ma);\n    }\n       \n    /*public static void Test9()\n    {\n        var m1 = OptionT.lift(StateT<string>.lift(IO.pure(100)));\n        var m2 = OptionT.lift(StateT<string>.lift(IO.pure(200)));\n\n        var m0 = from w in Pure(123)\n                 from q in m1\n                 from x in StateT.get<IO, string>()\n                 from i in OptionT.liftIO<StateT<string, IO>, string>(IO.pure(\"Hello\"))\n                 from j in IO.pure(\"Hello\").Fork()\n               //from k in m1.ForkIO()                          -- Can't work, because OptionT is not MonadUnliftIO\n                 from k in m1.Run().Run(\"state\").As().Fork()    // But we can manually unpack \n                 from _ in StateT.put<IO, string>(x)\n                 from r in envIO\n                 from y in m2\n                 select $\"{w} {j} {i}\";\n\n        var value = m0.Match(Some: v => $\"foo {v}\", \n                             None: () => \"bar\").As()\n                      .Run(\"Paul\").As()\n                      .Run(); \n    }*/\n       \n    public static void Test10()\n    {\n        var m1 = StateT<string>.lift(OptionT.lift(IO.pure(100)));\n        var m2 = StateT<string>.lift(OptionT.lift(IO.pure(200)));\n\n        var m0 = from w in Pure(123)\n                 from q in m1\n                 from x in StateT.get<OptionT<IO>, string>()\n                 from i in StateT<string, OptionT<IO>>.liftIO(IO.pure(\"Hello\"))\n                 from j in IO.pure(\"Hello\").Fork()\n                 from _ in StateT.put<OptionT<IO>, string>(x)\n                 from r in envIO\n                 from y in m2\n                 select $\"{w} {j} {i}\";\n\n        var value = m0.Run(\"Paul\").As()\n                      .Match(Some: v => $\"value: {v.Value}, state: {v.State}\", \n                             None: () => \"bar\").As()\n                      .Run(); \n    }\n\n    static void TravTest1()\n    {\n        var xs = Seq(1, 2, 3, 4, 5);\n        var r1 = Traversable.traverse(x => Some(x), xs);\n        \n        var ys = Seq(Some(1).Kind(), Some(2).Kind(), Option<int>.None.Kind(), Some(4).Kind(), Option<int>.None.Kind());\n        var r2 = Traversable.sequenceM(ys);\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// \n//  Generalised IO\n//\n\npublic static class GeneralIO<M>\n    where M : Monad<M>\n{\n    public static K<M, string> readAllText(string path) =>\n        M.LiftIOMaybe(liftIO(async _ => await File.ReadAllTextAsync(path)));\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// \n//  Maybe test\n//\n\npublic class Maybe : Monad<Maybe>\n{\n    public static Maybe<A> Just<A>(A value) =>\n        new Just<A>(value);\n\n    public static K<Maybe, B> Bind<A, B>(K<Maybe, A> ma, Func<A, K<Maybe, B>> f) => \n        ma.As().Bind(f);\n\n    public static K<Maybe, B> Recur<A, B>(A value, Func<A, K<Maybe, Next<A, B>>> f) =>\n        Monad.unsafeRecur(value, f);\n\n    public static K<Maybe, B> Map<A, B>(Func<A, B> f, K<Maybe, A> ma) => \n        ma.As().Map(f);\n    \n    public static K<Maybe, A> Pure<A>(A value) => \n        Just(value);\n\n    public static K<Maybe, B> Apply<A, B>(K<Maybe, Func<A, B>> mf, K<Maybe, A> ma) =>\n        mf.As().Bind(f => ma.As().Map(f));\n\n    public static K<Maybe, B> Apply<A, B>(K<Maybe, Func<A, B>> mf, Memo<Maybe, A> ma) =>\n        mf.As().Bind(f => ma.Value.As().Map(f));\n\n    public static K<Maybe, B> Action<A, B>(K<Maybe, A> ma, K<Maybe, B> mb) =>\n        ma.As().Bind(_ => mb);\n\n    public static K<Maybe, A> LiftIOMaybe<A>(IO<A> ma) => \n        throw new NotImplementedException();\n}\n\npublic abstract record Maybe<A> : K<Maybe, A>\n{\n    public static readonly Maybe<A> Nothing = \n        new Nothing<A>();\n    \n    public abstract Maybe<B> Map<B>(Func<A, B> f);\n\n    public abstract Maybe<B> Bind<B>(Func<A, Maybe<B>> f);\n\n    public virtual Maybe<B> Bind<B>(Func<A, K<Maybe, B>> f) =>\n        Bind(x => f(x).As());\n\n    public Maybe<C> SelectMany<B, C>(Func<A, Maybe<B>> bind, Func<A, B, C> project) =>\n        Bind(x => bind(x).Map(y => project(x, y)));\n\n    public Maybe<C> SelectMany<B, C>(Func<A, K<Maybe, B>> bind, Func<A, B, C> project) =>\n        SelectMany(x => bind(x).As(), project);\n}\n\npublic record Just<A>(A Value) : Maybe<A>\n{\n    public override Maybe<B> Map<B>(Func<A, B> f) => \n        new Just<B>(f(Value));\n\n    public override Maybe<B> Bind<B>(Func<A, Maybe<B>> f) =>\n        f(Value);\n}\n\npublic record Nothing<A> : Maybe<A>\n{\n    public override Maybe<B> Map<B>(Func<A, B> f) => \n        Maybe<B>.Nothing;\n\n    public override Maybe<B> Bind<B>(Func<A, Maybe<B>> f) =>\n        Maybe<B>.Nothing;\n}\n\npublic static class MaybeExt\n{\n    public static Maybe<A> As<A>(this K<Maybe, A> ma) =>\n        (Maybe<A>)ma;\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// \n//  App test\n//\n\n// Domain monad\npublic record App<A>(ReaderT<AppConfig, Either<Error>, A> runReader) : K<App, A>;\n\n// Application environment\npublic record AppConfig(string ConnectionString, string RootFolder);\n\npublic static class AppExtensions\n{\n    public static App<A> As<A>(this K<App, A> ma) =>\n        (App<A>)ma;\n    \n    public static Either<Error, A> Run<A>(this K<App, A> ma, AppConfig config) =>\n        ma.As().runReader.Run(config).As();\n}\n\npublic class App :\n    Fallible<App>,\n    Deriving.MonadT<App, ReaderT<AppConfig, Either<Error>>, Either<Error>>,\n    Deriving.MonadIO<App, ReaderT<AppConfig, Either<Error>>>,\n    Deriving.Readable<App, AppConfig, ReaderT<AppConfig, Either<Error>>>\n{\n    public static App<A> Pure<A>(A value) =>\n        Applicative.pure<App, A>(value).As();\n\n    public static App<A> Fail<A>(Error error) =>\n        Fallible.error<App, A>(error).As();\n\n    public static K<App, A> Catch<A>(K<App, A> fa, Func<Error, bool> Predicate, Func<Error, K<App, A>> Fail) => \n        throw new NotImplementedException();\n\n    public static App<string> connectionString =>\n        Readable.asks<App, AppConfig, string>(env => env.ConnectionString).As();\n\n    public static App<string> rootFolder =>\n        Readable.asks<App, AppConfig, string>(env => env.RootFolder).As();\n\n    public static K<ReaderT<AppConfig, Either<Error>>, A> Transform<A>(K<App, A> fa) => \n        fa.As().runReader;\n\n    public static K<App, A> CoTransform<A>(K<ReaderT<AppConfig, Either<Error>>, A> fa) => \n        new App<A>(fa.As());\n\n    static K<App, A> Fallible<Error, App>.Fail<A>(Error error) =>\n        new App<A>(ReaderT.lift<AppConfig, Either<Error>, A>(Left<Error, A>(error).As()));\n}\n\n"
  },
  {
    "path": "LanguageExt.Tests/TrackingHashMapTests.cs",
    "content": "﻿using static LanguageExt.Prelude;\nusing static LanguageExt.HashMap;\nusing Xunit;\nusing System;\nusing System.Linq;\nusing LanguageExt.ClassInstances;\n\nnamespace LanguageExt.Tests\n{\n    public class TrackingHashMapTests\n\n    {\n        [Fact]\n        public void itemLensGetShouldGetExistingValue()\n        {\n            var expected = \"3\";\n            var map = TrackingHashMap((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n            var actual = TrackingHashMap<int, string>.item(3).Get(map);\n\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void itemLensGetShouldThrowExceptionForNonExistingValue()\n        {\n            Assert.Throws<ArgumentException>(() =>\n            {\n                var map = TrackingHashMap((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n                var actual = TrackingHashMap<int, string>.item(10).Get(map);\n            });\n        }\n\n        [Fact]\n        public void itemOrNoneLensGetShouldGetExistingValue()\n        {\n            var expected = \"3\";\n            var map = TrackingHashMap((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n            var actual = TrackingHashMap<int, string>.itemOrNone(3).Get(map);\n\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void itemOrNoneLensGetShouldReturnNoneForNonExistingValue()\n        {\n            var expected = Option<string>.None;\n            var map = TrackingHashMap((1, \"1\"), (2, \"2\"), (3, \"3\"), (4, \"4\"), (5, \"5\"));\n            var actual = TrackingHashMap<int, string>.itemOrNone(10).Get(map);\n\n            Assert.Equal(expected, actual);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/TraitTests/AlternativeLawTests.cs",
    "content": "using Xunit;\nusing LanguageExt;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.TraitTests;\n\npublic class AlternativeLawTests\n{\n    [Fact]\n    public void Arr() =>\n        AlternativeLaw<Arr>.assert();\n    \n    [Fact]\n    public void HashSet() =>\n        AlternativeLaw<HashSet>.assert();\n    \n    [Fact]\n    public void Iterable() =>\n        AlternativeLaw<Iterable>.assert();\n    \n    [Fact]\n    public void Lst() =>\n        AlternativeLaw<Lst>.assert();\n    \n    [Fact]\n    public void Seq() =>\n        AlternativeLaw<Seq>.assert();\n    \n    [Fact]\n    public void EffRT()\n    {\n        bool eq(K<Eff<Unit>, int> vx, K<Eff<Unit>, int> vy) => \n            vx.Run(unit).Equals(vy.Run(unit));\n        \n        AlternativeLaw<Eff<Unit>>.assert(eq);\n    }\n    \n    [Fact]\n    public void Eff()\n    {\n        bool eq(K<Eff, int> vx, K<Eff, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        AlternativeLaw<Eff>.assert(eq);\n    }\n    \n    [Fact]\n    public void IO()\n    {\n        bool eq(K<IO, int> vx, K<IO, int> vy) => \n            vx.RunSafe().Equals(vy.RunSafe());\n        \n        AlternativeLaw<IO>.assert(eq);\n    }\n\n    [Fact]\n    public void Fin() => \n        AlternativeLaw<Fin>.assert();\n\n    [Fact]\n    public void FinT() => \n        AlternativeLaw<FinT<Identity>>.assert();\n\n    [Fact]\n    public void Option() => \n        AlternativeLaw<Option>.assert();\n\n    [Fact]\n    public void OptionT() => \n        AlternativeLaw<OptionT<Identity>>.assert();\n\n    [Fact]\n    public void Try()\n    {\n        bool eq(K<Try, int> vx, K<Try, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        AlternativeLaw<Try>.assert(eq);\n    }\n    \n    [Fact]\n    public void TryT()\n    {\n        bool eq(K<TryT<Identity>, int> vx, K<TryT<Identity>, int> vy) => \n            vx.Run().Run().Equals(vy.Run().Run());\n        \n        AlternativeLaw<TryT<Identity>>.assert(eq);\n    }\n    \n    [Fact]\n    public void Validation() => \n        AlternativeLaw<Validation<StringM>>.assert();\n\n    [Fact]\n    public void ValidationT()\n    {\n        bool eq(K<ValidationT<StringM, Identity>, int> vx, K<ValidationT<StringM, Identity>, int> vy) =>\n            vx.Run().As().Value.Equals(vy.Run().As().Value);\n\n        AlternativeLaw<ValidationT<StringM, Identity>>.assert(eq);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/TraitTests/ApplicativeLawTests.cs",
    "content": "using Xunit;\nnamespace LanguageExt.Tests.TraitTests;\n\npublic class ApplicativeFunctorLawTests\n{\n    [Fact]\n    public void Arr() =>\n        ApplicativeLaw<Arr>.assert();\n    \n    [Fact]\n    public void HashSet() =>\n        ApplicativeLaw<HashSet>.assert();\n    \n    [Fact]\n    public void Iterable() =>\n        ApplicativeLaw<Iterable>.assert();\n    \n    [Fact]\n    public void IterableNE() =>\n        ApplicativeLaw<IterableNE>.assert();\n    \n    [Fact]\n    public void Lst() =>\n        ApplicativeLaw<Lst>.assert();\n    \n    [Fact]\n    public void Seq() =>\n        ApplicativeLaw<Seq>.assert();\n    \n    [Fact]\n    public void EffRT()\n    {\n        bool eq(K<Eff<Unit>, int> vx, K<Eff<Unit>, int> vy) => \n            vx.Run(unit).Equals(vy.Run(unit));\n        \n        ApplicativeLaw<Eff<Unit>>.assert(eq);\n    }\n    \n    [Fact]\n    public void Eff()\n    {\n        bool eq(K<Eff, int> vx, K<Eff, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        ApplicativeLaw<Eff>.assert(eq);\n    }\n    \n    [Fact]\n    public void IO()\n    {\n        bool eq(K<IO, int> vx, K<IO, int> vy) => \n            vx.RunSafe().Equals(vy.RunSafe());\n        \n        ApplicativeLaw<IO>.assert(eq);\n    }\n    \n    [Fact]\n    public void StreamT()\n    {\n        // TODO: Restore\n        \n        /*static Seq<int> toSeq(StreamT<Identity, int> s) =>\n            s.Head().Run()\n             .Match(Some: x => x.Cons(toSeq(s.Tail())),\n                    None: []);\n\n        static bool eq(K<StreamT<Identity>, int> vx, K<StreamT<Identity>, int> vy) =>\n            toSeq(vx.As()) == toSeq(vy.As());\n        \n        ApplicativeLaw<StreamT<Identity>>.assert(eq);*/\n    }\n    \n    [Fact]\n    public void Either() => \n        ApplicativeLaw<Either<string>>.assert();\n\n    [Fact]\n    public void EitherT() => \n        ApplicativeLaw<EitherT<string, Identity>>.assert();\n\n    [Fact]\n    public void Fin() => \n        ApplicativeLaw<Fin>.assert();\n\n    [Fact]\n    public void FinT() => \n        ApplicativeLaw<FinT<Identity>>.assert();\n\n    [Fact]\n    public void Option() => \n        ApplicativeLaw<Option>.assert();\n\n    [Fact]\n    public void OptionT() => \n        ApplicativeLaw<OptionT<Identity>>.assert();\n\n    [Fact]\n    public void Try()\n    {\n        bool eq(K<Try, int> vx, K<Try, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        ApplicativeLaw<Try>.assert(eq);\n    }\n    \n    [Fact]\n    public void TryT()\n    {\n        bool eq(K<TryT<Identity>, int> vx, K<TryT<Identity>, int> vy) => \n            vx.Run().Run().Equals(vy.Run().Run());\n        \n        ApplicativeLaw<TryT<Identity>>.assert(eq);\n    }\n    \n    [Fact]\n    public void Validation() => \n        ApplicativeLaw<Validation<StringM>>.assert();\n\n    [Fact]\n    public void ValidationT()\n    {\n        bool eq(K<ValidationT<StringM, Identity>, int> vx, K<ValidationT<StringM, Identity>, int> vy) =>\n            vx.Run().As().Value.Equals(vy.Run().As().Value);\n\n        ApplicativeLaw<ValidationT<StringM, Identity>>.assert(eq);\n    }\n\n    [Fact]\n    public void Identity() => \n        ApplicativeLaw<Identity>.assert();\n\n    [Fact]\n    public void IdentityT() => \n        ApplicativeLaw<IdentityT<Identity>>.assert();\n\n    [Fact]\n    public void Reader()\n    {\n        bool eq(K<Reader<string>, int> vx, K<Reader<string>, int> vy) => \n            vx.Run(\"Hello\").Equals(vy.Run(\"Hello\"));\n        \n        ApplicativeLaw<Reader<string>>.assert(eq);\n    }\n    \n    [Fact]\n    public void ReaderT()\n    {\n        bool eq(K<ReaderT<string, Identity>, int> vx, K<ReaderT<string, Identity>, int> vy) => \n            vx.Run(\"Hello\").Run().Equals(vy.Run(\"Hello\").Run());\n                 \n        ApplicativeLaw<ReaderT<string, Identity>>.assert(eq);\n    }\n\n    [Fact]\n    public void State()\n    {\n        bool eq(K<State<string>, int> vx, K<State<string>, int> vy) => \n            vx.Run(\"Hello\").Equals(vy.Run(\"Hello\"));\n        \n        ApplicativeLaw<State<string>>.assert(eq);\n    }\n    \n    [Fact]\n    public void StateT()\n    {\n        bool eq(K<StateT<string, Identity>, int> vx, K<StateT<string, Identity>, int> vy) => \n            vx.Run(\"Hello\").Run().Equals(vy.Run(\"Hello\").Run());\n                 \n        ApplicativeLaw<StateT<string, Identity>>.assert(eq);\n    }\n    \n    [Fact]\n    public void Writer()\n    {\n        bool eq(K<Writer<StringM>, int> vx, K<Writer<StringM>, int> vy) => \n            vx.Run(\"Hello, \").Equals(vy.Run(\"Hello, \"));\n        \n        ApplicativeLaw<Writer<StringM>>.assert(eq);\n    }\n    \n    [Fact]\n    public void WriterT()\n    {\n        bool eq(K<WriterT<StringM, Identity>, int> vx, K<WriterT<StringM, Identity>, int> vy) => \n            vx.Run(\"Hello, \").Run().Equals(vy.Run(\"Hello, \").Run());\n        \n        ApplicativeLaw<WriterT<StringM, Identity>>.assert(eq);\n    }      \n}\n"
  },
  {
    "path": "LanguageExt.Tests/TraitTests/ChoiceLawTests.cs",
    "content": "using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.TraitTests;\n\npublic class ChoiceLawTests\n{\n    [Fact]\n    public void Arr() =>\n        ChoiceLaw<Arr>.assert(Arr<int>.Empty);\n    \n    [Fact]\n    public void HashSet() =>\n        ChoiceLaw<HashSet>.assert(HashSet<int>.Empty);\n    \n    [Fact]\n    public void Iterable() =>\n        ChoiceLaw<Iterable>.assert(Iterable<int>.Empty);\n    \n    [Fact]\n    public void Lst() =>\n        ChoiceLaw<Lst>.assert(Lst<int>.Empty);\n    \n    [Fact]\n    public void Seq() =>\n        ChoiceLaw<Seq>.assert(Seq<int>.Empty);\n    \n    [Fact]\n    public void EffRT()\n    {\n        bool eq(K<Eff<Unit>, int> vx, K<Eff<Unit>, int> vy) => \n            vx.Run(unit).Equals(vy.Run(unit));\n        \n        ChoiceLaw<Eff<Unit>>.assert(error<Eff<Unit>, int>(Errors.None), eq);\n    }\n    \n    [Fact]\n    public void Eff()\n    {\n        bool eq(K<Eff, int> vx, K<Eff, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        ChoiceLaw<Eff>.assert(error<Eff, int>(Errors.None), eq);\n    }\n    \n    [Fact]\n    public void IO()\n    {\n        bool eq(K<IO, int> vx, K<IO, int> vy) => \n            vx.RunSafe().Equals(vy.RunSafe());\n        \n        ChoiceLaw<IO>.assert(error<IO, int>(Errors.None), eq);\n    }\n    \n    [Fact]\n    public void Either() => \n        ChoiceLaw<Either<string>>.assert(fail<string, Either<string>, int>(\"error\"));\n\n    [Fact]\n    public void EitherT() => \n        ChoiceLaw<EitherT<string, Identity>>.assert(fail<string, EitherT<string, Identity>, int>(\"error\"));\n\n    [Fact]\n    public void Fin() => \n        ChoiceLaw<Fin>.assert(error<Fin, int>(Errors.None));\n\n    [Fact]\n    public void FinT() => \n        ChoiceLaw<FinT<Identity>>.assert(error<FinT<Identity>, int>(Errors.None));\n\n    [Fact]\n    public void Option() => \n        ChoiceLaw<Option>.assert(fail<Unit, Option, int>(unit));\n\n    [Fact]\n    public void OptionT() => \n        ChoiceLaw<OptionT<Identity>>.assert(fail<Unit, OptionT<Identity>, int>(unit));\n\n    [Fact]\n    public void Try()\n    {\n        bool eq(K<Try, int> vx, K<Try, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        ChoiceLaw<Try>.assert(error<Try, int>(Errors.None), eq);\n    }\n    \n    [Fact]\n    public void TryT()\n    {\n        bool eq(K<TryT<Identity>, int> vx, K<TryT<Identity>, int> vy) => \n            vx.Run().Run().Equals(vy.Run().Run());\n\n        ChoiceLaw<TryT<Identity>>.assert(error<TryT<Identity>, int>(Errors.None), eq);\n    }\n    \n    [Fact]\n    public void Validation() => \n        ChoiceLaw<Validation<StringM>>.assert(fail<StringM, Validation<StringM>, int>(\"error\"));\n\n    [Fact]\n    public void ValidationT()\n    {\n        bool eq(K<ValidationT<StringM, Identity>, int> vx, K<ValidationT<StringM, Identity>, int> vy) =>\n            vx.Run().As().Value.Equals(vy.Run().As().Value);\n        \n        ChoiceLaw<ValidationT<StringM, Identity>>.assert(fail<StringM, ValidationT<StringM, Identity>, int>(\"error\"), eq);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/TraitTests/FoldableDefaultsTests.cs",
    "content": "using System;\nusing LanguageExt.ClassInstances;\nusing Xunit;\n\nnamespace LanguageExt.Tests.TraitTests;\n\npublic class FoldableDefaultsTests\n{\n    [Fact]\n    public static void FoldTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Fold(0, (s, x) => s + x);\n        Assert.True(res == 15);\n    }\n    \n    [Fact]\n    public static void FoldBackTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldBack(0, (s, x) => s + x);\n        Assert.True(res == 15);\n    }\n        \n    [Fact]\n    public static void FoldMNoneTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldM(0, (s, x) => x == 4 ? None : Some(s + x));\n        \n        Assert.True(res.As() == None);\n    }\n        \n    [Fact]\n    public static void FoldBackNoneMTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldBackM(0, (s, x) => x == 4 ? None : Some(s + x));\n        \n        Assert.True(res.As() == None);\n    }\n        \n    [Fact]\n    public static void FoldMSomeTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldM(0, (s, x) => Some(s + x));\n        \n        Assert.True(res.As() == Some(15));\n    }\n        \n    [Fact]\n    public static void FoldBackSomeMTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldBackM(0, (s, x) => Some(s + x));\n        \n        Assert.True(res.As() == Some(15));\n    }\n\n    [Fact]\n    public static void FoldWhileStateTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldWhile(0, (s, x) => s + x, s => s.State < 3);\n        Assert.True(res == 3);\n    }\n    \n    [Fact]\n    public static void FoldWhileValueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldWhile(0, (s, x) => s + x, s => s.Value < 4);\n        Assert.True(res == 6);\n    }\n    \n    [Fact]\n    public static void FoldBackWhileStateTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldBackWhile(15, (s, x) => s - x, s => s.State > 3);\n        Assert.True(res == 3);\n    }\n    \n    [Fact]\n    public static void FoldBackWhileValueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldBackWhile(0, (s, x) => s + x, s => s.Value > 3);\n        Assert.True(res == 9);\n    }\n    \n    [Fact]\n    public static void FoldMaybeTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldMaybe(0, (s, x) => x == 4 ? None : Some(s + x));\n        \n        Assert.True(res == 6);\n    }\n    \n    [Fact]\n    public static void FoldBackMaybeTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldBackMaybe(0, (s, x) => x == 2 ? None : Some(s + x));\n        \n        Assert.True(res == 12);\n    }\n    \n    [Fact]\n    public static void FoldWhileMTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldWhileM(0, (s, x) => Some(s + x), x => x.Value < 4);\n        \n        Assert.True(res.As() == Some(6));\n    }\n    \n    [Fact]\n    public static void FoldBackWhileMTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldBackWhileM(15, (s, x) => Some(s - x), x => x.Value > 3);\n        \n        Assert.True(res.As() == Some(6));\n    }\n    \n    [Fact]\n    public static void FoldUntilStateTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldUntil(0, (s, x) => s + x, s => s.State == 3);\n        Assert.True(res == 3);\n    }\n    \n    [Fact]\n    public static void FoldUntilValueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldUntil(0, (s, x) => s + x, s => s.Value == 4);\n        Assert.True(res == 6);\n    }\n    \n    [Fact]\n    public static void FoldBackUntilStateTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldBackUntil(15, (s, x) => s - x, s => s.State == 3);\n        Assert.True(res == 3);\n    }\n    \n    [Fact]\n    public static void FoldBackUntilValueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FoldBackUntil(0, (s, x) => s + x, s => s.Value == 3);\n        Assert.True(res == 9);\n    }\n    \n    [Fact]\n    public static void FoldUntilMTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldUntilM(0, (s, x) => Some(s + x), x => x.Value == 4);\n        \n        Assert.True(res.As() == Some(6));\n    }\n    \n    [Fact]\n    public static void FoldBackUntilMTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5)\n                       .FoldBackUntilM(15, (s, x) => Some(s - x), x => x.Value == 3);\n        \n        Assert.True(res.As() == Some(6));\n    }\n\n    [Fact]\n    public static void ToSeqTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).ToSeq();\n        Assert.True(res == Seq(1, 2, 3, 4, 5));\n    }\n\n    [Fact]\n    public static void ToLstTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).ToLst();\n        Assert.True(res == List(1, 2, 3, 4, 5));\n    }\n\n    [Fact]\n    public static void ToArrTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).ToArr();\n        Assert.True(res == Array(1, 2, 3, 4, 5));\n    }\n\n    [Fact]\n    public static void ToIterableTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).ToIterable();\n        Assert.True(res == Iterable(1, 2, 3, 4, 5));\n    }\n\n    [Fact]\n    public static void IsEmptyFalseTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).IsEmpty;\n        Assert.False(res);\n    }\n\n    [Fact]\n    public static void IsEmptyTrueTest()\n    {\n        var res = FList.New<int>().IsEmpty;\n        Assert.True(res);\n    }\n\n    [Fact]\n    public static void CountTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Count;\n        Assert.True(res == 5);\n    }\n    \n    [Fact]\n    public static void ExistsTrueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Exists(x => x == 3);\n        Assert.True(res);\n    }\n    \n    [Fact]\n    public static void ExistsFalseTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Exists(x => x == 6);\n        Assert.False(res);\n    }\n    \n    [Fact]\n    public static void ExistsEmptyIsFalseTest()\n    {\n        var res = FList.New<int>().Exists(x => x == 6);\n        Assert.False(res);\n    }\n    \n    [Fact]\n    public static void ForAllTrueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).ForAll(x => x < 6);\n        Assert.True(res);\n    }\n    \n    [Fact]\n    public static void ForAllFalseTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).ForAll(x => x < 3);\n        Assert.False(res);\n    }\n    \n    [Fact]\n    public static void ForAllEmptyIsTrueTest()\n    {\n        var res = FList.New<int>().ForAll(x => x < 5);\n        Assert.True(res);\n    }\n    \n    [Fact]\n    public static void ContainsTrueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Contains(3);\n        Assert.True(res);\n    }\n    \n    [Fact]\n    public static void ContainsFalseTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Contains(6);\n        Assert.False(res);\n    }\n    \n    [Fact]\n    public static void ContainsEqTrueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Contains<EqInt, FList, int>(3);\n        Assert.True(res);\n    }\n    \n    [Fact]\n    public static void ContainsEqFalseTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Contains<EqInt, FList, int>(6);\n        Assert.False(res);\n    }\n        \n    [Fact]\n    public static void FindTrueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Find(x => x == 3);\n        Assert.True(res == Some(3));\n    }\n    \n    [Fact]\n    public static void FindFalseTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Find(x => x == 6);\n        Assert.True(res == None);\n    }\n        \n    [Fact]\n    public static void FindBackTrueTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FindBack(x => x == 3);\n        Assert.True(res == Some(3));\n    }\n    \n    [Fact]\n    public static void FindBackFalseTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FindBack(x => x == 6);\n        Assert.True(res == None);\n    }\n        \n    [Fact]\n    public static void FindAllTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FindAll(x => x > 3);\n        Assert.True(res == Iterable(4, 5));\n    }\n        \n    [Fact]\n    public static void FindAllBackTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).FindAllBack(x => x > 3);\n        Assert.True(res == Iterable(5, 4));\n    }\n        \n    [Fact]\n    public static void SumTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Sum();\n        Assert.True(res == 15);\n    }\n        \n    [Fact]\n    public static void ProductTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Product();\n        Assert.True(res == 120);\n    }\n        \n    [Fact]\n    public static void HeadSomeTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Head;\n        Assert.True(res == Some(1));\n    }\n        \n    [Fact]\n    public static void HeadNoneTest()\n    {\n        var res = FList.New<int>().Head;\n        Assert.True(res == None);\n    }\n        \n    [Fact]\n    public static void LastSomeTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Last;\n        Assert.True(res == Some(5));\n    }\n        \n    [Fact]\n    public static void LastNoneTest()\n    {\n        var res = FList.New<int>().Last;\n        Assert.True(res == None);\n    }\n            \n    [Fact]\n    public static void IterTest()\n    {\n        var atom = Atom(0);\n        var comp = FList.New(1, 2, 3, 4, 5)\n                        .Iter(x => atom.SwapIO(v => v + x));\n        \n        ignore(comp.Run());\n        \n        Assert.True(atom.Value == 15);\n    }\n        \n    [Fact]\n    public static void MinTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Min();\n        Assert.True(res == Some(1));\n    }\n        \n    [Fact]\n    public static void MinOrdTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Min<OrdInt, FList, int>();\n        Assert.True(res == 1);\n    }\n        \n    [Fact]\n    public static void MaxTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Max();\n        Assert.True(res == Some(5));\n    }\n        \n    [Fact]\n    public static void MaxOrdTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Max<OrdInt, FList, int>();\n        Assert.True(res == 5);\n    }\n        \n    [Fact]\n    public static void AverageTest()\n    {\n        var res = FList.New(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0).Average();\n        Assert.True(Math.Abs(res - 5.5) < 0.0000001);\n    }\n        \n    [Fact]\n    public static void AtTest()\n    {\n        var foldable = FList.New(1, 2, 3, 4, 5);\n        var r0       = foldable.At(0);\n        var r1       = foldable.At(1);\n        var r2       = foldable.At(2);\n        var r3       = foldable.At(3);\n        var r4       = foldable.At(4);\n        var x5       = foldable.At(5);\n        \n        Assert.True(r0 == Some(1));\n        Assert.True(r1 == Some(2));\n        Assert.True(r2 == Some(3));\n        Assert.True(r3 == Some(4));\n        Assert.True(r4 == Some(5));\n        Assert.True(x5 == None);\n    }\n        \n    [Fact]\n    public static void PartitionTest()\n    {\n        var res = FList.New(1, 2, 3, 4, 5).Partition(x => (x & 1) == 0);\n        \n        Assert.True(res.True == Seq(2, 4));\n        Assert.True(res.False == Seq(1, 3, 5));\n    }\n}\n\npublic record FList<A>(A[] Values) : K<FList, A>;\n\npublic static class FListExtensions\n{\n    public static FList<A> As<A>(this K<FList, A> self) =>\n        (FList<A>)self;\n}\n\npublic class FList : Foldable<FList>\n{\n    public static FList<A> New<A>(params A[] values) =>\n        new (values);\n\n\n    public static Fold<A, S> FoldStep<A, S>(K<FList, A> ta, S initialState)\n    {\n        var ix    = 0;\n        var ma    = ta.As().Values;\n        var count = ma.Length;\n        return go(initialState);\n\n        Fold<A, S> go(S state) =>\n            ix == count\n                ? Fold.Done<A, S>(state)\n                : Fold.Loop(state, ma[ix++], go);\n        \n    }\n\n    public static Fold<A, S> FoldStepBack<A, S>(K<FList, A> ta, S initialState)\n    {\n        var ma    = ta.As().Values;\n        var count = ma.Length;\n        var ix    = count;\n        return go(initialState);\n\n        Fold<A, S> go(S state) =>\n            ix == 0\n                ? Fold.Done<A, S>(state)\n                : Fold.Loop(state, ma[--ix], go);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/TraitTests/FunctorLawTests.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\nusing LE = LanguageExt;\n\nnamespace LanguageExt.Tests.TraitTests;\n\npublic class FunctorLawTests\n{\n    [Fact]\n    public void Arr()\n    {\n        Arr<int> fa = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        FunctorLaw<Arr>.assert(fa);\n    }\n    \n    [Fact]\n    public void HashMap()\n    {\n        HashMap<string, int> fa = [(\"one\", 1), (\"two\", 2), (\"three\", 3), (\"four\", 4), (\"five\", 5)];\n        FunctorLaw<HashMap<string>>.assert(fa);\n    }\n    \n    [Fact]\n    public void HashSet()\n    {\n        HashSet<int> fa = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        FunctorLaw<HashSet>.assert(fa);\n    }\n    \n    [Fact]\n    public void Iterable()\n    {\n        Iterable<int> fa = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        FunctorLaw<Iterable>.assert(fa);\n    }\n    \n    [Fact]\n    public void IterableNE()\n    {\n        var fa = LE.IterableNE.create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n        FunctorLaw<IterableNE>.assert(fa);\n    }\n    \n    [Fact]\n    public void Lst()\n    {\n        Lst<int> fa = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        FunctorLaw<Lst>.assert(fa);\n    }\n    \n    [Fact]\n    public void Map()\n    {\n        Map<string, int> fa = [(\"one\", 1), (\"two\", 2), (\"three\", 3), (\"four\", 4), (\"five\", 5)];\n        FunctorLaw<Map<string>>.assert(fa);\n    }\n    \n    [Fact]\n    public void Seq()\n    {\n        Seq<int> fa = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        FunctorLaw<Seq>.assert(fa);\n    }    \n    \n    [Fact]\n    public void EffRT()\n    {\n        bool eq(K<Eff<Unit>, int> vx, K<Eff<Unit>, int> vy) => \n            vx.Run(unit).Equals(vy.Run(unit));\n        \n        var ma = Eff<Unit, int>.Pure(1);\n        var mx = Eff<Unit, int>.Fail(Errors.Closed);\n        FunctorLaw<Eff<Unit>>.assert(ma, eq);\n        FunctorLaw<Eff<Unit>>.assert(mx, eq);\n    }\n    \n    [Fact]\n    public void Eff()\n    {\n        bool eq(K<Eff, int> vx, K<Eff, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        var ma = Eff<int>.Pure(1);\n        var mx = Eff<int>.Fail(Errors.Closed);\n        FunctorLaw<Eff>.assert(ma, eq);\n        FunctorLaw<Eff>.assert(mx, eq);\n    }\n    \n    [Fact]\n    public void IO()\n    {\n        bool eq(K<IO, int> vx, K<IO, int> vy) => \n            vx.RunSafe().Equals(vy.RunSafe());\n        \n        var ma = LE.IO.pure(1);\n        var mx = LE.IO.fail<int>(Errors.Closed);\n        FunctorLaw<IO>.assert(ma, eq);\n        FunctorLaw<IO>.assert(mx, eq);\n    }\n    \n    [Fact]\n    public void StreamT()\n    {\n        // TODO: Restore\n        \n        /*\n        static Seq<int> toSeq(StreamT<Identity, int> s) =>\n            s.Head().Run()\n             .Match(Some: x => x.Cons(toSeq(s.Tail())),\n                    None: []);\n\n        static bool eq(K<StreamT<Identity>, int> vx, K<StreamT<Identity>, int> vy) =>\n            toSeq(vx.As()) == toSeq(vy.As());\n        \n        var ma = StreamT<Identity, int>.Pure(1);\n        var mb = StreamT<Identity, int>.Lift([1, 2, 3, 4, 5 , 6, 7, 8, 9, 10]);\n        \n        FunctorLaw<StreamT<Identity>>.assert(ma, eq);\n        FunctorLaw<StreamT<Identity>>.assert(mb, eq);\n    */\n    }\n    \n    [Fact]\n    public void Either()\n    {\n        var fa = Right<string, int>(1);\n        var fx = Left<string, int>(\"failed\");\n        FunctorLaw<Either<string>>.assert(fa);\n        FunctorLaw<Either<string>>.assert(fx);\n    }\n    \n    [Fact]\n    public void EitherT()\n    {\n        var fa = LE.EitherT.Right<string, Identity, int>(1);\n        var fx = LE.EitherT.Left<string, Identity, int>(\"failed\");\n        FunctorLaw<EitherT<string, Identity>>.assert(fa);\n        FunctorLaw<EitherT<string, Identity>>.assert(fx);\n    }\n\n    [Fact]\n    public void Fin()\n    {\n        var fa = LE.Fin.Succ(1);\n        var fx = LE.Fin.Fail<int>(Errors.TimedOut);\n        FunctorLaw<Fin>.assert(fa);\n        FunctorLaw<Fin>.assert(fx);\n    }\n    \n    [Fact]\n    public void FinT()\n    {\n        var fa = LE.FinT.Succ<Identity, int>(1);\n        var fx = LE.FinT.Fail<Identity, int>(Errors.TimedOut);\n        FunctorLaw<FinT<Identity>>.assert(fa);\n        FunctorLaw<FinT<Identity>>.assert(fx);\n    }\n    \n    [Fact]\n    public void Option()\n    {\n        var fa = LE.Option.Some(1);\n        var fx = Option<int>.None;\n        FunctorLaw<Option>.assert(fa);\n        FunctorLaw<Option>.assert(fx);\n    }\n    \n    [Fact]\n    public void OptionT()\n    {\n        var fa = LE.OptionT.Some<Identity, int>(1);\n        var fx = LE.OptionT.None<Identity, int>();\n        FunctorLaw<OptionT<Identity>>.assert(fa);\n        FunctorLaw<OptionT<Identity>>.assert(fx);\n    }\n        \n    [Fact]\n    public void Try()\n    {\n        bool eq(K<Try, int> vx, K<Try, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        var fa = LE.Try.Succ(1);\n        var fx = LE.Try.Fail<int>(Errors.EndOfStream);\n        FunctorLaw<Try>.assert(fa, eq);\n        FunctorLaw<Try>.assert(fx, eq);\n    }\n    \n    [Fact]\n    public void TryT()\n    {\n        bool eq(K<TryT<Identity>, int> vx, K<TryT<Identity>, int> vy) => \n            vx.Run().Run().Equals(vy.Run().Run());\n        \n        var fa = LE.TryT.Succ<Identity, int>(1);\n        var fx = LE.TryT.Fail<Identity, int>(Errors.EndOfStream);\n        FunctorLaw<TryT<Identity>>.assert(fa, eq);\n        FunctorLaw<TryT<Identity>>.assert(fx, eq);\n    }\n    \n    [Fact]\n    public void Validation_()\n    {\n        var fa = Validation.Success<StringM, int>(1);\n        var fx = Validation.Fail<StringM, int>(\"failed\");\n        FunctorLaw<Validation<StringM>>.assert(fa);\n        FunctorLaw<Validation<StringM>>.assert(fx);\n    }\n    \n    [Fact]\n    public void ValidationT()\n    {\n        bool eq(K<ValidationT<StringM, Identity>, int> vx, K<ValidationT<StringM, Identity>, int> vy) =>\n            vx.Run().As().Value.Equals(vy.Run().As().Value);\n        \n        var fa = LE.ValidationT.Success<StringM, Identity, int>(1);\n        var fx = LE.ValidationT.Fail<StringM, Identity, int>(\"failed\");\n        FunctorLaw<ValidationT<StringM, Identity>>.assert(fa, eq);\n        FunctorLaw<ValidationT<StringM, Identity>>.assert(fx, eq);\n    }\n    \n    [Fact]\n    public void Identity()\n    {\n        var fa = LE.Identity.Pure(1);\n        FunctorLaw<Identity>.assert(fa);\n    }\n    \n    [Fact]\n    public void IdentityT()\n    {\n        var fa = LE.IdentityT.Pure<Identity, int>(1);\n        FunctorLaw<IdentityT<Identity>>.assert(fa);\n    }\n    \n    [Fact]\n    public void Reader()\n    {\n        bool eq(K<Reader<string>, int> vx, K<Reader<string>, int> vy) => \n            vx.Run(\"Hello\").Equals(vy.Run(\"Hello\"));\n        \n        var fa = from e in Readable.ask<Reader<string>, string>()   \n                 from v in Reader<string, int>.Pure(1)\n                 select e.Length + v;\n        \n        FunctorLaw<Reader<string>>.assert(fa, eq);\n    }\n    \n    [Fact]\n    public void ReaderT()\n    {\n        bool eq(K<ReaderT<string, Identity>, int> vx, K<ReaderT<string, Identity>, int> vy) => \n            vx.Run(\"Hello\").Run().Equals(vy.Run(\"Hello\").Run());\n        \n        var fa = from e in Readable.ask<ReaderT<string, Identity>, string>()  \n                 from v in ReaderT<string, Identity, int>.Pure(1)\n                 select e.Length + v;\n                 \n        FunctorLaw<ReaderT<string, Identity>>.assert(fa, eq);\n    }\n    \n    [Fact]\n    public void State()\n    {\n        bool eq(K<State<string>, int> vx, K<State<string>, int> vy) => \n            vx.Run(\"Hello\").Equals(vy.Run(\"Hello\"));\n        \n        var fa = from e in Stateful.get<State<string>, string>()  \n                 from v in State<string, int>.Pure(1)\n                 select e.Length + v;\n        \n        FunctorLaw<State<string>>.assert(fa, eq);\n    }\n    \n    [Fact]\n    public void StateT()\n    {\n        bool eq(K<StateT<string, Identity>, int> vx, K<StateT<string, Identity>, int> vy) => \n            vx.Run(\"Hello\").Run().Equals(vy.Run(\"Hello\").Run());\n        \n        var fa = from e in Stateful.get<StateT<string, Identity>, string>()  \n                 from v in StateT<string, Identity, int>.Pure(1)\n                 select e.Length + v;\n                 \n        FunctorLaw<StateT<string, Identity>>.assert(fa, eq);\n    }\n    \n    [Fact]\n    public void Writer()\n    {\n        bool eq(K<Writer<StringM>, int> vx, K<Writer<StringM>, int> vy) => \n            vx.Run(\"Hello, \").Equals(vy.Run(\"Hello, \"));\n        \n        var fa = from _ in Writable.tell<Writer<StringM>, StringM>(\"World\")  \n                 from v in Writer<StringM, int>.Pure(1)\n                 select v;\n        \n        FunctorLaw<Writer<StringM>>.assert(fa, eq);\n    }\n    \n    [Fact]\n    public void WriterT()\n    {\n        bool eq(K<WriterT<StringM, Identity>, int> vx, K<WriterT<StringM, Identity>, int> vy) => \n            vx.Run(\"Hello, \").Run().Equals(vy.Run(\"Hello, \").Run());\n        \n        var fa = from _ in Writable.tell<WriterT<StringM, Identity>, StringM>(\"World\")  \n                 from v in WriterT<StringM, Identity, int>.Pure(1)\n                 select v;\n                 \n        FunctorLaw<WriterT<StringM, Identity>>.assert(fa, eq);\n    }      \n}\n"
  },
  {
    "path": "LanguageExt.Tests/TraitTests/MonadLawsTest.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt.Tests.TraitTests;\n\npublic class MonadLawsTest\n{\n    [Fact]\n    public void Arr() =>\n        MonadLaw<Arr>.assert();\n    \n    [Fact]\n    public void HashSet() =>\n        MonadLaw<HashSet>.assert();\n    \n    [Fact]\n    public void Iterable() =>\n        MonadLaw<Iterable>.assert();\n    \n    [Fact]\n    public void IterableNE() =>\n        MonadLaw<IterableNE>.assert();\n    \n    [Fact]\n    public void Lst() =>\n        MonadLaw<Lst>.assert();\n    \n    [Fact]\n    public void Seq() =>\n        MonadLaw<Seq>.assert();\n    \n    [Fact]\n    public void EffRT()\n    {\n        bool eq(K<Eff<Unit>, int> vx, K<Eff<Unit>, int> vy) => \n            vx.Run(unit).Equals(vy.Run(unit));\n        \n        MonadLaw<Eff<Unit>>.assert(eq);\n    }\n    \n    [Fact]\n    public void Eff()\n    {\n        bool eq(K<Eff, int> vx, K<Eff, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        MonadLaw<Eff>.assert(eq);\n    }\n    \n    [Fact]\n    public void IO()\n    {\n        bool eq(K<IO, int> vx, K<IO, int> vy) => \n            vx.RunSafe().Equals(vy.RunSafe());\n        \n        MonadLaw<IO>.assert(eq);\n    }\n    \n    [Fact]\n    public void StreamT()\n    {\n        // TODO: Restore\n        \n        /*\n        static Seq<int> toSeq(StreamT<Identity, int> s) =>\n            s.Head().Run()\n             .Match(Some: x => x.Cons(toSeq(s.Tail())),\n                    None: []);\n\n        static bool eq(K<StreamT<Identity>, int> vx, K<StreamT<Identity>, int> vy) =>\n            toSeq(vx.As()) == toSeq(vy.As());\n\n        MonadLaw<StreamT<Identity>>.assert(eq);\n    */\n    }\n    \n    [Fact]\n    public void Either() => \n        MonadLaw<Either<string>>.assert();\n\n    [Fact]\n    public void EitherT() => \n        MonadLaw<EitherT<string, Identity>>.assert();\n\n    [Fact]\n    public void Fin() => \n        MonadLaw<Fin>.assert();\n\n    [Fact]\n    public void FinT() => \n        MonadLaw<FinT<Identity>>.assert();\n\n    [Fact]\n    public void Option() => \n        MonadLaw<Option>.assert();\n\n    [Fact]\n    public void OptionT() => \n        MonadLaw<OptionT<Identity>>.assert();\n\n    [Fact]\n    public void Try()\n    {\n        bool eq(K<Try, int> vx, K<Try, int> vy) => \n            vx.Run().Equals(vy.Run());\n        \n        MonadLaw<Try>.assert(eq);\n    }\n    \n    [Fact]\n    public void TryT()\n    {\n        bool eq(K<TryT<Identity>, int> vx, K<TryT<Identity>, int> vy) => \n            vx.Run().Run().Equals(vy.Run().Run());\n        \n        MonadLaw<TryT<Identity>>.assert(eq);\n    }\n    \n    [Fact]\n    public void Validation() => \n        MonadLaw<Validation<StringM>>.assert();\n\n    [Fact]\n    public void ValidationT()\n    {\n        bool eq(K<ValidationT<StringM, Identity>, int> vx, K<ValidationT<StringM, Identity>, int> vy) =>\n            vx.Run().As().Value.Equals(vy.Run().As().Value);\n        \n        MonadLaw<ValidationT<StringM, Identity>>.assert(eq);\n    }\n\n    [Fact]\n    public void Identity() => \n        MonadLaw<Identity>.assert();\n\n    [Fact]\n    public void IdentityT() => \n        MonadLaw<IdentityT<Identity>>.assert();\n\n    [Fact]\n    public void Reader()\n    {\n        bool eq(K<Reader<string>, int> vx, K<Reader<string>, int> vy) => \n            vx.Run(\"Hello\").Equals(vy.Run(\"Hello\"));\n        \n        MonadLaw<Reader<string>>.assert(eq);\n    }\n    \n    [Fact]\n    public void ReaderT()\n    {\n        bool eq(K<ReaderT<string, Identity>, int> vx, K<ReaderT<string, Identity>, int> vy) => \n            vx.Run(\"Hello\").Run().Equals(vy.Run(\"Hello\").Run());\n                 \n        MonadLaw<ReaderT<string, Identity>>.assert(eq);\n    }\n\n    [Fact]\n    public void State()\n    {\n        bool eq(K<State<string>, int> vx, K<State<string>, int> vy) => \n            vx.Run(\"Hello\").Equals(vy.Run(\"Hello\"));\n        \n        MonadLaw<State<string>>.assert(eq);\n    }\n    \n    [Fact]\n    public void StateT()\n    {\n        bool eq(K<StateT<string, Identity>, int> vx, K<StateT<string, Identity>, int> vy) => \n            vx.Run(\"Hello\").Run().Equals(vy.Run(\"Hello\").Run());\n                 \n        MonadLaw<StateT<string, Identity>>.assert(eq);\n    }\n    \n    [Fact]\n    public void Writer()\n    {\n        bool eq(K<Writer<StringM>, int> vx, K<Writer<StringM>, int> vy) => \n            vx.Run(\"Hello, \").Equals(vy.Run(\"Hello, \"));\n        \n        MonadLaw<Writer<StringM>>.assert(eq);\n    }\n    \n    [Fact]\n    public void WriterT()\n    {\n        bool eq(K<WriterT<StringM, Identity>, int> vx, K<WriterT<StringM, Identity>, int> vy) => \n            vx.Run(\"Hello, \").Run().Equals(vy.Run(\"Hello, \").Run());\n        \n        MonadLaw<WriterT<StringM, Identity>>.assert(eq);\n    }    \n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Collections/Arr.cs",
    "content": "using Xunit;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Collections;\n\npublic class ArrArr\n{\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        Arr<Arr<int>> ma = Empty;\n\n        var mb = ma.KindT<Arr, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Arr, Arr<int>, int>()\n                   .As();\n\n        var mc = Arr.singleton(Arr<int>.Empty);\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void ArrArrCrossProduct()\n    {\n        var ma = Array(Array(1, 2), Array(10, 20, 30));\n\n        var mb = ma.KindT<Arr, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Arr, Arr<int>, int>()\n                   .As();\n\n        var mc = Array(\n            Array(1, 10),\n            Array(1, 20),\n            Array(1, 30),\n            Array(2, 10),\n            Array(2, 20),\n            Array(2, 30));\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void ArrOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = Array(Array<int>(), Array(1, 2, 3));\n\n        var mb = ma.KindT<Arr, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Arr, Arr<int>, int>()\n                   .As();\n\n        var mc = Arr<Arr<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void ArrOfEmptiesIsEmpty()\n    {\n        var ma = Array(Array<int>(), Array<int>());\n\n        var mb = ma.KindT<Arr, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Arr, Arr<int>, int>()\n                   .As();\n\n        var mc = Arr<Arr<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Collections/HashSet.cs",
    "content": "using System.Linq;\nusing LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Collections;\n\npublic class HashSetArr\n{\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        HashSet<Arr<int>> ma = Empty;\n\n        var mb = ma.KindT<HashSet, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, HashSet, HashSet<int>, int>()\n                   .As();\n\n        var mc = Arr.singleton(HashSet<int>.Empty);\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void HashSetArrCrossProduct()\n    {\n        var ma = HashSet(Array(1, 2), Array(10, 20, 30));\n\n        var mb = ma.KindT<HashSet, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, HashSet, HashSet<int>, int>()\n                   .As();\n            \n        mb = mb.OrderBy(x => x.ToArray()[1])\n               .OrderBy(x => x.ToArray()[0])\n               .AsIterable()\n               .ToArr();\n\n        var mc = Array(\n            HashSet(1, 10),\n            HashSet(1, 20),\n            HashSet(1, 30),\n            HashSet(2, 10),\n            HashSet(2, 20),\n            HashSet(2, 30));\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void HashSetOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = HashSet(Array<int>(), Array(1, 2, 3));\n            \n        var mb = ma.KindT<HashSet, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, HashSet, HashSet<int>, int>()\n                   .As();\n            \n        var mc = Arr<HashSet<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void HashSetOfEmptiesIsEmpty()\n    {\n        var ma = HashSet(Array<int>(), Array<int>());\n            \n        var mb = ma.KindT<HashSet, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, HashSet, HashSet<int>, int>()\n                   .As();\n            \n        var mc = Arr<HashSet<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Collections/IEnumerable.cs",
    "content": "using Xunit;\nusing System.Linq;\nusing LanguageExt.Traits;\nusing System.Collections.Generic;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Collections;\n\npublic class IEnumerableArr\n{\n    private static Iterable<T> enumerable<T>(params T[] items) => items.AsIterable();\n\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        var ma = Iterable.empty<Arr<int>>();\n\n        var mb = ma.KindT<Iterable, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Iterable, Iterable<int>, int>()\n                   .As();\n\n        var mc = Arr.singleton(Iterable<int>.Empty);\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void IEnumerableArrCrossProduct()\n    {\n        var ma = new[] { Array(1, 2), Array(10, 20, 30) }.AsIterable();\n\n        var mb = ma.KindT<Iterable, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Iterable, Iterable<int>, int>()\n                   .As();\n\n        var mc = Array(\n            enumerable(1, 10),\n            enumerable(1, 20),\n            enumerable(1, 30),\n            enumerable(2, 10),\n            enumerable(2, 20),\n            enumerable(2, 30));\n\n        Assert.True(mb.Map(toArray) == mc.Map(toArray));\n    }\n\n    [Fact]\n    public void IEnumerableOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = enumerable(Array<int>(), Array(1, 2, 3));\n\n        var mb = ma.KindT<Iterable, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Iterable, Iterable<int>, int>()\n                   .As();\n\n        var mc = Arr<Iterable<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void IEnumerableOfEmptiesIsEmpty()\n    {\n        var ma = enumerable(Array<int>(), Array<int>());\n\n        var mb = ma.KindT<Iterable, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Iterable, Iterable<int>, int>()\n                   .As();\n\n        var mc = Arr<Iterable<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Collections/Lst.cs",
    "content": "using Xunit;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Collections;\n\npublic class LstArr\n{\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        Lst<Arr<int>> ma = Empty;\n\n        var mb = ma.KindT<LanguageExt.Lst, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, LanguageExt.Lst, Lst<int>, int>()\n                   .As();\n\n        var mc = Arr.singleton(Lst<int>.Empty);\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void LstArrCrossProduct()\n    {\n        var ma = List(Array(1, 2), Array(10, 20, 30));\n\n        var mb = ma.KindT<LanguageExt.Lst, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, LanguageExt.Lst, Lst<int>, int>()\n                   .As();\n\n        var mc = Array(\n            List(1, 10),\n            List(1, 20),\n            List(1, 30),\n            List(2, 10),\n            List(2, 20),\n            List(2, 30));\n\n        var sb = mb.ToString();\n        var sc = mc.ToString();\n        \n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void LstOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = List(Array<int>(), Array<int>(1, 2, 3));\n\n        var mb = ma.KindT<LanguageExt.Lst, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, LanguageExt.Lst, Lst<int>, int>()\n                   .As();\n\n        var mc = Arr<Lst<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void LstOfEmptiesIsEmpty()\n    {\n        var ma = List(Array<int>(), Array<int>());\n\n        var mb = ma.KindT<LanguageExt.Lst, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, LanguageExt.Lst, Lst<int>, int>()\n                   .As();\n\n        var mc = Arr<Lst<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Collections/Seq.cs",
    "content": "using LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Collections;\n\npublic class SeqArr\n{\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        Seq<Arr<int>> ma = Empty;\n\n        var mb = ma.KindT<Seq, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Seq, Seq<int>, int>()\n                   .As();\n\n        var mc = Arr.singleton(Seq<int>.Empty);\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SeqArrCrossProduct()\n    {\n        var ma = Seq(Array(1, 2), Array(10, 20, 30));\n\n        var mb = ma.KindT<Seq, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Seq, Seq<int>, int>()\n                   .As();\n\n        var mc = Array(\n            Seq(1, 10),\n            Seq(1, 20),\n            Seq(1, 30),\n            Seq(2, 10),\n            Seq(2, 20),\n            Seq(2, 30));\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SeqOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = Seq(Array<int>(), Array<int>(1, 2, 3));\n\n        var mb = ma.KindT<Seq, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Seq, Seq<int>, int>()\n                   .As();\n\n        var mc = Arr<Seq<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SeqOfEmptiesIsEmpty()\n    {\n        var ma = Seq(Array<int>(), Array<int>());\n\n        var mb = ma.KindT<Seq, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Seq, Seq<int>, int>()\n                   .As();\n\n        var mc = Arr<Seq<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Collections/Set.cs",
    "content": "using LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Collections;\n\npublic class SetArr\n{\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        Set<Arr<int>> ma = Empty;\n\n        var mb = ma.KindT<Set, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Set, Set<int>, int>()\n                   .As();\n\n        var mc = Arr.singleton(Set<int>.Empty);\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SetArrCrossProduct()\n    {\n        var ma = Set(Array(1, 2), Array(10, 20, 30));\n\n        var mb = ma.KindT<Set, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Set, Set<int>, int>()\n                   .As();\n\n        var mc = Array(\n            Set(1, 10),\n            Set(1, 20),\n            Set(1, 30),\n            Set(2, 10),\n            Set(2, 20),\n            Set(2, 30));\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SetOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = Set(Array<int>(), Array(1, 2, 3));\n\n        var mb = ma.KindT<Set, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Set, Set<int>, int>()\n                   .As();\n\n        var mc = Arr<Set<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SetOfEmptiesIsEmpty()\n    {\n        var ma = Set(Array<int>(), Array<int>());\n\n        var mb = ma.KindT<Set, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Set, Set<int>, int>()\n                   .As();\n\n        var mc = Arr<Set<int>>.Empty;\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Sync/Either.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Sync;\n\npublic class EitherArr\n{\n    [Fact]\n    public void LeftIsSingletonLeft()\n    {\n        var ma = Left<Error, Arr<int>>(Error.New(\"alt\"));\n\n        var mb = ma.KindT<Either<Error>, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Either<Error>, Either<Error, int>, int>()\n                   .As();\n            \n        var mc = Array(Left<Error, int>(Error.New(\"alt\")));\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void RightEmptyIsEmpty()\n    {\n        var ma = Right<Error, Arr<int>>(Empty);\n        var mb = ma.KindT<Either<Error>, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Either<Error>, Either<Error, int>, int>()\n                   .As();\n        var mc = Array<Either<Error, int>>();\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void RightNonEmptyArrIsArrRight()\n    {\n        var ma = Right<Error, Arr<int>>(Array(1, 2, 3, 4));\n        var mb = ma.KindT<Either<Error>, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Either<Error>, Either<Error, int>, int>()\n                   .As();\n        var mc = Array(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3), Right<Error, int>(4));\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Sync/Identity.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\nusing LanguageExt.Traits;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Sync;\n\npublic class IdentityArr\n{\n    [Fact]\n    public void IdEmptyIsEmpty()\n    {\n        var ma = Id<Arr<int>>(Empty);\n        var mb = ma.KindT<LanguageExt.Identity, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, LanguageExt.Identity, Identity<int>, int>()\n                   .As();\n        var mc = Array<Identity<int>>();\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void IdNonEmptyArrIsArrId()\n    {\n        var ma = Id(Array(1, 2, 3));\n        var mb = ma.KindT<LanguageExt.Identity, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, LanguageExt.Identity, Identity<int>, int>()\n                   .As();\n        var mc = Array(Id(1), Id(2), Id(3));\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Sync/Option.cs",
    "content": "using LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Sync;\n\npublic class OptionArr\n{\n    [Fact]\n    public void NoneIsSingletonNone()\n    {\n        var ma = Option<Arr<int>>.None;\n        var mb = ma.KindT<Option, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Option, Option<int>, int>()\n                   .As();\n        var mc = Array(Option<int>.None);\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SomeEmptyIsEmpty()\n    {\n        var ma = Some<Arr<int>>(Empty);\n        var mb = ma.KindT<Option, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Option, Option<int>, int>()\n                   .As();\n        var mc = Array<Option<int>>();\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SomeNonEmptyArrIsArrSomes()\n    {\n        var ma = Some(Array(1, 2, 3));\n        var mb = ma.KindT<Option, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Option, Option<int>, int>()\n                   .As();\n        var mc = Array(Some(1), Some(2), Some(3));\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Arr/Sync/Validation.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.ArrT.Sync;\n\npublic class ValidationArr\n{\n    [Fact]\n    public void FailIsSingletonFail()\n    {\n        var ma = Fail<Error, Arr<int>>(Error.New(\"alt\"));\n        var mb = ma.KindT<Validation<Error>, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Validation<Error>, Validation<Error, int>, int>()\n                   .As();\n        var mc = Array(Fail<Error, int>(Error.New(\"alt\")));\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SuccessEmptyIsEmpty()\n    {\n        var ma = Success<Error, Arr<int>>(Empty);\n        var mb = ma.KindT<Validation<Error>, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Validation<Error>, Validation<Error, int>, int>()\n                   .As();\n        var mc = Array<Validation<Error, int>>();\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SuccessNonEmptyArrIsArrSuccesses()\n    {\n        var ma = Success<Error, Arr<int>>(Array(1, 2, 3, 4));\n        var mb = ma.KindT<Validation<Error>, Arr, Arr<int>, int>()\n                   .SequenceM()\n                   .AsT<Arr, Validation<Error>, Validation<Error, int>, int>()\n                   .As();\n        var mc = Array(Success<Error, int>(1), Success<Error, int>(2), Success<Error, int>(3), Success<Error, int>(4));\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Collections/Arr.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Collections;\n\npublic class ArrEither\n{\n    [Fact]\n    public void EmptyArrIsRightEmptyArr()\n    {\n        Arr<Either<Error, int>> ma = Empty;\n\n        var mb = ma.KindT<Arr, Either<Error>, Either<Error, int>, int>()\n                   .SequenceM()\n                   .AsT<Either<Error>, Arr, Arr<int>, int>()\n                   .As();\n\n        Assert.True(mb == Right(Arr<int>.Empty));\n    }\n        \n    [Fact]\n    public void ArrRightsIsRightArrs()\n    {\n        var ma = Array(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3));\n\n        var mb = ma.KindT<Arr, Either<Error>, Either<Error, int>, int>()\n                   .SequenceM()\n                   .AsT<Either<Error>, Arr, Arr<int>, int>()\n                   .As();\n\n        Assert.True(mb == Right(Array(1, 2, 3)));\n    }\n        \n    [Fact]\n    public void ArrRightAndLeftIsLeftEmpty()\n    {\n        var ma = Array(Right<Error, int>(1), Right<Error, int>(2), Left<Error, int>(Error.New(\"alternative\")));\n\n        var mb = ma.KindT<Arr, Either<Error>, Either<Error, int>, int>()\n                   .SequenceM()\n                   .AsT<Either<Error>, Arr, Arr<int>, int>()\n                   .As() ; \n\n        Assert.True(mb == Left(Error.New(\"alternative\")));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Collections/HashSet.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Collections;\n\npublic class HashSetEither\n{\n    [Fact]\n    public void EmptyHashSetIsRightEmptyHashSet()\n    {\n        HashSet<Either<Error, int>> ma = Empty;\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Right(HashSet<int>.Empty));\n    }\n        \n    [Fact]\n    public void HashSetRightsIsRightHashSets()\n    {\n        var ma = HashSet(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3));\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Right(HashSet(1, 2, 3)));\n    }\n        \n    [Fact]\n    public void HashSetRightAndLeftIsLeftEmpty()\n    {\n        var ma = HashSet(Right<Error, int>(1), Right<Error, int>(2), Left<Error, int>(Error.New(\"alternative\")));\n        \n        var mb = ma.Traverse(x => x).As();\n        \n        Assert.True(mb == Left(Error.New(\"alternative\")));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Collections/IEnumerable.cs",
    "content": "using System.Linq;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Collections;\n\npublic class IEnumerableEither\n{\n    [Fact]\n    public void EmptyIEnumerableIsRightEmptyIEnumerable()\n    {\n        var ma = Iterable.empty<Either<Error, int>>();\n\n        var mb = ma.Traverse(x => x).As();\n\n        var mr = mb.Map(b => ma.Count() == b.Count())\n                   .IfLeft(false);\n            \n        Assert.True(mr);\n    }\n\n    [Fact]\n    public void IEnumerableRightsIsRightIEnumerables()\n    {\n        var ma = new[] {Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3)}.AsIterable();\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb.Map(b => EqEnumerable<int>.Equals(b, new[] {1, 2, 3}.AsEnumerable())).IfLeft(false));\n    }\n\n    [Fact]\n    public void IEnumerableRightAndLeftIsLeftEmpty()\n    {\n        var ma = new[] {Right<Error, int>(1), Right<Error, int>(2), Left<Error, int>(Error.New(\"alternative\"))}.AsIterable();\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Left(Error.New(\"alternative\")));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Collections/Lst.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Collections;\n\npublic class LstEither\n{\n    [Fact]\n    public void EmptyLstIsRightEmptyLst()\n    {\n        Lst<Either<Error, int>> ma = Empty;\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Right(Lst<int>.Empty));\n    }\n        \n    [Fact]\n    public void LstRightsIsRightLsts()\n    {\n        var ma = List(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3));\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Right(List(1, 2, 3)));\n    }\n        \n    [Fact]\n    public void LstRightAndLeftIsLeftEmpty()\n    {\n        var ma = List(Right<Error, int>(1), Right<Error, int>(2), Left<Error, int>(Error.New(\"alternative\")));\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Left(Error.New(\"alternative\")));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Collections/Seq.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Collections;\n\npublic class SeqEither\n{\n    [Fact]\n    public void EmptySeqIsRightEmptySeq()\n    {\n        Seq<Either<Error, int>> ma = Empty;\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Right(Seq<int>.Empty));\n    }\n        \n    [Fact]\n    public void SeqRightsIsRightSeqs()\n    {\n        var ma = Seq(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3));\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Right(Seq(1, 2, 3)));\n    }\n        \n    [Fact]\n    public void SeqRightAndLeftIsLeftEmpty()\n    {\n        var ma = Seq(Right<Error, int>(1), Right<Error, int>(2), Left<Error, int>(Error.New(\"alternative\")));\n\n        var mb = ma.KindT<Seq, Either<Error>, Either<Error, int>, int>()\n                   .SequenceM()\n                   .AsT<Either<Error>, Seq, Seq<int>, int>()\n                   .As();\n\n        Assert.True(mb == Left(Error.New(\"alternative\")));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Collections/Set.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Collections;\n\npublic class SetEither\n{\n    [Fact]\n    public void EmptySetIsRightEmptySet()\n    {\n        Set<Either<Error, int>> ma = Empty;\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Right(Set<int>.Empty));\n    }\n        \n    [Fact]\n    public void SetRightsIsRightSets()\n    {\n        var ma = Set(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3));\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Right(Set(1, 2, 3)));\n    }\n        \n    [Fact]\n    public void SetRightAndLeftIsLeftEmpty()\n    {\n        var ma = Set(Right<Error, int>(1), Right<Error, int>(2), Left<Error, int>(Error.New(\"alternative\")));\n\n        var mb = ma.Traverse(x => x).As();\n\n        Assert.True(mb == Left(Error.New(\"alternative\")));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Sync/Either.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Sync;\n\npublic class EitherEither\n{\n    [Fact]\n    public void LeftIsRightLeft()\n    {\n        var ma = Left<Error, Either<Error, int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Right<Error, Either<Error, int>>(Error.New(\"alt\"));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void RightLeftIsLeft()\n    {\n        var ma = Right<Error, Either<Error, int>>(Left(Error.New(\"alt\")));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Left<Error, Either<Error, int>>(Error.New(\"alt\"));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void RightRightIsRight()\n    {\n        var ma = Right<Error, Either<Error, int>>(Right(1234));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Right<Error, Either<Error, int>>(Right(1234));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Sync/Identity.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Sync;\n\npublic class IdentityEither\n{\n    [Fact]\n    public void IdentityLeftIsLeft()\n    {\n        var ma = new Identity<Either<Error, int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Left<Error, Identity<int>>(Error.New(\"alt\"));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void IdentityRightIsRightIdentity()\n    {\n        var ma = new Identity<Either<Error, int>>(1234);\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Right<Error, Identity<int>>(new Identity<int>(1234));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Sync/Option.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Sync;\n\npublic class OptionEither\n{\n    [Fact]\n    public void NoneLeftIsRightNone()\n    {\n        var ma = Option<Either<Error, int>>.None;\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Right<Error, Option<int>>(None);\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void SomeLeftIsLeft()\n    {\n        var ma = Some<Either<Error, int>>(Left(Error.New(\"alt\")));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Left<Error, Option<int>>(Error.New(\"alt\"));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void SomeRightIsRight()\n    {\n        var ma = Some<Either<Error, int>>(Right(1234));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Right<Error, Option<int>>(Some(1234));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Either/Sync/ValidationSeq.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.EitherT.Sync;\n\npublic class ValidationSeqEither\n{\n    [Fact]\n    public void FailIsRightFail()\n    {\n        var ma = Fail<Error, Either<Error, int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Right<Error, Validation<Error, int>>(Error.New(\"alt\"));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void SuccessLeftIsLeft()\n    {\n        var ma = Success<Error, Either<Error, int>>(Left(Error.New(\"alt\")));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Left<Error, Validation<Error, int>>(Error.New(\"alt\"));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void SuccessRightIsRight()\n    {\n        var ma = Success<Error, Either<Error, int>>(Right(1234));\n        var mb = ma.Traverse(mx => mx).As();\n        var mc = Right<Error, Validation<Error, int>>(Success<Error, int>(1234));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Collections/Arr.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Collections\n{\n    public class ArrHashSet\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Arr<HashSet<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet.singleton(Arr<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void ArrHashSetCrossProduct()\n        {\n            var ma = Array(HashSet(1, 2), HashSet(10, 20, 30));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet(Array(1, 10), Array(1, 20), Array(1, 30), Array(2, 10), Array(2, 20), Array(2, 30));\n            \n            Assert.True(mb == mc);\n        }\n        \n                \n        [Fact]\n        public void ArrOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Array(HashSet<int>(), HashSet<int>(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet<Arr<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void ArrOfEmptiesIsEmpty()\n        {\n            var ma = Array(HashSet<int>(), HashSet<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet<Arr<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Collections/HashSet.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Collections;\n\npublic class HashSetHashSet\n{\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        HashSet<HashSet<int>> ma = Empty;\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mc = HashSet.singleton(HashSet<int>.Empty);\n            \n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void HashSetHashSetCrossProduct()\n    {\n        var ma = HashSet(HashSet(1, 2), HashSet(10, 20, 30));\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mc = HashSet(HashSet(1, 10), HashSet(1, 20), HashSet(1, 30), HashSet(2, 10), HashSet(2, 20), HashSet(2, 30));\n            \n        Assert.True(mb == mc);\n    }\n        \n                \n    [Fact]\n    public void HashSetOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = HashSet(HashSet<int>(), HashSet<int>(1, 2, 3));\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mc = HashSet<HashSet<int>>.Empty;\n            \n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void HashSetOfEmptiesIsEmpty()\n    {\n        var ma = HashSet(HashSet<int>(), HashSet<int>());\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mc = HashSet<HashSet<int>>.Empty;\n            \n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Collections/Lst.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Collections;\n\npublic class LstHashSet\n{\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        Lst<HashSet<int>> ma = Empty;\n\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = HashSet.singleton(Lst<int>.Empty);\n            \n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void LstHashSetCrossProduct()\n    {\n        var ma = List(HashSet(1, 2), HashSet(10, 20, 30));\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mc = HashSet(List(1, 10), List(1, 20), List(1, 30), List(2, 10), List(2, 20), List(2, 30));\n            \n        Assert.True(mb == mc);\n    }\n        \n                \n    [Fact]\n    public void LstOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = List(HashSet<int>(), HashSet<int>(1, 2, 3));\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mc = HashSet<Lst<int>>.Empty;\n            \n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void LstOfEmptiesIsEmpty()\n    {\n        var ma = List(HashSet<int>(), HashSet<int>());\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mc = HashSet<Lst<int>>.Empty;\n            \n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Collections/Seq.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Collections\n{\n    public class SeqHashSet\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Seq<HashSet<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = HashSet.singleton(Seq<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SeqHashSetCrossProduct()\n        {\n            var ma = Seq(HashSet(1, 2), HashSet(10, 20, 30));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet(Seq(1, 10), Seq(1, 20), Seq(1, 30), Seq(2, 10), Seq(2, 20), Seq(2, 30));\n            \n            Assert.True(mb == mc);\n        }\n        \n                \n        [Fact]\n        public void SeqOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Seq(HashSet<int>(), HashSet<int>(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet<Seq<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SeqOfEmptiesIsEmpty()\n        {\n            var ma = Seq(HashSet<int>(), HashSet<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet<Seq<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Collections/Set.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Collections\n{\n    public class SetHashSet\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Set<HashSet<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = HashSet.singleton(Set<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SetHashSetCrossProduct()\n        {\n            var ma = Set(HashSet(1, 2), HashSet(10, 20, 30));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet(Set(1, 10), Set(1, 20), Set(1, 30), Set(2, 10), Set(2, 20), Set(2, 30));\n            \n            Assert.True(mb == mc);\n        }\n        \n                \n        [Fact]\n        public void SetOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Set(HashSet<int>(), HashSet<int>(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet<Set<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SetOfEmptiesIsEmpty()\n        {\n            var ma = Set(HashSet<int>(), HashSet<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = HashSet<Set<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Sync/Either.cs",
    "content": "using System;\nusing Xunit;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Sync\n{\n    public class EitherHashSet\n    {\n        [Fact]\n        public void LeftIsSingletonLeft()\n        {\n            var ma = Left<Error, HashSet<int>>(Error.New(\"alt\"));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = HashSet(Left<Error, int>(Error.New(\"alt\")));\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void RightEmptyIsEmpty()\n        {\n            var ma = Right<Error, HashSet<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = HashSet<Either<Error, int>>();\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void RightNonEmptyHashSetIsHashSetRight()\n        {\n            var ma = Right<Error, HashSet<int>>(HashSet(1, 2, 3, 4));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = HashSet(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3), Right<Error, int>(4));\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Sync/Identity.cs",
    "content": "using System;\nusing Xunit;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Sync\n{\n    public class IdentityHashSet\n    {\n        [Fact]\n        public void IdEmptyIsEmpty()\n        {\n            var ma = Id<HashSet<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = HashSet<Identity<int>>();\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void IdNonEmptyHashSetIsHashSetId()\n        {\n            var ma = Id(HashSet(1, 2, 3));\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = HashSet(Id(1), Id(2), Id(3));\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Sync/Option.cs",
    "content": "using System;\nusing Xunit;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Sync\n{\n    public class OptionHashSet\n    {\n        [Fact]\n        public void NoneIsSingletonNone()\n        {\n            var ma = Option<HashSet<int>>.None;\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = HashSet(Option<int>.None);\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SomeEmptyIsEmpty()\n        {\n            var ma = Some<HashSet<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = HashSet<Option<int>>();\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SomeNonEmptyHashSetIsHashSetSomes()\n        {\n            var ma = Some(HashSet(1, 2, 3));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = HashSet(Some(1), Some(2), Some(3)); \n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/HashSet/Sync/ValidationSeq.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.HashSetT.Sync;\n\npublic class ValidationSeqHashSet\n{\n    [Fact]\n    public void FailIsSingletonFail()\n    {\n        var ma = Fail<Error, HashSet<int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = HashSet(Fail<Error, int>(Error.New(\"alt\")));\n\n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void SuccessEmptyIsEmpty()\n    {\n        var ma = Success<Error, HashSet<int>>(Empty);\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = HashSet<Validation<Error, int>>();\n\n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void SuccessNonEmptyHashSetIsHashSetSuccesses()\n    {\n        var ma = Success<Error, HashSet<int>>(HashSet(1, 2, 3, 4));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = HashSet(Success<Error, int>(1), Success<Error, int>(2), Success<Error, int>(3), Success<Error, int>(4));\n            \n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/IEnumerable/Collections/Arr.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.IEnumerableT.Collections\n{\n    public class ArrIEnumerable\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Arr<Iterable<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Iterable.singleton(Arr.empty<int>());\n\n            Assert.True(mb.ToSeq() == mc.ToSeq());\n        }\n\n        [Fact]\n        public void ArrIEnumerableCrossProduct()\n        {\n            var ma = Array<Iterable<int>>([1, 2], [10, 20, 30]);\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = Iterable.create(\n                    Array(1, 10),\n                    Array(1, 20),\n                    Array(1, 30),\n                    Array(2, 10),\n                    Array(2, 20),\n                    Array(2, 30));\n\n            var r = mb == mc;\n            Assert.True(r);\n        }\n\n        [Fact]\n        public void ArrOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Array<Iterable<int>>([], [1, 2, 3]);\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Iterable.empty<Arr<int>>();\n\n            Assert.True(mb.ToSeq() == mc.ToSeq());\n        }\n\n        [Fact]\n        public void ArrOfEmptiesIsEmpty()\n        {\n            var ma = Array<Iterable<int>>([], []);\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Iterable.empty<Arr<int>>();\n\n            Assert.True(mb.ToSeq() == mc.ToSeq());\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/IEnumerable/Collections/HashSet.cs",
    "content": "using System.Linq;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.IEnumerableT.Collections;\n\npublic class HashSetIEnumerable\n{\n    [Fact]\n    public void EmptyEmptyIsEmptyEmpty()\n    {\n        HashSet<Iterable<int>> ma = Empty;\n\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Iterable.singleton(HashSet.empty<int>());\n\n        Assert.True(mb.ToSeq() == mc.ToSeq());\n    }\n\n    [Fact]\n    public void HashSetIEnumerableCrossProduct()\n    {\n        var ma = HashSet<Iterable<int>>([1, 2], [10, 20, 30]);\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mc = new[]\n            {\n                HashSet(1, 10),\n                HashSet(1, 20),\n                HashSet(1, 30),\n                HashSet(2, 10),\n                HashSet(2, 20),\n                HashSet(2, 30)\n            };\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n\n    [Fact]\n    public void HashSetOfEmptiesAndNonEmptiesIsEmpty()\n    {\n        var ma = HashSet<Iterable<int>>([], [1, 2, 3]);\n\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Enumerable.Empty<HashSet<int>>();\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n\n    [Fact]\n    public void HashSetOfEmptiesIsEmpty()\n    {\n        var ma = HashSet<Iterable<int>>([], []);\n\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Iterable.empty<HashSet<int>>();\n\n        Assert.True(mb.ToSeq() == mc.ToSeq());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/IEnumerable/Sync/Either.cs",
    "content": "using System.Linq;\nusing LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.IEnumerableT.Sync;\n\npublic class EitherIEnumerable\n{\n    [Fact]\n    public void LeftIsSingletonLeft()\n    {\n        var ma = Left<Error, Iterable<int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = new[] { Left<Error, int>(Error.New(\"alt\")) }.AsEnumerable();\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n\n    [Fact]\n    public void RightEmptyIsEmpty()\n    {\n        var ma = Right<Error, Iterable<int>>(Iterable.empty<int>());\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Enumerable.Empty<Either<Error, int>>();\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n\n    [Fact]\n    public void RightNonEmptyIEnumerableIsIEnumerableRight()\n    {\n        var ma = Right<Error, Iterable<int>>([1, 2, 3, 4]);\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = new[] { Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3), Right<Error, int>(4) };\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/IEnumerable/Sync/Identity.cs",
    "content": "using System.Linq;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.IEnumerableT.Sync;\n\npublic class IdentityIEnumerable\n{\n    [Fact]\n    public void IdEmptyIsEmpty()\n    {\n        var ma = Id(Iterable.empty<int>());\n        var mb = ma.Traverse(identity).As();\n        var mc = Iterable.empty<Identity<int>>();\n\n        Assert.True(mb.ToSeq() == mc.ToSeq());\n    }\n\n    [Fact]\n    public void IdNonEmptyIEnumerableIsIEnumerableId()\n    {\n        var ma = Id(Iterable.create([1, 2, 3]));\n        var mb = ma.Traverse(identity).As();\n        var mc = new[] { Id(1), Id(2), Id(3) }.AsEnumerable();\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/IEnumerable/Sync/Option.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.IEnumerableT.Sync\n{\n    public class OptionIEnumerable\n    {\n        [Fact]\n        public void NoneIsSingletonNone()\n        {\n            var ma = Option<Iterable<int>>.None;\n            var mb = ma.Traverse(mx => mx).As();\n\n            IEnumerable<Option<int>> mc = new[] { Option<int>.None };\n\n            Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n        }\n\n        [Fact]\n        public void SomeEmptyIsEmpty()\n        {\n            var ma = Some(Iterable.empty<int>());\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Enumerable.Empty<Option<int>>();\n\n            Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n        }\n\n        [Fact]\n        public void SomeNonEmptyIEnumerableIsIEnumerableSomes()\n        {\n            var ma = Some(new[] { 1, 2, 3 }.AsIterable());\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = new[] { Some(1), Some(2), Some(3) }.AsEnumerable();\n\n            Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/IEnumerable/Sync/ValidationSeq.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.IEnumerableT.Sync;\n\npublic class ValidationIEnumerable\n{\n    [Fact]\n    public void FailIsSingletonFail()\n    {\n        var ma = Fail<Error, Iterable<int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n\n        IEnumerable<Validation<Error, int>> mc = new[] { Fail<Error, int>(Error.New(\"alt\")) };\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n\n    [Fact]\n    public void SuccessEmptyIsEmpty()\n    {\n        var ma = Success<Error, Iterable<int>>(Iterable.empty<int>());\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Enumerable.Empty<Validation<Error, int>>();\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n\n    [Fact]\n    public void SuccessNonEmptyIEnumerableIsIEnumerableSuccesses()\n    {\n        var ma = Success<Error, Iterable<int>>([1, 2, 3, 4]);\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = new[]\n                 {\n                     Success<Error, int>(1),\n                     Success<Error, int>(2),\n                     Success<Error, int>(3),\n                     Success<Error, int>(4)\n                 }.AsEnumerable();\n\n        Assert.True(mb.ToSeq() == mc.AsIterable().ToSeq());\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Collections/Arr.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Collections\n{\n    public class ArrIdentity\n    {\n        [Fact]\n        public void EmptyArrayIsSuccess()\n        {\n            Arr<Identity<int>> ma = Empty;\n\n            var mb = ma.Traverse(identity);\n            \n            Assert.Equal(Id(Arr<int>.Empty), mb);\n        }\n\n        [Fact]\n        public void ArrOfIdentitiesIsIdentityOfArr()\n        {\n            var ma = Array(Id(1), Id(3), Id(5));\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(Array(1, 3, 5)), mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Collections/HashSet.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Collections\n{\n    public class HashSet\n    {\n        [Fact]\n        public void EmptyHashSetIsSuccess()\n        {\n            HashSet<Identity<int>> ma = Empty;\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(HashSet<int>.Empty), mb);\n        }\n\n        [Fact]\n        public void HashSetOfIdentitiesIsSuccess()\n        {\n            var ma = HashSet(Id(1), Id(3), Id(5));\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(HashSet(1, 3, 5)), mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Collections/IEnumerable.cs",
    "content": "﻿using LanguageExt.Traits;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Collections\n{\n    public class IEnumerable\n    {\n        [Fact]\n        public void EmptyIEnumerableIsEmpty()\n        {\n            var ma = Iterable.empty<Identity<int>>();\n\n            var mb = ma.Traverse(x => x).As();\n\n            Assert.True(Id(Iterable.empty<int>()) == mb);\n        }\n\n        [Fact]\n        public void EnumerableOfIdentitiesIsIdentityOfEnumerable()\n        {\n            var ma = Iterable.create(Id(1), Id(3), Id(5));\n\n            var mb = ma.Traverse(x => x).As();\n\n            Assert.True(Id(Iterable.create(1, 3, 5)) == mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Collections/Lst.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Collections\n{\n    public class LstIdentity\n    {\n        [Fact]\n        public void EmptyLstIsEmpty()\n        {\n            var ma = Lst<Identity<int>>.Empty;\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(Lst<int>.Empty), mb);\n        }\n\n        [Fact]\n        public void LstOfIdentitiesIsIdentityOfLst()\n        {\n            var ma = List(Id(1), Id(3), Id(5));\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(List(1, 3, 5)), mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Collections/Seq.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Collections\n{\n    public class Seq\n    {\n        [Fact]\n        public void EmptySeqIsEmpty()\n        {\n            var ma = Seq<Identity<int>>.Empty;\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(Seq<int>.Empty), mb);\n        }\n\n        [Fact]\n        public void SeqOfIdentitiesIsIdentityOfSeq()\n        {\n            var ma = Seq(Id(1), Id(3), Id(5));\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(Seq(1, 3, 5)), mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Collections/Set.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Collections\n{\n    public class Set\n    {\n        [Fact]\n        public void EmptySetIsEmpty()\n        {\n            var ma = Set<Identity<int>>.Empty;\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(Set<int>.Empty), mb);\n        }\n\n        [Fact]\n        public void SetOfIdentitiesIsIdentityOfSet()\n        {\n            var ma = Set(Id(1), Id(3), Id(5));\n\n            var mb = ma.Traverse(identity);\n\n            Assert.Equal(Id(Set(1, 3, 5)), mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Sync/Either.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Sync\n{\n    public class Either\n    {\n        [Fact]\n        public void LeftIsIdentityLeft()\n        {\n            var ma = Left<Error, Identity<int>>(Error.New(\"An Error\"));\n            \n            var mb = ma.Traverse(identity);\n\n            var mc = Id(Left<Error, int>(Error.New(\"An Error\")));\n            \n            Assert.Equal(mc, mb);\n        }\n\n        [Fact]\n        public void RightIsIdentityRight()\n        {\n            var ma = Right<Error, Identity<int>>(Id(42));\n            \n            var mb = ma.Traverse(identity);\n            \n            var mc = Id(Right<Error, int>(42));\n            \n            Assert.Equal(mc, mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Sync/Identity.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Sync\n{\n    public class Identity\n    {\n        [Fact]\n        public void IdentityIdentityIsIdentityIdentity()\n        {\n            var ma = Id(Id(42));\n            \n            var mb = ma.Traverse(identity);\n\n            var mc = Id(Id(42));\n\n            Assert.Equal(mc, mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Sync/Option.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Sync\n{\n    public class Option\n    {\n        [Fact]\n        public void SomeIdentityIsIdentitySome()\n        {\n            var ma = Some(Id(42));\n\n            var mb = ma.Traverse(identity);\n\n            var mc = Id(Some(42));\n\n            Assert.Equal(mc, mb);\n        }\n\n        [Fact]\n        public void NoneIdentityIsIdentityNone()\n        {\n            var ma = Option<Identity<int>>.None;\n\n            var mb = ma.Traverse(identity);\n\n            var mc = Id(Option<int>.None);\n\n            Assert.Equal(mc, mb);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Identity/Sync/ValidationSeq.cs",
    "content": "﻿using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Identity.Sync;\n\npublic class ValidationSeq\n{\n    [Fact]\n    public void ValidationFailIsIdentityFail()\n    {\n        var ma = Fail<Error, Identity<int>>(Error.New(\"An Error\"));\n\n        var mb = ma.Traverse(identity);\n\n        var mc = Id(Fail<Error, int>(Error.New(\"An Error\")));\n\n        Assert.Equal(mc, mb);\n    }\n\n    [Fact]\n    public void ValidationSuccIsIdentitySuccess()\n    {\n        var ma = Success<Error, Identity<int>>(Id(42));\n\n        var mb = ma.Traverse(identity);\n\n        var mc = Id(Success<Error, int>(42));\n\n        Assert.Equal(mc, mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Collections/Arr.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Collections\n{\n    public class ArrLst\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Arr<Lst<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = List.singleton(Arr<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void ArrLstCrossProduct()\n        {\n            var ma = Array(List(1, 2), List(10, 20, 30));\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = List(\n                Array(1, 10), \n                Array(1, 20), \n                Array(1, 30), \n                Array(2, 10), \n                Array(2, 20), \n                Array(2, 30));\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void ArrOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Array(List<int>(), List(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = List<Arr<int>>();\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void ArrOfEmptiesIsEmpty()\n        {\n            var ma = Array(List<int>(), List<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = List<Arr<int>>();\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Collections/HashSet.cs",
    "content": "using System;\nusing System.Linq;\nusing Xunit;\nusing Xunit.Abstractions;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Collections\n{\n    public class HashSetLst\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            HashSet<Lst<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = List.singleton(HashSet<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void HashSetLstCrossProduct()\n        {\n            var ma = HashSet(List(1, 2), List(10, 20, 30));\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = List(\n                HashSet(1, 10), \n                HashSet(1, 20), \n                HashSet(1, 30), \n                HashSet(2, 10), \n                HashSet(2, 20), \n                HashSet(2, 30));\n\n            var tb = mb.ToString();\n            var tc = mc.ToString();\n            \n            Assert.True(mb == mc);\n        }\n        \n                \n        [Fact]\n        public void HashSetOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = HashSet(List<int>(), List(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Lst<HashSet<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void HashSetOfEmptiesIsEmpty()\n        {\n            var ma = HashSet(List<int>(), List<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Lst<HashSet<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Collections/IEnumerable.cs",
    "content": "using System.Linq;\nusing Xunit;\nusing G = System.Collections.Generic;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Collections\n{\n    using static Prelude;\n    \n    public class IEnumerableLst\n    {\n        G.IEnumerable<T> mkEnum<T>(params T[] ts)\n        {\n            foreach (var t in ts)\n                yield return t;\n        }\n        \n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            var ma = Iterable<Lst<int>>();\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = LanguageExt.List.singleton<Iterable<int>>(Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void EnumLstCrossProduct()\n        {\n            var ma = mkEnum(List(1, 2), List(10, 20, 30)).AsIterable();\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List(\n                mkEnum(1, 10), \n                mkEnum(1, 20), \n                mkEnum(1, 30), \n                mkEnum(2, 10), \n                mkEnum(2, 20), \n                mkEnum(2, 30));\n            \n            Assert.True(mb.Map(toList) == mc.Map(toList));\n            \n        }\n                \n        [Fact]\n        public void SeqOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = mkEnum(List<int>(), List(1, 2, 3)).AsIterable();\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Lst<Iterable<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SeqOfEmptiesIsEmpty()\n        {\n            var ma = mkEnum(List<int>(), List<int>()).AsIterable();\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Lst<Iterable<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Collections/Lst.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Collections\n{\n    public class LstLst\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Lst<Lst<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = List.singleton(Lst<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void LstLstCrossProduct()\n        {\n            var ma = List(List(1, 2), List(10, 20, 30));\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = List(\n                List(1, 10), \n                List(1, 20), \n                List(1, 30), \n                List(2, 10), \n                List(2, 20), \n                List(2, 30));\n            Assert.True(mb == mc);\n        }\n                \n        [Fact]\n        public void LstOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = List(List<int>(), List(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Lst<Lst<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void LstOfEmptiesIsEmpty()\n        {\n            var ma = List(List<int>(), List<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Lst<Lst<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Collections/Seq.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Collections\n{\n    public class SeqLst\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Seq<Lst<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List.singleton(Seq<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SeqLstCrossProduct()\n        {\n            var ma = Seq(List(1, 2), List(10, 20, 30));\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = List(\n                Seq(1, 10), \n                Seq(1, 20), \n                Seq(1, 30), \n                Seq(2, 10), \n                Seq(2, 20), \n                Seq(2, 30));\n            \n            Assert.True(mb == mc);\n        }\n                \n        [Fact]\n        public void SeqOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Seq(List<int>(), List(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Lst<Seq<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SeqOfEmptiesIsEmpty()\n        {\n            var ma = Seq(List<int>(), List<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Lst<Seq<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Collections/Set.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Collections\n{\n    public class SetLst\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Set<Lst<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List.singleton(Set<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SetLstCrossProduct()\n        {\n            var ma = Set(List(1, 2), List(10, 20, 30));\n\n            var mb = ma.Traverse(mx => mx).As();\n            var mbb = ma.Traverse(x => x).As();\n\n            var mc = List(\n                Set(1, 10), \n                Set(1, 20), \n                Set(1, 30), \n                Set(2, 10), \n                Set(2, 20), \n                Set(2, 30));\n            \n            Assert.True(mb == mc);\n            Assert.True(mbb == mc);\n        }\n        \n                \n        [Fact]\n        public void SetOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Set(List<int>(), List(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Lst<Set<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SetOfEmptiesIsEmpty()\n        {\n            var ma = Set(List<int>(), List<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Lst<Set<int>>.Empty;\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Sync/Either.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Sync\n{\n    public class EitherLst\n    {\n        [Fact]\n        public void LeftIsSingletonLeft()\n        {\n            var ma = Left<Error, Lst<int>>(Error.New(\"alt\"));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List(Left<Error, int>(Error.New(\"alt\")));\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void RightEmptyIsEmpty()\n        {\n            var ma = Right<Error, Lst<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List<Either<Error, int>>();\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void RightNonEmptyLstIsLstRight()\n        {\n            var ma = Right<Error, Lst<int>>(List(1, 2, 3, 4));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3), Right<Error, int>(4));\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Sync/Identity.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Sync;\n\npublic class IdentityLst\n{\n    [Fact]\n    public void IdEmptyIsEmpty()\n    {\n        var ma = Id<Lst<int>>(Empty);\n        var mb = ma.Traverse(x => x).As();\n        var mc = List<Identity<int>>();\n\n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void IdNonEmptyLstIsLstId()\n    {\n        var ma = Id(List(1, 2, 3));\n        var mb = ma.Traverse(x => x).As();\n        var mc = List(Id(1), Id(2), Id(3));\n            \n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Sync/Option.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Sync\n{\n    public class OptionLst\n    {\n        [Fact]\n        public void NoneIsSingletonNone()\n        {\n            var ma = Option<Lst<int>>.None;\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List(Option<int>.None);\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SomeEmptyIsEmpty()\n        {\n            var ma = Some<Lst<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List<Option<int>>();\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SomeNonEmptyLstIsLstSomes()\n        {\n            var ma = Some(List(1, 2, 3));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List(Some(1), Some(2), Some(3)); \n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Lst/Sync/ValidationSeq.cs",
    "content": "using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Lst.Sync;\n\npublic class ValidationSeqLst\n{\n    [Fact]\n    public void FailIsSingletonFail()\n    {\n        var ma = Fail<Error, Lst<int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = List(Fail<Error, int>(Error.New(\"alt\")));\n\n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void SuccessEmptyIsEmpty()\n    {\n        var ma = Success<Error, Lst<int>>(Empty);\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = List<Validation<Error, int>>();\n\n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void SuccessNonEmptyLstIsLstSuccesses()\n    {\n        var ma = Success<Error, Lst<int>>(List(1, 2, 3, 4));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = List(Success<Error, int>(1), Success<Error, int>(2), Success<Error, int>(3), Success<Error, int>(4));\n            \n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Collections/Arr.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Collections;\n\npublic class ArrOption\n{\n    [Fact]\n    public void EmptyArrIsSomeEmptyArr()\n    {\n        Arr<Option<int>> ma = Empty;\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == Some(Arr<int>.Empty));\n    }\n        \n    [Fact]\n    public void ArrSomesIsSomeArrs()\n    {\n        var ma = Array(Some(1), Some(2), Some(3));\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == Some(Array(1, 2, 3)));\n    }\n        \n    [Fact]\n    public void ArrSomeAndNoneIsNone()\n    {\n        var ma = Array(Some(1), Some(2), None);\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == None);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Collections/HashSet.cs",
    "content": "using LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Collections\n{\n    public class HashSetOption\n    {\n        [Fact]\n        public void EmptyHashSetIsSomeEmptyHashSet()\n        {\n            HashSet<Option<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            Assert.True(mb == Some(HashSet<int>.Empty));\n        }\n        \n        [Fact]\n        public void HashSetSomesIsSomeHashSets()\n        {\n            var ma = HashSet(Some(1), Some(2), Some(3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            Assert.True(mb == Some(HashSet(1, 2, 3)));\n        }\n        \n        [Fact]\n        public void HashSetSomeAndNoneIsNone()\n        {\n            var ma = HashSet(Some(1), Some(2), None);\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            Assert.True(mb == None);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Collections/IEnumerable.cs",
    "content": "using System.Linq;\nusing LanguageExt.ClassInstances;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Collections;\n\npublic class IEnumerableOption\n{\n    [Fact]\n    public void EmptyIEnumerableIsSomeEmptyIEnumerable()\n    {\n        var ma = Iterable.empty<Option<int>>();\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        var mr = mb.Map(b => ma.Count() == b.Count())\n                   .IfNone(false);\n            \n        Assert.True(mr);\n    }\n\n    [Fact]\n    public void IEnumerableSomesIsSomeIEnumerables()\n    {\n        var ma = new[] {Some(1), Some(2), Some(3)}.AsIterable();\n\n        var mb = ma.Traverse(mx => mx).As();\n\n        Assert.True(mb.Map(b => EqEnumerable<int>.Equals(b, new[] {1, 2, 3}.AsEnumerable())).IfNone(false));\n    }\n\n    [Fact]\n    public void IEnumerableSomeAndNoneIsNone()\n    {\n        var ma = new[] {Some(1), Some(2), None}.AsIterable();\n        var mb = ma.Traverse(mx => mx).As();\n        Assert.True(mb == None);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Collections/Lst.cs",
    "content": "using LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Collections\n{\n    public class LstOption\n    {\n        [Fact]\n        public void EmptyLstIsSomeEmptyLst()\n        {\n            Lst<Option<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            Assert.True(mb == Some(Lst<int>.Empty));\n        }\n        \n        [Fact]\n        public void LstSomesIsSomeLsts()\n        {\n            var ma = List(Some(1), Some(2), Some(3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            Assert.True(mb == Some(List(1, 2, 3)));\n        }\n        \n        [Fact]\n        public void LstSomeAndNoneIsNone()\n        {\n            var ma = List(Some(1), Some(2), None);\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            Assert.True(mb == None);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Collections/Seq.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Collections;\n\npublic class SeqOption\n{\n    [Fact]\n    public void EmptySeqIsSomeEmptySeq()\n    {\n        Seq<Option<int>> ma = Empty;\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == Some(Seq<int>.Empty));\n    }\n        \n    [Fact]\n    public void SeqSomesIsSomeSeqs()\n    {\n        var ma = Seq(Some(1), Some(2), Some(3));\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == Some(Seq(1, 2, 3)));\n    }\n        \n    [Fact]\n    public void SeqSomeAndNoneIsNone()\n    {\n        var ma = Seq(Some(1), Some(2), None);\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == None);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Collections/Set.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Collections;\n\npublic class SetOption\n{\n    [Fact]\n    public void EmptySetIsSomeEmptySet()\n    {\n        Set<Option<int>> ma = Empty;\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == Some(Set<int>.Empty));\n    }\n        \n    [Fact]\n    public void SetSomesIsSomeSets()\n    {\n        var ma = Set(Some(1), Some(2), Some(3));\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == Some(Set(1, 2, 3)));\n    }\n        \n    [Fact]\n    public void SetSomeAndNoneIsNone()\n    {\n        var ma = Set(Some(1), Some(2), None);\n\n        var mb = ma.Traverse(mx => mx).As();\n\n\n        Assert.True(mb == None);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Sync/Either.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Sync\n{\n    public class EitherOption\n    {\n        [Fact]\n        public void LeftIsSomeLeft()\n        {\n            var ma = Left<Error, Option<int>>(Error.New(\"alt\"));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Some(Left<Error, int>(Error.New(\"alt\")));\n\n            var mr = mb == mc;\n            \n            Assert.True(mr);\n        }\n        \n        [Fact]\n        public void RightNoneIsNone()\n        {\n            var ma = Right<Error, Option<int>>(None);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Option<Either<Error, int>>.None;\n\n            var mr = mb == mc;\n            \n            Assert.True(mr);\n        }\n        \n        [Fact]\n        public void RightSomeIsSomeRight()\n        {\n            var ma = Right<Error, Option<int>>(Some(1234));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Some(Right<Error, int>(1234));\n\n            var mr = mb == mc;\n            \n            Assert.True(mr);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Sync/Identity.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Sync;\n\npublic class IdentityOption\n{\n    [Fact]\n    public void IdentityNoneIsNone()\n    {\n        var ma = new Identity<Option<int>>(None);\n        var mb = ma.Traverse(x => x).As();\n        var mc = Option<Identity<int>>.None;\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void IdentitySomeIsSomeIdentity()\n    {\n        var ma = new Identity<Option<int>>(1234);\n        var mb = ma.Traverse(x => x).As();\n        var mc = Some(new Identity<int>(1234));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Sync/Option.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Sync;\n\npublic class OptionOption\n{\n    [Fact]\n    public void NoneIsSomeNone()\n    {\n        var ma = Option<Option<int>>.None;\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Some(Option<int>.None);\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void SomeNoneIsNone()\n    {\n        var ma = Some<Option<int>>(None);\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Option<Option<int>>.None;\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void SomeSomeIsSomeSome()\n    {\n        var ma = Some(Some(1234));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Some(Some(1234));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Option/Sync/ValidationSeq.cs",
    "content": "using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.OptionT.Sync;\n\npublic class ValidationSeqOption\n{\n    [Fact]\n    public void FailIsSomeFail()\n    {\n        var ma = Fail<Error, Option<int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Some(Fail<Error, int>(Error.New(\"alt\")));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void SuccessNoneIsNone()\n    {\n        var ma = Success<Error, Option<int>>(None);\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Option<Validation<Error, int>>.None;\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n        \n    [Fact]\n    public void SuccessSomeIsSomeSuccess()\n    {\n        var ma = Success<Error, Option<int>>(Some(1234));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Some(Success<Error, int>(1234));\n\n        var mr = mb == mc;\n            \n        Assert.True(mr);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Collections/Arr.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Collections\n{\n    public class ArrSeq\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Arr<Seq<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq.singleton(Arr<int>.Empty);\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void ArrSeqCrossProduct()\n        {\n            var ma = Array(Seq(1, 2), Seq(10, 20, 30));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq(\n                Array(1, 10),\n                Array(1, 20),\n                Array(1, 30),\n                Array(2, 10),\n                Array(2, 20),\n                Array(2, 30));\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void ArrOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Array(Seq<int>(), Seq<int>(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Arr<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void ArrOfEmptiesIsEmpty()\n        {\n            var ma = Array(Seq<int>(), Seq<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Arr<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Collections/HashSet.cs",
    "content": "using System.Linq;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Collections\n{\n    public class HashSetSeq\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            HashSet<Seq<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq.singleton(HashSet<int>.Empty);\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void HashSetSeqCrossProduct()\n        {\n            var ma = HashSet(Seq(1, 2), Seq(10, 20, 30));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq(\n                HashSet(1, 10),\n                HashSet(1, 20),\n                HashSet(1, 30),\n                HashSet(2, 10),\n                HashSet(2, 20),\n                HashSet(2, 30));\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void HashSetOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = HashSet(Seq<int>(), Seq<int>(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<HashSet<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void HashSetOfEmptiesIsEmpty()\n        {\n            var ma = HashSet(Seq<int>(), Seq<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<HashSet<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Collections/IEnumerable.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Collections\n{\n    public class IEnumerableSeq\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            var ma = Iterable.empty<Seq<int>>();\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq.singleton(Iterable<int>.Empty);\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void IEnumerableSeqCrossProduct()\n        {\n            var ma = new[] { Seq(1, 2), Seq(10, 20, 30) }.AsIterable();\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Iterable<int>>(\n                [1, 10],\n                [1, 20],\n                [1, 30],\n                [2, 10],\n                [2, 20],\n                [2, 30]);\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void IEnumerableOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = new[] { Seq<int>(), Seq<int>(1, 2, 3) }.AsIterable();\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Iterable<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void IEnumerableOfEmptiesIsEmpty()\n        {\n            var ma = new[] { Seq<int>(), Seq<int>() }.AsIterable();\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Iterable<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Collections/Lst.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Collections\n{\n    public class LstSeq\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Lst<Seq<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq.singleton(Lst<int>.Empty);\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void LstSeqCrossProduct()\n        {\n            var ma = List(Seq(1, 2), Seq(10, 20, 30));\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = Seq(\n                List(1, 10),\n                List(1, 20),\n                List(1, 30),\n                List(2, 10),\n                List(2, 20),\n                List(2, 30));\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void LstOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = List(Seq<int>(), Seq<int>(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Lst<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void LstOfEmptiesIsEmpty()\n        {\n            var ma = List(Seq<int>(), Seq<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Lst<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Collections/Seq.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Collections\n{\n    public class SeqSeq\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Seq<Seq<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq.singleton(Seq<int>.Empty);\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void SeqSeqCrossProduct()\n        {\n            var ma = Seq(Seq(1, 2), Seq(10, 20, 30));\n            var mb = ma.Traverse(mx => mx).As();\n            var mc = Seq(\n                Seq(1, 10),\n                Seq(1, 20),\n                Seq(1, 30),\n                Seq(2, 10),\n                Seq(2, 20),\n                Seq(2, 30));\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void SeqOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Seq(Seq<int>(), Seq<int>(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Seq<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void SeqOfEmptiesIsEmpty()\n        {\n            var ma = Seq(Seq<int>(), Seq<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Seq<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Collections/Set.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Collections\n{\n    public class SetSeq\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Set<Seq<int>> ma = Empty;\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq.singleton(Set<int>.Empty);\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void SetSeqCrossProduct()\n        {\n            var ma = Set(Seq(1, 2), Seq(10, 20, 30));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq(\n                Set(1, 10),\n                Set(1, 20),\n                Set(1, 30),\n                Set(2, 10),\n                Set(2, 20),\n                Set(2, 30));\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void SetOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Set(Seq<int>(), Seq<int>(1, 2, 3));\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Set<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void SetOfEmptiesIsEmpty()\n        {\n            var ma = Set(Seq<int>(), Seq<int>());\n\n            var mb = ma.Traverse(mx => mx).As();\n\n\n            var mc = Seq<Set<int>>.Empty;\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Sync/Either.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Sync\n{\n    public class EitherSeq\n    {\n        [Fact]\n        public void LeftIsSingletonLeft()\n        {\n            var ma = Left<Error, Seq<int>>(Error.New(\"alt\"));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Seq1(Left<Error, int>(Error.New(\"alt\")));\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void RightEmptyIsEmpty()\n        {\n            var ma = Right<Error, Seq<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Seq<Either<Error, int>>();\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void RightNonEmptySeqIsSeqRight()\n        {\n            var ma = Right<Error, Seq<int>>(Seq(1, 2, 3, 4));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Seq(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3), Right<Error, int>(4));\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Sync/Identity.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Sync\n{\n    public class IdentitySeq\n    {\n        [Fact]\n        public void IdEmptyIsEmpty()\n        {\n            var ma = Id<Seq<int>>(Empty);\n            var mb = ma.Traverse(x => x).As();\n            var mc = Seq<Identity<int>>();\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void IdNonEmptySeqIsSeqId()\n        {\n            var ma = Id(Seq(1, 2, 3));\n            var mb = ma.Traverse(x => x).As();\n            var mc = Seq(Id(1), Id(2), Id(3));\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Sync/Option.cs",
    "content": "using LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Sync\n{\n    public class OptionSeq\n    {\n        [Fact]\n        public void NoneIsSingletonNone()\n        {\n            var ma = Option<Seq<int>>.None;\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Seq1(Option<int>.None);\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void SomeEmptyIsEmpty()\n        {\n            var ma = Some<Seq<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Seq<Option<int>>();\n\n            Assert.True(mb == mc);\n        }\n\n        [Fact]\n        public void SomeNonEmptySeqIsSeqSomes()\n        {\n            var ma = Some(Seq(1, 2, 3));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Seq(Some(1), Some(2), Some(3));\n\n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Sync/Validation.cs",
    "content": "using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Sync;\n\npublic class ValidationSeq\n{\n    [Fact]\n    public void FailIsSingletonFail()\n    {\n        var ma = Fail<Error, Seq<int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Seq(Fail<Error, int>(Error.New(\"alt\")));\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SuccessEmptyIsEmpty()\n    {\n        var ma = Success<Error, Seq<int>>(Empty);\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Seq<Validation<Error, int>>();\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SuccessNonEmptySeqIsSeqSuccesses()\n    {\n        var ma = Success<Error, Seq<int>>(Seq(1, 2, 3, 4));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Seq(Success<Error, int>(1), Success<Error, int>(2), Success<Error, int>(3), Success<Error, int>(4));\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SeqT/Sync/ValidationWithMonoid.cs",
    "content": "using System;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SeqT.Sync;\n\npublic class ValidationWithMonoidSeq\n{\n    [Fact]\n    public void FailIsSingletonFail()\n    {\n        var ma = Fail<Seq<Error>, Seq<int>>([Error.New(\"alt\")]);\n        var mb = ma.Traverse(x => x).As();\n        var mc = Seq.singleton(Fail<Seq<Error>, int>([Error.New(\"alt\")]));\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SuccessEmptyIsEmpty()\n    {\n        var ma = Success<Seq<Error>, Seq<int>>(Empty);\n        var mb = ma.Traverse(x => x).As();\n        var mc = Seq.empty<Validation<Seq<Error>, int>>();\n\n        Assert.True(mb == mc);\n    }\n\n    [Fact]\n    public void SuccessNonEmptySeqIsSeqSuccesses()\n    {\n        var ma = Success<Seq<Error>, Seq<int>>(Seq(1, 2, 3, 4));\n        var mb = ma.Traverse(x => x).As();\n        var mc = Seq(\n            Success<Seq<Error>, int>(1),\n            Success<Seq<Error>, int>(2),\n            Success<Seq<Error>, int>(3),\n            Success<Seq<Error>, int>(4));\n\n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SetT/Collections/Arr.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SetT.Collections\n{\n    public class ArrSet\n    {\n        [Fact]\n        public void EmptyEmptyIsEmptyEmpty()\n        {\n            Arr<Set<int>> ma = Empty;\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Set.singleton(Arr<int>.Empty);\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void ArrSetCrossProduct()\n        {\n            var ma = Set(List(1, 2), List(10, 20, 30));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List(\n                Set(1, 10), \n                Set(1, 20), \n                Set(1, 30), \n                Set(2, 10), \n                Set(2, 20), \n                Set(2, 30));\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void ArrOfEmptiesAndNonEmptiesIsEmpty()\n        {\n            var ma = Set(List<int>(), List(1, 2, 3));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List<Set<int>>();\n            \n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void ArrOfEmptiesIsEmpty()\n        {\n            var ma = Set(List<int>(), List<int>());\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = List<Set<int>>();\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SetT/Sync/Either.cs",
    "content": "using System;\nusing LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SetT.Sync\n{\n    public class EitherSet\n    {\n        // TODO: OrdDefault\n        // [Fact]\n        // public void LeftIsSingletonLeft()\n        // {\n        //     var ma = Left<Error, Set<int>>(Error.New(\"alt\"));\n        //     var mb = ma.Traverse(mx => mx).As();\n\n        //     var mc = Set(Left<Error, int>(new Exception(\"alt\")));\n        //\n        //     Assert.True(mb == mc);\n        // }\n        \n        [Fact]\n        public void RightEmptyIsEmpty()\n        {\n            var ma = Right<Error, Set<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Set<Either<Error, int>>();\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void RightNonEmptySetIsSetRight()\n        {\n            var ma = Right<Error, Set<int>>(Set(1, 2, 3, 4));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Set(Right<Error, int>(1), Right<Error, int>(2), Right<Error, int>(3), Right<Error, int>(4));\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SetT/Sync/Identity.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SetT.Sync\n{\n    public class IdentitySet\n    {\n        [Fact]\n        public void IdEmptyIsEmpty()\n        {\n            var ma = Id<Set<int>>(Empty);\n            var mb = ma.Traverse(x => x).As();\n            var mc = Set<Identity<int>>();\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void IdNonEmptySetIsSetId()\n        {\n            var ma = Id(Set(1, 2, 3));\n            var mb = ma.Traverse(x => x).As();\n            var mc = Set(Id(1), Id(2), Id(3));\n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SetT/Sync/Option.cs",
    "content": "using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SetT.Sync\n{\n    public class OptionSet\n    {\n        [Fact]\n        public void NoneIsSingletonNone()\n        {\n            var ma = Option<Set<int>>.None;\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Set(Option<int>.None);\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SomeEmptyIsEmpty()\n        {\n            var ma = Some<Set<int>>(Empty);\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Set<Option<int>>();\n\n            Assert.True(mb == mc);\n        }\n        \n        [Fact]\n        public void SomeNonEmptySetIsSetSomes()\n        {\n            var ma = Some(Set(1, 2, 3));\n            var mb = ma.Traverse(mx => mx).As();\n\n            var mc = Set(Some(1), Some(2), Some(3)); \n            \n            Assert.True(mb == mc);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/SetT/Sync/ValidationSeq.cs",
    "content": "using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.SetT.Sync;\n\npublic class ValidationSeqSet\n{\n    // TODO: OrdDefault\n    // [Fact]\n    // public void FailIsSingletonFail()\n    // {\n    //     var ma = Fail<Error, Set<int>>(Error.New(\"alt\"));\n    //     var mb = ma.Traverse(mx => mx).As();\n\n    //     var mc = Set(Fail<Error, int>(new Exception(\"alt\")));\n    //\n    //     Assert.True(mb == mc);\n    // }\n        \n    [Fact]\n    public void SuccessEmptyIsEmpty()\n    {\n        var ma = Success<Error, Set<int>>(Empty);\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Set<Validation<Error, int>>();\n\n        Assert.True(mb == mc);\n    }\n        \n    [Fact]\n    public void SuccessNonEmptySetIsSetSuccesses()\n    {\n        var ma = Success<Error, Set<int>>(Set(1, 2, 3, 4));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Set(Success<Error, int>(1), Success<Error, int>(2), Success<Error, int>(3), Success<Error, int>(4));\n            \n        Assert.True(mb == mc);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Collections/Arr.cs",
    "content": "﻿using Xunit;\nusing LanguageExt.Common;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Collections;\n\npublic class Arr\n{\n    [Fact]\n    public void EmptyArrayIsSuccessEmptyArray()\n    {\n        Arr<Validation<Error, string>> ma = Empty;\n        var                            mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Arr<string>>(Empty), mb);\n    }\n\n    [Fact]\n    public void ArraySuccessIsSuccessArray()\n    {\n        var ma = Array(Success<Error, int>(2), Success<Error, int>(8), Success<Error, int>(64));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Arr<int>>(Array(2, 8, 64)), mb);\n    }\n\n    [Fact]\n    public void ArrayFailedIsFailedArray()\n    {\n        var ma       = Array(Fail<Error, int>(Error.New(\"failed\")), Fail<Error, int>(Error.New(\"failuire\")));\n        var mb       = ma.Traverse(x => x);\n        var expected = Fail<Error, Arr<int>>(Seq(Error.New(\"failed\"), Error.New(\"failuire\")));\n        Assert.Equal(expected, mb);\n    }\n\n    [Fact]\n    public void ArrSuccAndFailIsFailedArr()\n    {\n        var ma = Array(Fail<Error, int>(Error.New(\"failed\")), Success<Error, int>(12));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Fail<Error, Arr<int>>(Error.New(\"failed\")), mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Collections/HashSet.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Collections;\n\npublic class HashSet\n{\n    [Fact]\n    public void EmptyHashSetIsSuccessEmptyHashSet()\n    {\n        HashSet<Validation<Error, string>> ma = Empty;\n        var                                mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, HashSet<string>>(Empty), mb);\n    }\n\n    [Fact]\n    public void HashSetSuccessIsSuccessHashSet()\n    {\n        var ma = HashSet(Success<Error, int>(2), Success<Error, int>(8), Success<Error, int>(64));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, HashSet<int>>(HashSet(2, 8, 64)), mb);\n    }\n\n    [Fact]\n    public void HashSetSuccAndFailIsFailedHashSet()\n    {\n        var ma = HashSet(Fail<Error, int>(Error.New(\"failed\")), Success<Error, int>(12));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Fail<Error, HashSet<int>>(Error.New(\"failed\")), mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Collections/IEnumerable.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Collections;\n\npublic class IEnumerable\n{\n    [Fact]\n    public void EmptyIEnumerableIsSuccessIEnumerable()\n    {\n        var ma = Iterable.empty<Validation<Error, int>>();\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Iterable<int>>(Iterable.empty<int>()), mb);\n    }\n\n    [Fact]\n    public void IEnumerableSuccessIsSuccessIEnumerable()\n    {\n        var ma = IterableExtensions.AsIterable(List(Success<Error, int>(2), Success<Error, int>(8), Success<Error, int>(64)));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Iterable<int>>(IterableExtensions.AsIterable(List(2, 8, 64))), mb);\n    }\n\n    [Fact]\n    public void IEnumerableSuccAndFailIsFailedIEnumerable()\n    {\n        var ma = IterableExtensions.AsIterable(List(Fail<Error, int>(Error.New(\"failed\")), Success<Error, int>(12)));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Fail<Error, Iterable<int>>(Error.New(\"failed\")), mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Collections/Lst.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Collections;\n\npublic class LstValidation\n{\n    [Fact]\n    public void EmptyLstIsSuccessEmptyLst()\n    {\n        Lst<Validation<Error, string>> ma = Empty;\n        var                            mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Lst<string>>(Empty), mb);\n    }\n\n    [Fact]\n    public void LstSuccessIsSuccessLst()\n    {\n        var ma = List(Success<Error, int>(2), Success<Error, int>(8), Success<Error, int>(64));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Lst<int>>(List(2, 8, 64)), mb);\n    }\n\n    [Fact]\n    public void LstFailedIsFailedLst()\n    {\n        var ma       = List(Fail<Error, int>(Error.New(\"failed\")), Fail<Error, int>(Error.New(\"failuire\")));\n        var mb       = ma.Traverse(x => x);\n        var expected = Fail<Error, Lst<int>>(Seq(Error.New(\"failed\"), Error.New(\"failuire\")));\n        Assert.Equal(expected, mb);\n    }\n\n    [Fact]\n    public void LstSuccAndFailIsFailedLst()\n    {\n        var ma = List(Fail<Error, int>(Error.New(\"failed\")), Success<Error, int>(12));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Fail<Error, Lst<int>>(Error.New(\"failed\")), mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Collections/Seq.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Collections;\n\npublic class Seq\n{\n    [Fact]\n    public void EmptySeqIsSuccessEmptySeq()\n    {\n        Seq<Validation<Error, string>> ma = Empty;\n        var                            mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Seq<string>>(Empty), mb);\n    }\n\n    [Fact]\n    public void SeqSuccessIsSuccessSeq()\n    {\n        var ma = Seq(Success<Error, int>(2), Success<Error, int>(8), Success<Error, int>(64));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Seq<int>>(Seq(2, 8, 64)), mb);\n    }\n\n    [Fact]\n    public void SeqFailedIsFailedSeq()\n    {\n        var ma       = Seq(Fail<Error, int>(Error.New(\"failed\")), Fail<Error, int>(Error.New(\"failuire\")));\n        var mb       = ma.Traverse(x => x);\n        var expected = Fail<Error, Seq<int>>(Seq(Error.New(\"failed\"), Error.New(\"failuire\")));\n        Assert.Equal(expected, mb);\n    }\n\n    [Fact]\n    public void SeqSuccAndFailIsFailedSeq()\n    {\n        var ma = Seq(Fail<Error, int>(Error.New(\"failed\")), Success<Error, int>(12));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Fail<Error, Seq<int>>(Error.New(\"failed\")), mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Collections/Set.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Collections;\n\npublic class Set\n{\n    [Fact]\n    public void EmptySetIsSuccessEmptySet()\n    {\n        Set<Validation<Error, string>> ma = Empty;\n        var                            mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Set<string>>(Empty), mb);\n    }\n\n    [Fact]\n    public void SetSuccessIsSuccessSet()\n    {\n        var ma = Set(Success<Error, int>(2), Success<Error, int>(8), Success<Error, int>(64));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Success<Error, Set<int>>(Set(2, 8, 64)), mb);\n    }\n\n    [Fact]\n    public void SetSuccAndFailIsFailedSet()\n    {\n        var ma = Set(Fail<Error, int>(Error.New(\"failed\")), Success<Error, int>(12));\n        var mb = ma.Traverse(x => x);\n        Assert.Equal(Fail<Error, Set<int>>(Error.New(\"failed\")), mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Sync/Either.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Sync;\n\npublic class Either\n{\n    [Fact]\n    public void LeftIsSuccessLeft()\n    {\n        var ma = Left<Error, Validation<Error, int>>(Error.New(\"alt\"));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Success<Error, Either<Error, int>>(Left(Error.New(\"alt\")));\n        Assert.Equal(mc, mb);\n    }\n\n    [Fact]\n    public void RightSuccessIsSuccess()\n    {\n        var ma = Right<Error, Validation<Error, int>>(Success<Error, int>(12));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Success<Error, Either<Error, int>>(Right(12));\n        Assert.Equal(mc, mb);\n    }\n\n    [Fact]\n    public void RightFailIsFail()\n    {\n        var ma = Right<Error, Validation<Error, int>>(Fail<Error, int>(Error.New(\"Error\")));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Fail<Error, Either<Error, int>>(Error.New(\"Error\"));\n        Assert.Equal(mc, mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Sync/Identity.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Sync;\n\npublic class Identity\n{\n    [Fact]\n    public void IdentitySuccessIsSuccessIdentity()\n    {\n        var ma = Id(Success<Error, int>(12));\n        var mb = ma.Traverse(x => x);\n        var mc = Success<Error, Identity<int>>(Id(12));\n\n        Assert.Equal(mc, mb);\n    }\n\n    [Fact]\n    public void IdentityFailIsFailIdentity()\n    {\n        var ma = Id(Fail<Error, int>(Error.New(\"error\")));\n        var mb = ma.Traverse(x => x);\n        var mc = Fail<Error, Identity<int>>(Error.New(\"error\"));\n\n        Assert.Equal(mc, mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Sync/Option.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Sync;\n\npublic class Option\n{\n    [Fact]\n    public void NoneIsSuccessNone()\n    {\n        var ma = Option<Validation<Error, int>>.None;\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Success<Error, Option<int>>(None);\n\n        Assert.Equal(mc, mb);\n    }\n\n    [Fact]\n    public void SomeSuccessIsSuccessSome()\n    {\n        var ma = Some(Success<Error, int>(12));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Success<Error, Option<int>>(12);\n\n        Assert.Equal(mc, mb);\n    }\n\n    [Fact]\n    public void SomeFailIsFailSome()\n    {\n        var ma = Some(Fail<Error, int>(Error.New(\"Err\")));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Fail<Error, Option<int>>(Error.New(\"Err\"));\n\n        Assert.Equal(mc, mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/Transformer/Traverse/Validation/Sync/ValidationSeq.cs",
    "content": "﻿using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests.Transformer.Traverse.Validation.Sync;\n\npublic class ValidationSeq\n{\n    [Fact]\n    public void FailIsSuccessFail()\n    {\n        var ma = Fail<Error, Validation<Error, int>>(Error.New(\"Fail\"));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Success<Error, Validation<Error, int>>(Fail<Error, int>(Error.New(\"Fail\")));\n\n        Assert.Equal(mc, mb);\n    }\n\n    [Fact]\n    public void SuccessIsRightSuccess()\n    {\n        var ma = Success<Error, Validation<Error, int>>(Success<Error, int>(12));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Success<Error, Validation<Error, int>>(Success<Error, int>(12));\n\n        Assert.Equal(mc, mb);\n    }\n\n    [Fact]\n    public void SuccessFailIsFail()\n    {\n        var ma = Success<Error, Validation<Error, int>>(Fail<Error, int>(Error.New(\"Fail\")));\n        var mb = ma.Traverse(mx => mx).As();\n\n        var mc = Fail<Error, Validation<Error, int>>(Error.New(\"Fail\"));\n\n        Assert.Equal(mc, mb);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/TupleTests.cs",
    "content": "﻿using Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests;\n\npublic class TupleTests\n{\n    [Fact] public void TupleGeneratorTests()\n    {\n        var t2 = (\"a\", \"b\");\n        var t3 = (\"a\", \"b\", \"c\");\n        var t4 = (\"a\", \"b\", \"c\", \"d\");\n        var t5 = (\"a\", \"b\", \"c\", \"d\", \"e\");\n        var t6 = (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\");\n        var t7 = (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\");\n\n        Assert.True(t2.Item1 == \"a\" && t2.Item2 == \"b\");\n        Assert.True(t3.Item1 == \"a\" && t3.Item2 == \"b\" && t3.Item3 == \"c\");\n        Assert.True(t4.Item1 == \"a\" && t4.Item2 == \"b\" && t4.Item3 == \"c\" && t4.Item4 == \"d\");\n        Assert.True(t5.Item1 == \"a\" && t5.Item2 == \"b\" && t5.Item3 == \"c\" && t5.Item4 == \"d\" && t5.Item5 == \"e\");\n        Assert.True(t6.Item1 == \"a\" && t6.Item2 == \"b\" && t6.Item3 == \"c\" && t6.Item4 == \"d\" && t6.Item5 == \"e\" && t6.Item6 == \"f\");\n        Assert.True(t6.Item1 == \"a\" && t6.Item2 == \"b\" && t6.Item3 == \"c\" && t6.Item4 == \"d\" && t6.Item5 == \"e\" && t6.Item6 == \"f\");\n        Assert.True(t7.Item1 == \"a\" && t7.Item2 == \"b\" && t7.Item3 == \"c\" && t7.Item4 == \"d\" && t7.Item5 == \"e\" && t7.Item6 == \"f\" && t7.Item7 == \"g\");\n    }\n\n    [Fact] public void WithApplicationTests1()\n    {\n        (\"a\", \"b\").Iter((a, b) => Assert.True(a == \"a\" && b == \"b\"));\n        (\"a\", \"b\", \"c\").Iter((a, b, c) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\"));\n        (\"a\", \"b\", \"c\", \"d\").Iter((a, b, c, d) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\"));\n        (\"a\", \"b\", \"c\", \"d\", \"e\").Iter((a, b, c, d, e) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\"));\n        (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\").Iter((a, b, c, d, e, f) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\" && f == \"f\"));\n        (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\").Iter((a, b, c, d, e, f, g) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\" && f == \"f\" && g == \"g\"));\n    }\n\n    [Fact] public void WithApplicationTests2()\n    {\n        iter( (\"a\", \"b\"), (a, b) => Assert.True(a == \"a\" && b == \"b\"));\n        iter( (\"a\", \"b\", \"c\"), (a, b, c) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\"));\n        iter( (\"a\", \"b\", \"c\", \"d\"), (a, b, c, d) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\"));\n        iter( (\"a\", \"b\", \"c\", \"d\", \"e\"), (a, b, c, d, e) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\"));\n        iter( (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"), (a, b, c, d, e, f) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\" && f == \"f\"));\n        iter( (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"), (a, b, c, d, e, f, g) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\" && f == \"f\" && g == \"g\"));\n    }\n\n    [Fact]\n    public void ValueTupleGeneratorTests()\n    {\n        var t2 = (\"a\", \"b\");\n        var t3 = (\"a\", \"b\", \"c\");\n        var t4 = (\"a\", \"b\", \"c\", \"d\");\n        var t5 = (\"a\", \"b\", \"c\", \"d\", \"e\");\n        var t6 = (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\");\n        var t7 = (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\");\n\n        Assert.True(t2.Item1 == \"a\" && t2.Item2 == \"b\");\n        Assert.True(t3.Item1 == \"a\" && t3.Item2 == \"b\" && t3.Item3 == \"c\");\n        Assert.True(t4.Item1 == \"a\" && t4.Item2 == \"b\" && t4.Item3 == \"c\" && t4.Item4 == \"d\");\n        Assert.True(t5.Item1 == \"a\" && t5.Item2 == \"b\" && t5.Item3 == \"c\" && t5.Item4 == \"d\" && t5.Item5 == \"e\");\n        Assert.True(t6.Item1 == \"a\" && t6.Item2 == \"b\" && t6.Item3 == \"c\" && t6.Item4 == \"d\" && t6.Item5 == \"e\" && t6.Item6 == \"f\");\n        Assert.True(t6.Item1 == \"a\" && t6.Item2 == \"b\" && t6.Item3 == \"c\" && t6.Item4 == \"d\" && t6.Item5 == \"e\" && t6.Item6 == \"f\");\n        Assert.True(t7.Item1 == \"a\" && t7.Item2 == \"b\" && t7.Item3 == \"c\" && t7.Item4 == \"d\" && t7.Item5 == \"e\" && t7.Item6 == \"f\" && t7.Item7 == \"g\");\n    }\n\n    [Fact]\n    public void ValueWithApplicationTests1()\n    {\n        (\"a\", \"b\").Iter((a, b) => Assert.True(a == \"a\" && b == \"b\"));\n        (\"a\", \"b\", \"c\").Iter((a, b, c) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\"));\n        (\"a\", \"b\", \"c\", \"d\").Iter((a, b, c, d) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\"));\n        (\"a\", \"b\", \"c\", \"d\", \"e\").Iter((a, b, c, d, e) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\"));\n        (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\").Iter((a, b, c, d, e, f) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\" && f == \"f\"));\n        (\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\").Iter((a, b, c, d, e, f, g) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\" && f == \"f\" && g == \"g\"));\n    }\n\n    [Fact]\n    public void ValueWithApplicationTests2()\n    {\n        iter((\"a\", \"b\"), (a, b) => Assert.True(a == \"a\" && b == \"b\"));\n        iter((\"a\", \"b\", \"c\"), (a, b, c) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\"));\n        iter((\"a\", \"b\", \"c\", \"d\"), (a, b, c, d) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\"));\n        iter((\"a\", \"b\", \"c\", \"d\", \"e\"), (a, b, c, d, e) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\"));\n        iter((\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"), (a, b, c, d, e, f) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\" && f == \"f\"));\n        iter((\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"), (a, b, c, d, e, f, g) => Assert.True(a == \"a\" && b == \"b\" && c == \"c\" && d == \"d\" && e == \"e\" && f == \"f\" && g == \"g\"));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/UnionCustomJsonSerializerTests.cs",
    "content": "/*\n \n TODO: Consider restoring when SourceGen arrives \n \nusing System;\nusing System.Linq;\nusing System.Reflection;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    [Union]\n    [MyUnion]\n    public abstract partial class UnionTestClass\n    {\n        public abstract UnionTestClass UnionA();\n        public abstract UnionTestClass UnionB(int i);\n        public abstract UnionTestClass UnionC(int i);\n        public abstract UnionTestClass UnionD(int i, int j);\n    }\n        \n    [AttributeUsage(AttributeTargets.Class, Inherited = false)]\n    public class MyUnionAttribute : Attribute\n    {\n    }\n        \n    public partial class UnionCustomJsonSerializerTests\n    {\n        public class UnionJsonReadConverter : JsonConverter\n        {\n            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();\n\n            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)\n            {\n                string typeName = null;\n                JObject typeValueToken = null;\n                if (reader.TokenType != JsonToken.StartObject) throw new Exception();\n                while (reader.Read())\n                {\n                    if (reader.TokenType == JsonToken.EndObject) break;\n                    if (reader.TokenType != JsonToken.PropertyName) throw new Exception();\n                    if ((string) reader.Value == \"Type\")\n                    {\n                        if (!reader.Read()) throw new Exception();\n                        if (typeName != null) throw new Exception();\n                        if (reader.TokenType != JsonToken.String) throw new Exception();\n                        typeName = (string) reader.Value;\n                    }\n                    else if ((string) reader.Value == \"Value\")\n                    {\n                        if (typeValueToken != null) throw new Exception();\n                        if (!reader.Read()) throw new Exception();\n                        if (reader.TokenType != JsonToken.StartObject) throw new Exception();\n                        typeValueToken = JObject.Load(reader);\n                    }\n                }\n\n                var type = objectType.Assembly.GetTypes().Where(_ => objectType.IsAssignableFrom(_) && _.Name == typeName).Single();\n                var result = typeValueToken.ToObject(type, serializer);\n                return result;\n            }\n\n            public override bool CanWrite => false;\n            public override bool CanConvert(Type objectType) => objectType.IsClass && objectType.GetCustomAttribute<MyUnionAttribute>() != null;\n        }\n         \n        public class UnionJsonWriteConverter : JsonConverter\n        {\n            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)\n            {\n                var t = value.GetType();\n                writer.WriteStartObject();\n                writer.WritePropertyName(\"Type\");\n                writer.WriteValue(t.Name);\n                writer.WritePropertyName(\"Value\");\n                writer.WriteStartObject();\n                foreach (var fieldInfo in t.GetFields(BindingFlags.Instance | BindingFlags.Public))\n                {\n                    writer.WritePropertyName(fieldInfo.Name);\n                    serializer.Serialize(writer, fieldInfo.GetValue(value));\n                }\n                writer.WriteEndObject();\n                writer.WriteEndObject();\n            }\n\n            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) =>\n                new NotImplementedException();\n\n            public override bool CanRead => false;\n\n            public override bool CanConvert(Type objectType) => objectType.IsClass && objectType.BaseType?.BaseType?.GetCustomAttribute<MyUnionAttribute>() != null;\n        }\n        \n        [Fact(Skip = \"No feature written that supports this yet\")]\n        public void UnionFromJson()\n        {\n            var json = @\"{\"\"Type\"\":\"\"B\"\",\"\"Value\"\":{\"\"I\"\":42}}\";\n            var x = JsonConvert.DeserializeObject<UnionTestClass>(json, new UnionJsonReadConverter()) as UnionB;\n            Assert.Equal(42, x?.I);\n        }\n        \n        [Fact(Skip = \"No feature written that supports this yet\")]\n        public void UnionToJson()\n        {\n            var x = JsonConvert.SerializeObject(UnionTestClassCon.UnionB(42), new UnionJsonWriteConverter());\n            Assert.Equal(@\"{\"\"Type\"\":\"\"B\"\",\"\"Value\"\":{\"\"I\"\":42}}\", x);\n        }\n    }\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Tests/UnionJsonSerializerTests.cs",
    "content": "/*\n \n TODO: Consider restoring when SourceGen arrives \n using System.Runtime.Serialization;\nusing Newtonsoft.Json;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    [Union]\n    public abstract partial class LightControl\n    {\n        public abstract LightControl OnOff(bool enabled);\n        public abstract LightControl Dimmer(int value);\n    }\n\n    public partial class UnionJsonSerializerTests\n    { \n        [Fact]\n        public void UnionInstanceFromJson()\n        {\n            var json = @\"{\"\"Value\"\":100,\"\"Tag\"\":2}\";\n            var x = JsonConvert.DeserializeObject<Dimmer>(json);\n            Assert.Equal(100, x.Value);\n        }\n        \n        [Fact(Skip=\"not yet supported\")]\n        public void UnionInstanceToJson()\n        {\n            var json = JsonConvert.SerializeObject(LightControlCon.Dimmer(100));\n            Assert.Equal(@\"{\"\"Value\"\":100,\"\"Tag\"\":2}\", json);\n        }        \n        \n        [Fact]\n        public void UnionRoundTrip()\n        {\n            Assert.Equal(LightControlCon.OnOff(true), JsonConvert.DeserializeObject<OnOff>(JsonConvert.SerializeObject(LightControlCon.OnOff(true))));\n            Assert.Equal(LightControlCon.OnOff(false), JsonConvert.DeserializeObject<OnOff>(JsonConvert.SerializeObject(LightControlCon.OnOff(false))));\n            Assert.Equal(LightControlCon.Dimmer(10), JsonConvert.DeserializeObject<Dimmer>(JsonConvert.SerializeObject(LightControlCon.Dimmer(10))));\n            Assert.Equal(LightControlCon.Dimmer(90), JsonConvert.DeserializeObject<Dimmer>(JsonConvert.SerializeObject(LightControlCon.Dimmer(90))));\n            \n        }\n    }\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Tests/UnionTests.cs",
    "content": "﻿/*\n \n TODO: Consider restoring when SourceGen arrives \n using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing static LanguageExt.Tests.AorBCon;\nusing Xunit;\n\nnamespace LanguageExt.Tests {\n    [Union]\n    public interface AorB {\n        public AorB A();\n        public AorB B(int value);\n    }\n\n    public class UnionTests {\n        public static IEnumerable<object[]> DataArray<T1, T2, T3>((T1, T2, T3)[] rows) =>\n            rows.Map(row => {\n                (var t1, var t2, var t3) = row;\n                return new object[] { t1, t2, t3 };\n            });\n\n        public static IEnumerable<object[]> CompareToUnspecialized_Data() => DataArray(new (AorB, AorB, int) [] {\n            (A(),  A(),  0),\n            (A(),  B(0), 1),\n            (B(0), A(),  1),\n            (B(0), B(0), 0),\n            (B(0), B(1), -1),\n            (B(1), B(0), 1),\n        });\n            \n        [Theory]\n        [MemberData(nameof(CompareToUnspecialized_Data), new object[]{ })]\n        void CompareTo_Unspecialized(AorB left, AorB right, int expected) {\n            Assert.Equal(\n                expected,\n                ((IComparable) left).CompareTo((IComparable) right));\n        }\n\n        [Fact]\n        void CompareTo_Specialized_A() {\n            Assert.Equal(0, ((IComparable<A>) A()).CompareTo((A) A()));\n        }\n        public static IEnumerable<object[]> CompareTo_Specialized_B_Data() => DataArray(new (AorB, AorB, int) [] {\n            (B(0), B(0), 0),\n            (B(0), B(1), -1),\n            (B(1), B(0), 1),\n        });\n\n        [Theory]\n        [MemberData(nameof(CompareTo_Specialized_B_Data), new object[] { })]\n        void CompareTo_Specialized_B(AorB left, AorB right, int expected) {\n            Assert.Equal(expected, ((IComparable<B>) left).CompareTo((B) right));\n        }\n        public static IEnumerable<object[]> EqualsTest_Data() => DataArray(new (AorB, AorB, bool) [] {\n            (A(),  A(),  true),\n            (A(),  B(0), false),\n            (B(0), A(),  false),\n            (B(0), B(0), true),\n            (B(0), B(1), false),\n            (B(1), B(0), false),\n        });\n\n        [Theory]\n        [MemberData(nameof(EqualsTest_Data), new object[] { })]\n        public void EqualsTest(AorB left, AorB right, bool expected) =>\n            Assert.Equal(expected, left.Equals(right));\n    }\n}\n*/\n"
  },
  {
    "path": "LanguageExt.Tests/UnitsOfMeasureTests.cs",
    "content": "﻿using System;\nusing Xunit;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace LanguageExt.Tests;\n\npublic class UnitsOfMeasureTests\n{\n    [Fact]\n    public void PreludeLengthEqualityTest()\n    {\n        Assert.True(100 *cm == 1    *m);\n        Assert.True(1   *km == 1000 *m);\n    }\n\n    [Fact]\n    public void PreludeLengthEqualityTest3()\n    {\n        Assert.True(1 *yard == 3 *feet);\n    }\n\n    [Fact]\n    public void PreludeLengthEqualityTest4()\n    {\n        Assert.True(12 *inches == 1 *feet);\n    }\n\n    [Fact]\n    public void PreludeLengthCompareTest1()\n    {\n        Assert.True(1 *mile > 1 *km);\n    }\n\n    [Fact]\n    public void PreludeLengthScalarTest2()\n    {\n        Assert.True(1 *km / 500 == 2 *metres);\n    }\n\n    [Fact]\n    public void LengthEqualityTest()\n    {\n        Assert.True(100.Centimetres() == 1.Metres());\n        Assert.True(1.Kilometres()    == 1000.Metres());\n    }\n\n    [Fact]\n    public void LengthEqualityTest2()\n    {\n        Length length = 1000.Millimetres();\n\n        Assert.True(length.Metres      == 1.0);\n        Assert.True(length.Millimetres == 1000.0);\n    }\n\n    [Fact]\n    public void LengthEqualityTest3()\n    {\n        Assert.True(1.Yards() == 3.Feet());\n    }\n\n    [Fact]\n    public void LengthEqualityTest4()\n    {\n        Assert.True(12.Inches() == 1.Feet());\n    }\n\n    [Fact]\n    public void LengthCompareTest1()\n    {\n        Assert.True(1.Miles() > 1.Kilometres());\n    }\n\n    [Fact]\n    public void LengthScalarTest1()\n    {\n        Assert.True(1.Miles() * 10 == 10.Miles());\n    }\n\n    [Fact]\n    public void LengthScalarTest2()\n    {\n        Assert.True(1.Kilometres() / 500 == 2.Metres());\n    }\n\n    [Fact]\n    public void OperatorTests()\n    {\n        Length len = 1 *km;\n\n        double val = len / (1 *m); // Divide by 1 metre to get a dimensionless value\n\n        Assert.True(val == 1000.0);\n\n        val = len / (1000 *m);\n\n        Assert.True(val == 1.0);\n    }\n\n    [Fact]\n    public void LengthCompareTest2()\n    {\n        Assert.True(100 *mm < 2 *m);\n    }\n\n    [Fact]\n    public void LengthArithmetic1()\n    {\n        Length length = 1000    *mm + 1 *m;\n        Assert.True(length == 2 *m);\n    }\n\n    [Fact]\n    public void LengthArithmetic2()\n    {\n        Length length = 1       *cm + 10 *mm;\n        Assert.True(length == 2 *cm);\n    }\n\n    [Fact]\n    public void TimeEqualityTest()\n    {\n        Assert.True(60 *sec  == 1 *min);\n        Assert.True(60 *mins == 1 *hr);\n    }\n\n    [Fact]\n    public void AreaTest1()\n    {\n        var a = 1000 *cm * 8 *m;\n        var b = 80   *m2;\n\n        Assert.True(a == b);\n    }\n\n    [Fact]\n    public void SpeedTest1()\n    {\n        Velocity v = 100 *m /s;\n\n        Length l = v * 2 *sec;\n\n        double r = l / (1 *m);\n\n        Assert.True(l == 200 * m);\n        Assert.True(r == 200.0);\n    }\n\n    [Fact]\n    public void SpeedTest2()\n    {\n        Velocity v = 100 *mph;\n\n        Time t = 50 *miles / v;\n\n        Length l = v * (4 *hours);\n\n        Assert.True(t == 30  *mins);\n        Assert.True(l == 400 *miles);\n    }\n\n    [Fact]\n    public void AccelTest1()\n    {\n        Accel g  = 9.8 *m /s /s;\n        Accel g2 = 9.8    *ms2;\n\n        Velocity vel = g   * 5 *sec;\n        Length   len = vel * 5 *sec;\n\n        Assert.True(vel.MetresPerSecond == 49.0);\n        Assert.True(len.Metres          == 245.0);\n    }\n\n    [Fact]\n    public void AccelObjectEquals_Both0_True() =>\n        AssertTypeObjectEquals<Accel>(0 * m / s / s);\n\n    [Fact]\n    public void AreaObjectEquals_Both0_True() =>\n        AssertTypeObjectEquals<Area>(0 * m * m);\n\n    [Fact]\n    public void LengthObjectEquals_Both0_True() =>\n        AssertTypeObjectEquals<Length>(0 * m);\n\n    [Fact]\n    public void TimeObjectEquals_Both0_True() =>\n        AssertTypeObjectEquals<Time>(0 * s);\n\n    [Fact]\n    public void TimeSqObjectEquals_Both0_True() =>\n        AssertTypeObjectEquals<TimeSq>(0 * s * s);\n\n    [Fact]\n    public void VelocityObjectEquals_Both0_True() =>\n        AssertTypeObjectEquals<Velocity>(0 * m / s);\n\n    [Fact]\n    public void VelocitySqObjectEquals_Both0_True() =>\n        AssertTypeObjectEquals<VelocitySq>((0 * m / s) * (0 * m / s));\n\n    private void AssertTypeObjectEquals<T>(T t)\n    {\n        object o1 = t;\n        object o2 = t;\n        Assert.True(o1.Equals(o2));\n    }\n\n    [Fact]\n    public void CelsiusToStringTest()\n    {\n        var x = 10 * degC;\n        Assert.True(x.ToString() == \"10 °C\");\n    }\n\n    [Fact]\n    public void CelsiusAddTest()\n    {\n        var x = 10 * degC;\n        var y = 20 * degC;\n        var z = 30 * degC;\n\n        Assert.True(x + y == z);\n    }\n\n    [Fact]\n    public void CelsiusSubTest()\n    {\n        var x = 10 * degC;\n        var y = 20 * degC;\n        var z = 30 * degC;\n\n        Assert.True(z - y == x);\n    }\n\n    [Fact]\n    public void CelsiusScalar1Test()\n    {\n        var x = 10 * degC;\n        var y = 20 * degC;\n\n        Assert.True(x * 2.0 == y);\n    }\n\n    [Fact]\n    public void CelsiusScalar2Test()\n    {\n        var x = 10 * degC;\n        var y = 20 * degC;\n\n        Assert.True(y / 2.0 == x);\n    }\n\n    [Fact]\n    public void FahrenheitToStringTest()\n    {\n        var x = 10 * degF;\n        Assert.True(x.ToString() == \"10 °F\");\n    }\n\n    [Fact]\n    public void FahrenheitAddTest()\n    {\n        var x = 10 * degF;\n        var y = 20 * degF;\n        var z = 30 * degF;\n\n        Assert.True(x + y == z);\n    }\n\n    [Fact]\n    public void FahrenheitSubTest()\n    {\n        var x = 10 * degF;\n        var y = 20 * degF;\n        var z = 30 * degF;\n\n        Assert.True(z - y == x);\n    }\n\n    [Fact]\n    public void FahrenheitScalar1Test()\n    {\n        var x = 10 * degF;\n        var y = 20 * degF;\n\n        Assert.True(x * 2.0 == y);\n    }\n\n    [Fact]\n    public void FahrenheitScalar2Test()\n    {\n        var x = 10 * degF;\n        var y = 20 * degF;\n\n        Assert.True(y / 2.0 == x);\n    }\n\n    [Fact]\n    public void KelvinToStringTest()\n    {\n        var x = 10 * K;\n        Assert.True(x.ToString() == \"10 K\");\n    }\n\n    [Fact]\n    public void KelvinAddTest()\n    {\n        var x = 10 * K;\n        var y = 20 * K;\n        var z = 30 * K;\n\n        Assert.True(x + y == z);\n    }\n\n    [Fact]\n    public void KelvinSubTest()\n    {\n        var x = 10 * K;\n        var y = 20 * K;\n        var z = 30 * K;\n\n        Assert.True(z - y == x);\n    }\n\n    [Fact]\n    public void KelvinScalar1Test()\n    {\n        var x = 10 * K;\n        var y = 20 * K;\n\n        Assert.True(x * 2.0 == y);\n    }\n\n    [Fact]\n    public void KelvinScalar2Test()\n    {\n        var x = 10 * K;\n        var y = 20 * K;\n\n        Assert.True(y / 2.0 == x);\n    }\n\n    [Fact]\n    public void KelvinAddCelsiusTest()\n    {\n        var x = 10 * K;\n        var y = 20 * degC;\n        var z = (10 * K) + (20 * degC).Kelvin;\n\n        Assert.True(x + y == z);\n    }\n\n    [Fact]\n    public void KelvinAddFahrenheitTest()\n    {\n        var x = 10 * K;\n        var y = 20 * degF;\n        var z = (10 * K) + (20 * degF).Kelvin;\n\n        Assert.True(x + y == z);\n    }\n\n    [Fact]\n    public void CtorThrowsBelowAbsZeroTest()\n    {\n        Assert.Throws<ArgumentOutOfRangeException>(() => -300 * degC);\n    }\n\n    [Fact]\n    public void RetrieveKValueTest()\n    {\n        var x = 100.0 * degC;\n        Assert.True(x.KValue == 373.15);\n    }\n\n    private double delta = 0.00001;\n\n    [Fact]\n    public void MassEqualityTests()\n    {\n        Assert.True(1000.Grams()                                        == 1.Kilograms());\n        Assert.True(1000.Kilograms()                                    == 1.Tonnes());\n        Assert.True(Math.Abs((16.Ounces()   - 1.Pounds()).Pounds)       < delta);\n        Assert.True(Math.Abs((14.Pounds()   - 1.Stones()).Pounds)       < delta);\n        Assert.True(Math.Abs((2240.Pounds() - 1.ImperialTons()).Pounds) < delta);\n        Assert.True(Math.Abs((2000.Pounds() - 1.ShortTon()).Pounds)     < delta);\n    }\n\n    [Fact]\n    public void PreludeMassEqualityTest()\n    {\n        // Metric units\n        Assert.True(1000 * g  == 1 * kg, \"g -> kg\");\n        Assert.True(1000 * kg == 1 * tonne, \"kg -> tonne\");\n        // Imperial units. We use Math.Abs to check these, as they will differ at some point down the decimal expansion due to the fact that we store the value internally in Kg\n        Mass sixteenOunces = 16 * ounce;\n        Mass onePound      = 1  * lb;\n        Assert.True(Math.Abs((sixteenOunces - onePound).Pounds) < delta, \"ounce -> pound\");\n        Mass fourteenPounds = 14 * lb;\n        Mass oneStone       = 1  * stone;\n        Assert.True(Math.Abs((fourteenPounds - oneStone).Pounds) < delta, \"lb -> stone\");\n        Mass oneHundredAndSixtyStones = 160 * stone;\n        Mass oneTonUk                 = 1   * ton;\n        Assert.True(Math.Abs((oneHundredAndSixtyStones - oneTonUk).Pounds) < delta, \"stone -> tonUK\");\n        Mass oneTonUs         = 1             * shortTon;\n        Mass oneTonUsinStones = 142.857142858 * stone;\n        Assert.True(Math.Abs((oneTonUsinStones - oneTonUs).Pounds) < delta, \"stone -> tonUS\");\n        // Metric against Imperial\n        Mass oneKilo         = 1            * kg;\n        Mass oneKiloInPounds = 2.2046226219 * lb;\n        Assert.True(Math.Abs((oneKilo - oneKiloInPounds).Pounds) < delta, \"kg -> pounds\");\n    }\n\n    [Fact]\n    public void PreludeMassCompareTest1()\n    {\n        Assert.True(1 * tonne > 1 * kg);\n    }\n\n    [Fact]\n    public void PreludeMassScalarTest2()\n    {\n        Assert.True(1 * kg       / 500 == 2 * g);\n        Assert.True(1 * kilogram / 500 == 2 * gram);\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/ValidationTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class ValidationTests\n{\n    public Func<string, string> ToUpper => x => x.ToUpper();\n\n    [Fact]\n    public void ValidationSeq_MapFails_Failure()\n    {\n        var failure = Fail<Seq<string>, int>([\"something went wrong\"])\n                          .MapFail(xs => xs.Map(ToUpper));\n\n        failure.Match(\n            Succ: _ => Assert.Fail(\"should never get here\"),\n            Fail: errors =>\n                  {\n                      Assert.True(errors.Count == 1);\n                      Assert.True(errors.Head  == \"SOMETHING WENT WRONG\");\n                  });\n    }\n\n    [Fact]\n    public void ValidationSeq_MapFails_Success()\n    {\n        var success = Success<Seq<string>, int>(42)\n                         .MapFail(xs => xs.Map(ToUpper));\n\n        success.Match(\n            Succ: succ => Assert.True(succ == 42),\n            Fail: errors => Assert.Fail(\"should never get here\"));\n    }\n\n    [Fact]\n    public void ValidationSeq_BiMap_Failure()\n    {\n        var failure = Fail<Seq<string>, int>([\"something went wrong\"])\n                        .BiMap(Succ: succ => succ + 1,\n                               Fail: xs => xs.Map(ToUpper));\n\n        failure.Match(\n            Succ: _ => Assert.Fail(\"should never get here\"),\n            Fail: errors =>\n                  {\n                      Assert.True(errors.Count == 1);\n                      Assert.True(errors.Head  == \"SOMETHING WENT WRONG\");\n                  });\n    }\n\n    [Fact]\n    public void ValidationSeq_BiMap_Success()\n    {\n        var success = Success<Seq<string>, int>(42)\n           .BiMap(Succ: succ => succ + 1,\n                  Fail: xs => xs.Map(ToUpper));\n\n        success.Match(\n            Succ: succ => Assert.True(succ == 43),\n            Fail: err => Assert.Fail(\"should never get here\"));\n    }\n\n    [Fact]\n    public void ValidCreditCardTest()\n    {\n        // Valid test\n        var res = ValidateCreditCard(\"Paul\", \"1234567891012345\", \"10\", \"2020\");\n\n        res.Match(\n            Succ: cc =>\n                  {\n                      Assert.True(cc.CardHolder == \"Paul\");\n                      Assert.True(cc.Month      == 10);\n                      Assert.True(cc.Year       == 2020);\n                      Assert.True(cc.Number     == \"1234567891012345\");\n                  },\n            Fail: err => Assert.Fail(\"should never get here\"));\n    }\n\n    [Fact]\n    public void InValidCreditCardNumberTest()\n    {\n        var res = ValidateCreditCard(\"Paul\", \"ABCDEF567891012345\", \"10\", \"2020\");\n        Assert.True(res.IsFail);\n\n        res.Match(\n            Succ: _ => Assert.Fail(\"should never get here\"),\n            Fail: errors =>\n                  {\n                      Assert.True(errors.Count             == 2);\n                      Assert.True(errors.Head.Message      == \"only numbers are allowed\");\n                      Assert.True(errors.Tail.Head.Message == \"can not exceed 16 characters\");\n                  });\n    }\n\n    [Fact]\n    public void ExpiredAndInValidCreditCardNumberTest()\n    {\n        var res = ValidateCreditCard(\"Paul\", \"ABCDEF567891012345\", \"1\", \"2001\");\n        Assert.True(res.IsFail);\n\n        res.Match(\n            Succ: _ => Assert.Fail(\"should never get here\"),\n            Fail: errors =>\n                  {\n                      Assert.True(errors.Count                  == 3);\n                      Assert.True(errors.Head.Message           == \"only numbers are allowed\");\n                      Assert.True(errors.Tail.Head.Message      == \"can not exceed 16 characters\");\n                      Assert.True(errors.Tail.Tail.Head.Message == \"card has expired\");\n                  });\n    }\n\n    /// <summary>\n    /// Validates the string has only ASCII characters\n    /// </summary>\n    public static Validation<Error, string> AsciiOnly(string str) =>\n        str.AsIterable().ForAll(c => c <= 0x7f)\n            ? Success<Error, string>(str)\n            : Fail<Error, string>(Error.New(\"only ascii characters are allowed\"));\n\n    /// <summary>\n    /// Creates a delegate that when passed a string will validate that it's below\n    /// a specific length\n    /// </summary>\n    public static Func<string, Validation<Error, string>> MaxStrLength(int max) =>\n        str =>\n            str.Length <= max\n                ? Success<Error, string>(str)\n                : Fail<Error, string>(Error.New($\"can not exceed {max} characters\"));\n\n    /// <summary>\n    /// Validates that the string passed contains only digits\n    /// </summary>\n    public static Validation<Error, string> DigitsOnly(string str) =>\n        str.AsIterable().ForAll(Char.IsDigit)\n            ? Success<Error, string>(str)\n            : Fail<Error, string>(Error.New($\"only numbers are allowed\"));\n\n    /// <summary>\n    /// Uses parseInt which returns an Option and converts it to a Validation\n    /// value with a default Error if the parse fails\n    /// </summary>\n    public static Validation<Error, int> ToInt(string str) =>\n        parseInt(str).ToValidation(Error.New(\"must be a number\"));\n\n    /// <summary>\n    /// Validates that the value passed is a month\n    /// </summary>\n    public static Validation<Error, int> ValidMonth(int month) =>\n        month >= 1 && month <= 12\n            ? Success<Error, int>(month)\n            : Fail<Error, int>(Error.New($\"invalid month\"));\n\n    /// <summary>\n    /// Validates that the value passed is a positive number\n    /// </summary>\n    public static Validation<Error, int> PositiveNumber(int value) =>\n        value > 0\n            ? Success<Error, int>(value)\n            : Fail<Error, int>(Error.New($\"must be positive\"));\n\n    /// <summary>\n    /// Takes todays date and builds a delegate that can take a month and year\n    /// to see if the credit card has expired.\n    /// </summary>\n    public static Func<int, int, Validation<Error, (int month, int year)>> ValidExpiration(int currentMonth, int currentYear) =>\n        (month, year) =>\n            year > currentYear || (year == currentYear && month >= currentMonth)\n                ? Success<Error, (int, int)>((month, year))\n                : Fail<Error, (int, int)>(Error.New($\"card has expired\"));\n\n    /// <summary>\n    /// Validate that the card holder is ASCII and has a maximum of 30 characters\n    /// This uses the | operator as a disjunction computation.  If any items are\n    /// Failed then the errors are collected and returned.  If they all pass then\n    /// the Success value from the first item is propagated.  This only works when\n    /// all the operands are of the same type and you only care about the first\n    /// success value.  Which in this case is cardHolder for both.\n    /// </summary>\n    public static Validation<Error, string> ValidateCardHolder(string cardHolder) =>\n        AsciiOnly(cardHolder) | MaxStrLength(30)(cardHolder);\n\n    /// <summary>\n    /// This is the main validation function for validating a credit card\n    /// </summary>\n    public static Validation<Error, CreditCard> ValidateCreditCard(string cardHolder, string number, string expMonth, string expYear)\n    {\n        var fakeDateTime = new DateTime(year: 2019, month: 1, day: 1);\n        var cardHolderV  = ValidateCardHolder(cardHolder);\n        var numberV      = DigitsOnly(number) & MaxStrLength(16)(number);\n        var validToday   = ValidExpiration(fakeDateTime.Month, fakeDateTime.Year);\n\n        // This falls back to monadic behaviour because validToday needs both\n        // a month and year to continue.  \n        var monthYear = from m in ToInt(expMonth).Bind(ValidMonth)\n                        from y in ToInt(expYear).Bind(PositiveNumber)\n                        from my in validToday(m, y)\n                        select my;\n\n        // The items to validate are placed in a tuple, then you call apply to\n        // confirm that all items have passed the validation.  If not then all\n        // the errors are collected.  If they have passed then the results are\n        // passed to the lambda function allowing the creation of the\n        // CreditCard object.\n        return (cardHolderV, numberV, monthYear).Apply((c, num, my) => new CreditCard(c, num[0], my.month, my.year)).As();\n    }\n\n    public class CreditCard\n    {\n        public readonly string CardHolder;\n        public readonly string Number;\n        public readonly int Month;\n        public readonly int Year;\n\n        public CreditCard(string c, string num, int month, int year)\n        {\n            CardHolder = c;\n            Number = num;\n            Month = month;\n            Year = year;\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/VectorClockTests.cs",
    "content": "using Newtonsoft.Json;\nusing Xunit;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt.Tests\n{\n    public class VectorClockTests\n    {\n        [Fact]\n        public void SerialisationTest1()\n        {\n            var vc1 = VectorClock<char>.fromList(Seq(('a', 1L), ('b', 2L)));\n\n            var jvc = JsonConvert.SerializeObject(vc1);\n            var vc2 = JsonConvert.DeserializeObject<VectorClock<char>>(jvc);\n\n            Assert.Equal(vc1, vc2);\n        }\n\n        [Fact]\n        public void MaxTest()\n        {\n            var vc1 = VectorClock.fromList(Seq(('a', 1L), ('b', 2L)));\n            var vc2 = VectorClock.fromList(Seq(('c', 3L), ('b', 1L)));\n\n            var vc3 = VectorClock.max(vc1, vc2);\n            \n            var exp = VectorClock.fromList(Seq(('a', 1L), ('b', 2L), ('c', 3L)));\n\n            Assert.Equal(vc3, exp);\n        }\n\n        [Fact]\n        public void CausesTest()\n        {\n            var vc1 = VectorClock.fromList(Seq(('a', 1L), ('b', 2L)));\n            var vc2 = VectorClock.fromList(Seq(('a', 2L), ('b', 2L)));\n\n            var rel = VectorClock.relation(vc1, vc2);\n            var flg = VectorClock.causes(vc1, vc2);\n            \n            Assert.Equal(Relation.Causes, rel);\n            Assert.True(flg);\n        }\n\n        [Fact]\n        public void CausedByTest()\n        {\n            var vc1 = VectorClock.fromList(Seq(('a', 2L), ('b', 2L)));\n            var vc2 = VectorClock.fromList(Seq(('a', 1L), ('b', 2L)));\n\n            var rel = VectorClock.relation(vc1, vc2);\n            var flg = VectorClock.causes(vc1, vc2);\n            \n            Assert.Equal(Relation.CausedBy, rel);\n            Assert.False(flg);\n        }\n\n        [Fact]\n        public void ConcurrentTest()\n        {\n            var vc1 = VectorClock.fromList(Seq(('a', 2L), ('b', 2L)));\n            var vc2 = VectorClock.fromList(Seq(('a', 1L), ('b', 3L)));\n\n            var rel = VectorClock.relation(vc1, vc2);\n            var flg = VectorClock.causes(vc1, vc2);\n            \n            Assert.Equal(Relation.Concurrent, rel);\n            Assert.False(flg);\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/VersionHashMapTests.cs",
    "content": "using System.Linq;\nusing Xunit;\n\nnamespace LanguageExt.Tests;\n\npublic class VersionHashMapTests\n{\n    [Fact]\n    public void Write_with_no_conflicts()\n    {\n        var data = VersionHashMap<string, int>.Empty;\n\n        data.Update(data[\"a\"].Write(\"paul\", 1));\n        data.Update(data[\"b\"].Write(\"james\", 1));\n        data.Update(data[\"b\"].Write(\"james\", 2));\n        data.Update(data[\"b\"].Write(\"gavin\", 3));\n\n        var str = data.AsIterable().OrderBy(p => p.Key).AsIterable().ToSeq().ToString();\n\n        Assert.True(str == \"[(a, 1), (b, 3)]\");\n    }\n        \n    [Fact]\n    public void Write_with_conflicts_that_are_resolved_to_last_write_wins1()\n    {\n        var data = VersionHashMap<string, int>.Empty;\n\n        var client1 = data[\"a\"].Write(\"paul\", 10000, 1);\n        var client2 = data[\"a\"].Write(\"james\", 5000, 2);\n        var client3 = data[\"b\"].Write(\"gavin\", 500, 3);\n\n        data.Update(client1);\n        data.Update(client2);\n        data.Update(client3);\n\n        var str = data.AsIterable().OrderBy(p => p.Key).AsIterable().ToSeq().ToString();\n\n        Assert.True(str == \"[(a, 1), (b, 3)]\");\n    }\n        \n    [Fact]\n    public void Write_with_conflicts_that_are_resolved_to_last_write_wins2()\n    {\n        var data = VersionHashMap<string, int>.Empty;\n\n        var client1 = data[\"a\"].Write(\"paul\", 10000, 1);\n        var client2 = data[\"a\"].Write(\"james\", 5000, 2);\n        var client3 = data[\"b\"].Write(\"gavin\", 500, 3);\n\n        data.Update(client2);\n        data.Update(client1);\n        data.Update(client3);\n\n        var str = data.AsIterable().OrderBy(p => p.Key).AsIterable().ToSeq().ToString();\n\n        Assert.True(str == \"[(a, 1), (b, 3)]\");\n    }\n        \n    [Fact]\n    public void Write_with_conflicts_that_are_resolved_to_first_write_wins1()\n    {\n        var data = VersionHashMap<FirstWriteWins<int>, string, int>.Empty;\n\n        var client1 = data[\"a\"].Write(\"paul\", 10000, 1);\n        var client2 = data[\"a\"].Write(\"james\", 5000, 2);\n        var client3 = data[\"b\"].Write(\"gavin\", 500, 3);\n\n        data.Update(client1);\n        data.Update(client2);\n        data.Update(client3);\n\n        var str = data.AsIterable().OrderBy(p => p.Key).AsIterable().ToSeq().ToString();\n\n        Assert.True(str == \"[(a, 2), (b, 3)]\");\n    }\n        \n    [Fact]\n    public void Write_with_conflicts_that_are_resolved_to_first_write_wins2()\n    {\n        var data = VersionHashMap<FirstWriteWins<int>, string, int>.Empty;\n\n        var client1 = data[\"a\"].Write(\"paul\", 10000, 1);\n        var client2 = data[\"a\"].Write(\"james\", 5000, 2);\n        var client3 = data[\"b\"].Write(\"gavin\", 500, 3);\n\n        data.Update(client2);\n        data.Update(client1);\n        data.Update(client3);\n\n        var str = data.AsIterable().OrderBy(p => p.Key).AsIterable().ToSeq().ToString();\n\n        Assert.True(str == \"[(a, 2), (b, 3)]\");\n    }\n}\n"
  },
  {
    "path": "LanguageExt.Tests/WithTests.cs",
    "content": "﻿/*\n \n TODO: Restore when we get SourceGen\n \nusing System;\nusing System.Collections.Generic;\nusing System.Text;\nusing Xunit;\n\nnamespace LanguageExt.Tests\n{\n    public class WithTests\n    {\n        // Test that the generated With() only supplies valid properties to the Record constructor.\n        [Fact]\n        public void WithIsGeneratedForValidProperties()\n        {\n            var p1 = new PropertyFields(\"\");\n            var p2 = p1.With(Prop1: \"p\");\n            Assert.True(p2.Prop1 == \"p\");\n        }\n    }\n\n    [With]\n    public partial class PropertyFields : Record<PropertyFields>\n    {\n        public string Prop1 { get; }  // Valid record field\n        public string Prop2 { get; set; } // Invalid - set accessor not allowed\n        public string Prop3 { get => \"\"; } // Invalid - Expression body not allowed\n        public string Prop4 { get { return \"\"; } } // Invalid - Body not allowed\n        public string Prop5 { get; } = \"\"; // Invalid - Initializer not allowed\n\n        // Prop1 is the only valid record field that we'll need to cater for in our constructor.\n        public PropertyFields(string prop1)\n        {\n            Prop1 = prop1;\n        }\n    }\n\n}\n*/\n"
  },
  {
    "path": "LanguageExt.XUnitExt/EffExtensions.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Sys.Test;\n\nnamespace LanguageExt;\n\npublic static class EffExtensions\n{\n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Eff helpers\n    //\n\n    public static void AssertFail<A>(this Eff<Runtime, A> ma)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertFail();\n    }\n\n    public static void AssertFail<A>(this Eff<Runtime, A> ma, string userMessage)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertFail(userMessage);\n    }\n\n    public static void AssertSucc<A>(this Eff<Runtime, A> ma)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertSucc();\n    }\n\n    public static void AssertSucc<A>(this Eff<Runtime, A> ma, string userMessage)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertSucc(userMessage);\n    }\n\n    public static void AssertFail<A>(this Eff<Runtime, A> ma, Error expected)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertFail(expected);\n    }\n\n    public static void AssertFail<A>(this Eff<Runtime, A> ma, Error expected, string userMessage)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertFail(expected, userMessage);\n    }\n\n    public static void AssertSucc<A>(this Eff<Runtime, A> ma, A expected)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertSucc(expected);\n    }\n\n    public static void AssertSucc<A>(this Eff<Runtime, A> ma, A expected, string userMessage)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertSucc(expected, userMessage);\n    }\n\n    public static void AssertFail<A>(this Eff<Runtime, A> ma, Func<Error, bool> predicate)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertFail(predicate);\n    }\n\n    public static void AssertFail<A>(this Eff<Runtime, A> ma, Func<Error, bool> predicate, string userMessage)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertFail(predicate, userMessage);\n    }\n\n    public static void AssertSucc<A>(this Eff<Runtime, A> ma, Func<A, bool> predicate)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertSucc(predicate);\n    }\n\n    public static void AssertSucc<A>(this Eff<Runtime, A> ma, Func<A, bool> predicate, string userMessage)\n    {\n        using var rt = Runtime.New();\n        ma.Run(rt, EnvIO.New()).AssertSucc(predicate, userMessage);\n    }\n    \n    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n    //\n    //  Eff helpers\n    //\n\n    public static void AssertFail<A>(this Eff<A> ma) =>\n        ma.Run().AssertFail();\n\n    public static void AssertFail<A>(this Eff<A> ma, string userMessage) =>\n        ma.Run().AssertFail(userMessage);\n\n    public static void AssertSucc<A>(this Eff<A> ma) =>\n        ma.Run().AssertSucc();\n\n    public static void AssertSucc<A>(this Eff<A> ma, string userMessage) =>\n        ma.Run().AssertSucc(userMessage);\n    \n    public static void AssertFail<A>(this Eff<A> ma, Error expected) =>\n        ma.Run().AssertFail(expected);\n\n    public static void AssertFail<A>(this Eff<A> ma, Error expected, string userMessage) =>\n        ma.Run().AssertFail(expected, userMessage);\n\n    public static void AssertSucc<A>(this Eff<A> ma, A expected) =>\n        ma.Run().AssertSucc(expected);\n\n    public static void AssertSucc<A>(this Eff<A> ma, A expected, string userMessage) =>\n        ma.Run().AssertSucc(expected, userMessage);\n    \n    public static void AssertFail<A>(this Eff<A> ma, Func<Error, bool> predicate) =>\n        ma.Run().AssertFail(predicate);\n\n    public static void AssertFail<A>(this Eff<A> ma, Func<Error, bool> predicate, string userMessage) =>\n        ma.Run().AssertFail(predicate, userMessage);\n\n    public static void AssertSucc<A>(this Eff<A> ma, Func<A, bool> predicate) =>\n        ma.Run().AssertSucc(predicate);\n\n    public static void AssertSucc<A>(this Eff<A> ma, Func<A, bool> predicate, string userMessage) =>\n        ma.Run().AssertSucc(predicate, userMessage);    \n}\n"
  },
  {
    "path": "LanguageExt.XUnitExt/EitherExtensions.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt;\n\npublic static class EitherExtensions\n{\n    public static void AssertLeft<L, R>(this Either<L, R> ma) =>\n        AssertLeft(ma, \"Expected  to be in a Left state\");\n\n    public static void AssertLeft<L, R>(this Either<L, R> ma, string userMessage) =>\n        Assert.True(ma.IsLeft, userMessage);\n\n    public static void AssertRight<L, R>(this Either<L, R> ma) =>\n        AssertRight(ma, \"Expected to be in a Right state\");\n\n    public static void AssertRight<L, R>(this Either<L, R> ma, string userMessage) =>\n        Assert.True(ma.IsRight, userMessage);\n    \n    public static void AssertLeft<L, R>(this Either<L, R> ma, L expected) =>\n        AssertLeft(ma, expected, $\"Expected to be in a Left state with a value of {expected}\");\n\n    public static void AssertLeft<L, R>(this Either<L, R> ma, L expected, string userMessage) =>\n        Assert.True(ma.IsLeft && (expected?.Equals((L?)ma) ?? false), userMessage);\n\n    public static void AssertRight<L, R>(this Either<L, R> ma, R expected) =>\n        AssertRight(ma, expected, $\"Expected to be in a Right state with a value of {expected}\");\n\n    public static void AssertRight<L, R>(this Either<L, R> ma, R expected, string userMessage) =>\n        Assert.True(ma.IsRight && (expected?.Equals((R?)ma) ?? false), userMessage);\n    \n    public static void AssertLeft<L, R>(this Either<L, R> ma, Func<L, bool> predicate) =>\n        AssertLeft(ma, predicate, \"Expected to be in a Left state with a predicate that returns true\");\n\n    public static void AssertLeft<L, R>(this Either<L, R> ma, Func<L, bool> predicate, string userMessage) =>\n        Assert.True(ma.IsLeft && predicate((L)ma), userMessage);\n\n    public static void AssertRight<L, R>(this Either<L, R> ma, Func<R, bool> predicate) =>\n        AssertRight(ma, predicate, \"Expected to be in a Right state with a predicate that returns true\");\n\n    public static void AssertRight<L, R>(this Either<L, R> ma, Func<R, bool> predicate, string userMessage) =>\n        Assert.True(ma.IsRight && predicate((R)ma), userMessage);    \n}\n"
  },
  {
    "path": "LanguageExt.XUnitExt/ErrorExtensions.cs",
    "content": "﻿using LanguageExt.Common;\nusing static LanguageExt.Prelude;\n\nnamespace LanguageExt;\n\npublic static partial class AssertExt\n{\n    /// <summary>\n    /// Asserts that the action throws an `Error`\n    /// </summary>\n    public static Unit Throws<A>(Error error, Func<A> action)\n    {\n        try\n        {\n            action();\n            throw new Exception(\"Expected error: \" + error + \", but got none\");\n        }\n        catch (Exception e)\n        {\n            if (Error.New(e).Is(error))\n            {\n                return unit;\n            }\n            else\n            {\n                throw new Exception(\"Expected error: \" + error + \", but got: \" + e);\n            }\n        }\n    }\n    \n    /// <summary>\n    /// Asserts that the action throws an `Error`\n    /// </summary>\n    public static Unit Throws(Error error, Action action)\n    {\n        try\n        {\n            action();\n            throw new Exception(\"Expected error: \" + error + \", but got none\");\n        }\n        catch (Exception e)\n        {\n            if (Error.New(e).Is(error))\n            {\n                return unit;\n            }\n            else\n            {\n                throw new Exception(\"Expected error: \" + error + \", but got: \" + e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "LanguageExt.XUnitExt/FinExtensions.cs",
    "content": "using LanguageExt.Common;\nusing Xunit;\n\nnamespace LanguageExt;\n\npublic static class FinExtensions\n{\n    public static void AssertFail<A>(this Fin<A> ma) =>\n        AssertFail(ma, \"Expected to be in a Fail state\");\n\n    public static void AssertFail<A>(this Fin<A> ma, string userMessage) =>\n        Assert.True(ma.IsFail, userMessage);\n\n    public static void AssertSucc<A>(this Fin<A> ma) =>\n        AssertSucc(ma, \"Expected to be in a Succ state\");\n\n    public static void AssertSucc<A>(this Fin<A> ma, string userMessage) =>\n        Assert.True(ma.IsSucc, userMessage);\n    \n    public static void AssertFail<A>(this Fin<A> ma, Error expected) =>\n        AssertFail(ma, expected, $\"Expected to be in a Fail state with a value of {expected}\");\n\n    public static void AssertFail<A>(this Fin<A> ma, Error expected, string userMessage) =>\n        Assert.True(ma.IsFail && expected.Is((Error)ma), userMessage);\n\n    public static void AssertSucc<A>(this Fin<A> ma, A expected) =>\n        AssertSucc(ma, expected, $\"Expected to be in a Succ state with a value of {expected}\");\n\n    public static void AssertSucc<A>(this Fin<A> ma, A expected, string userMessage) =>\n        Assert.True(ma.IsSucc && (expected?.Equals((A?)ma) ?? false), userMessage);\n    \n    public static void AssertFail<A>(this Fin<A> ma, Func<Error, bool> predicate) =>\n        AssertFail(ma, predicate, \"Expected to be in a Fail state with a predicate that returns true\");\n\n    public static void AssertFail<A>(this Fin<A> ma, Func<Error, bool> predicate, string userMessage) =>\n        Assert.True(ma.IsFail && predicate((Error)ma), userMessage);\n\n    public static void AssertSucc<A>(this Fin<A> ma, Func<A, bool> predicate) =>\n        AssertSucc(ma, predicate, \"Expected to be in a Succ state with a predicate that returns true\");\n\n    public static void AssertSucc<A>(this Fin<A> ma, Func<A, bool> predicate, string userMessage) =>\n        Assert.True(ma.IsSucc && predicate((A)ma), userMessage);        \n}\n"
  },
  {
    "path": "LanguageExt.XUnitExt/IOExtensions.cs",
    "content": "using LanguageExt.Common;\nusing LanguageExt.Sys.Test;\nusing Xunit;\n\nnamespace LanguageExt;\n\npublic static class IOExtensions\n{\n    public static void AssertFail<A>(this IO<A> ma) => \n        ma.AssertFail(_ => true, \"Expected to be in a Fail state\");\n\n    public static void AssertFail<A>(this IO<A> ma, string userMessage) =>\n        ma.AssertFail(_ => true, userMessage);\n\n    public static void AssertSucc<A>(this IO<A> ma) =>\n        ma.AssertSucc(_ => true, \"Expected to be in a Succ state\");\n    \n    public static void AssertSucc<A>(this IO<A> ma, string userMessage) =>\n        ma.AssertSucc(_ => true, userMessage);\n    \n    public static void AssertFail<A>(this IO<A> ma, Error expected) =>\n        ma.AssertFail(e => e.Is(expected), \n                      e => $\"Expected to be in a Fail state with an Error that equals '{expected}', instead got: '{e}'\");\n\n    public static void AssertFail<A>(this IO<A> ma, Error expected, string userMessage) =>\n        ma.AssertFail(e => e.Is(expected), userMessage);\n\n    public static void AssertSucc<A>(this IO<A> ma, A expected) =>\n        ma.AssertSucc(x => expected?.Equals(x) ?? false, \n                      x => $\"Expected to be in a Succ state with a result that equals {expected}, instead got: {x}\");\n\n    public static void AssertSucc<A>(this IO<A> ma, A expected, string userMessage) =>\n        ma.AssertSucc(x => expected?.Equals(x) ?? false, userMessage);\n    \n    public static void AssertFail<A>(this IO<A> ma, Func<Error, bool> predicate)\n    {\n        try\n        {\n            ma.Run().Ignore();\n        }\n        catch (Exception e)\n        {\n            Assert.True(predicate(Error.New(e)), \"Expected to be in a Fail state with a predicate that returns true\");\n        }\n    }\n\n    public static void AssertFail<A>(this IO<A> ma, Func<Error, bool> predicate, string userMessage)\n    {\n        try\n        {\n            ma.Run().Ignore();\n        }\n        catch (Exception e)\n        {\n            Assert.True(predicate(Error.New(e)), userMessage);\n        }\n    }\n\n    public static void AssertFail<A>(this IO<A> ma, Func<Error, bool> predicate, Func<Error, string> userMessage)\n    {\n        try\n        {\n            ma.Run().Ignore();\n        }\n        catch (Exception e)\n        {\n            Assert.True(predicate(e), userMessage(e));\n        }\n    }\n\n    public static void AssertSucc<A>(this IO<A> ma, Func<A, bool> predicate) =>\n        Assert.True(predicate(ma.Run()), \"Expected to be in a Succ state with a predicate that returns true\");\n\n    public static void AssertSucc<A>(this IO<A> ma, Func<A, bool> predicate, string userMessage) => \n        Assert.True(predicate(ma.Run()), userMessage);\n\n    public static void AssertSucc<A>(this IO<A> ma, Func<A, bool> predicate, Func<A, string> userMessage)\n    {\n        var x = ma.Run();\n        Assert.True(predicate(x), userMessage(x));\n    }\n}\n"
  },
  {
    "path": "LanguageExt.XUnitExt/LanguageExt.XUnitExt.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <None Update=\"README.nuget.md\">\n        <Pack>true</Pack>\n        <PackagePath>/</PackagePath>\n      </None>\n    </ItemGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n      <ProjectReference Include=\"..\\LanguageExt.Streaming\\LanguageExt.Streaming.csproj\" />\n      <ProjectReference Include=\"..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    </ItemGroup>\n\n    <ItemGroup>\n      <PackageReference Include=\"xunit\" Version=\"2.7.0\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "LanguageExt.XUnitExt/OptionExtensions.cs",
    "content": "using Xunit;\n\nnamespace LanguageExt;\n\npublic static class OptionExtensions\n{\n    public static void AssertNone<A>(this Option<A> ma) =>\n        AssertNone(ma, \"Expected to be in a None state\");\n\n    public static void AssertNone<A>(this Option<A> ma, string userMessage) =>\n        Assert.True(ma.IsNone, userMessage);\n\n    public static void AssertSome<A>(this Option<A> ma) =>\n        AssertSome(ma, \"Expected to be in a Some state\");\n\n    public static void AssertSome<A>(this Option<A> ma, string userMessage) =>\n        Assert.True(ma.IsSome, userMessage);\n    \n    public static void AssertSome<A>(this Option<A> ma, A expected) =>\n        AssertSome(ma, expected, $\"Expected to be in a Some state with a value of {expected}\");\n\n    public static void AssertSome<A>(this Option<A> ma, A expected, string userMessage) =>\n        Assert.True(ma.IsSome && expected.Equals((A)ma), userMessage);\n    \n    public static void AssertSome<A>(this Option<A> ma, Func<A, bool> predicate) =>\n        AssertSome(ma, predicate, \"Expected to be in a Some state with a predicate that returns true\");\n\n    public static void AssertSome<A>(this Option<A> ma, Func<A, bool> predicate, string userMessage) =>\n        Assert.True(ma.IsSome && predicate((A)ma), userMessage);    \n}\n"
  },
  {
    "path": "LanguageExt.XUnitExt/README.nuget.md",
    "content": "# LanguageExt.XUnitExt\n\nExtensions for XUnit that are aware of language-ext types.\n"
  },
  {
    "path": "LanguageExt.XUnitExt/SourceExtensions.cs",
    "content": "namespace LanguageExt;\n\npublic static partial class AssertExt\n{\n}\n"
  },
  {
    "path": "Major Version Release Notes/Version 2/README.md",
    "content": "# Version 2 Release Notes\n\nVersion 2.0 of Language-Ext is now in released.  This is a major overhaul of every type in the system.  I have also broken out the `LanguageExt.Process` actor system into its own repo, it is now named *Echo*, so if you're using that you should [head over to the repo](https://github.com/louthy/echo-process) and follow that.  It's still in alpha - it's feature complete, it just needs more testing - so it's lagging behind at the moment.  If you're using both lang-ext Core and the Echo Process system then wait until the Echo Process system is released before migrating to the new Core.\n\nVersion 2.0 of Language-Ext actually just started out as a branch where I was trying out a new technique for doing ad-hoc polymorphism in C# (think somewhere between Haskell typeclasses and Scala implicits).  \n\nI didn't expect it to lead to an entire re-write.  So a word of warning, there are many areas that I know will be breaking changes, but some I don't.  Breaking changes will 99% of the time be compile time errors (rather than changes in behaviour that silently affect your code).  So although I don't expect any major issues, For any large projects I would put aside an afternoon to fix up any compilation breakages.  \n\nOften the breakages are for things like rectifying naming inconsistencies (for example some bi-map functions were named `Map`, some named `BiMap`, they're all now `BiMap`), another example is that all collection types (`Lst`, `Map`, etc.) are now structs.  So any code that does this will fail to compile:\n```c\n    Map<int, string> x = null;\n```\nThe transformer extensions have been overhauled too (they provided overloads for nested monadic types, `Option<Lst<A>>` for example).  If you were cheating trying to get directly at values by calling `Lift` or `LiftUnsafe`, well, now you can't.  It was a bad idea that was primarily to make the old transformer types work.  So they're gone.  \n\nThe overloads of `Select` and `SelectMany` are more restricted now, because combining different monadic types could lead to some type resolution issues with the compiler.  You will now need to lift your types into the context of the LINQ expression (there are now lots of extensions to do that: `ToOption`, `ToTry`, etc.)\n\n> For the problems you will inevitablity have with upgrading to language-ext 2.0, you will also have an enormous amount of new benefits and possibilities.  \nMy overriding goal with this library is to try and provide a safer environment in which to write C#.  Version 1 was mostly trying to protect the programmer from null and mutable state.  Version 2 is very much focussed on improving our lot when implementing abstract types.  \n\nInheritance based polymorphism is pretty much accepted to be the worst performer in the polymorphic world.  Our other option is parametric polymorphism (generics).  With this release I have facilitated [ad-hoc polymorphism](https://en.wikipedia.org/wiki/Ad_hoc_polymorphism) with a little known technique in C#.  \n\nSo for the first time it's possible to write numeric methods once for all numeric types or do structural equality testing that you can rely on. \n\nAlso there is support for the much more difficult higher-order polymorphic types like `Monad<MA, A>`.  LanguageExt 2.0 provides a fully type-safe and efficient approach to working with higher order types.  So yes, you can now write functions that take monads, or functors, or applicatives, and return specialised values (rather than abstract or dynamic values).  Instead of writing a function that takes an `Option<A>`, you can write one that takes any monadic type, bind them, join them, map them, and return the concrete type that you pushed in.\n\nOf course without compiler or runtime support for higher-order generics some hoops need to be jumped through (and I'm sure there will be some Haskell purist losing their shit over the approach).  But at no point is the integrity of your types affected.  Often the technique requires quite a large amount of generic argument typing, but if you want to write the super generic code, it's now possible.  I don't know of any other library that provides this functionality.\n\nThis has allowed the transformer extensions to become more powerful too (because the code generator that emits them can now use the type-class/instance system).  The `Writer` monad can now work with any output type (as long as it has a `Monoid` instance), so it's not limited to telling its output to an `IEnumerable`, it can be a `Lst`, a `string`, an `int`, or whatever `Monoid` you specify.\n\n> Personally I find this very elegant and exciting.  It has so much potential, but many will be put off by the amount of generic args typing they need to do.  If anybody from the Rosyln team is reading this, please for the love of god help out with the issues around constraints and excessive specifying of generic arguments.  The power is here, but needs more support.\n\nScroll down to the section on Ad-hoc polymorphism for more details.\n\n## Documentation\n\n[Full API documentation can be found here](https://louthy.github.io/language-ext/index.htm)\n\n## Bug fixes\n\n* Fix for `Lst.RemoveAt(index)` - certain tree arrangements caused this function to fail\n* Fix for `HSet` (now `HashSet`) constructor bug - constructing with an enumerable always failed\n\n## New features - LanguageExt.Core\n\n### New collection types:\n\n Type                                       | Description\n--------------------------------------------|--------------\n`Seq<A>`                                    | Cons-like, singly-linked list\n`HashSet<A>`                                | Ordering is done by `GetHashCode()`.  Existence testing is with `EqualityComparer<A>.Default.Equals(a,b)`\n`HashMap<A, B>`                             | Ordering is done by `GetHashCode()`.  Existence testing is with `EqualityComparer<A>.Default.Equals(a,b)`\n`HashSet<EqA, A> where EqA : struct, Eq<A>` | Ordering is done by `GetHashCode()`.  Existence testing is with `default(EqA).Equals(a,b)`\n`HashMap<EqA, A, B>`                        | Ordering is done by `GetHashCode()`.  Existence testing is with `default(EqA).Equals(a,b)`\n`Set<OrdA, A> where OrdA : struct, Ord<A>`  | Ordering is done by `default(OrdA).Compare(a,b)`.  Existence testing is with `default(OrdA).Equals(a,b)`\n`Map<EqA, A, B>`                            | Ordering is done by `default(OrdA).Compare(a,b)`.  Existence testing is with `default(OrdA).Equals(a,b)`\n`Arr<A>`                                    | Immutable array.  Has the same access speed as the built-in array type, but with immutable cells.  Modification is expensive, due to the entire array being copied per operation (although for very small arrays this would be more efficient than `Lst<T>` or `Set<T>`).\n`Lst<PredList, A> where PredList : struct, Pred<ListInfo>` | This allows lists to run a predicate on the `Count` property of the list after construction.  \n`Lst<PredList, PredItem, A> where PredItem : struct, Pred<A>` | This allows lists to run a predicate on the `Count` property of the list after construction and on items as they're being added to the list.  \n\nAs you can see above there are new type-safe key versions of `Set`, `HashSet`, `Map`, and `HashMap`.  Imagine you want to sort the value of a set of strings in a case-insensitive way (without losing information by calling `value.ToLower()`).\n```c#\n    var map = Set<TStringOrdinalIgnoreCase, string>(...)\n```\nThe resulting type would be incompatible with:\n```c#\n    Set<TString, string>, or Set<TStringOrdinal, string>\n```\nAnd is therefore more type-safe than just using Set<string>.  [Examples](https://github.com/louthy/language-ext/blob/type-classes/LanguageExt.Tests/SetTests.cs)\n\nThe two new predicate versions of `Lst` allow for properties of the list to travel with the type.  So for example this shows how you can enforce a list to be non-empty:\n```c#\n    public int Product(Lst<NonEmpty, int> list) =>\n        list.Fold(1, (s, x) => s * x);\n```\nThere are implicit conversion operators between `Lst<A>` and `Lst<PredList, A>`, and between `Lst<A>` and `Lst<PredList, PredItem, A>`.  They don't need to reallocate the collection, but converting to a more constrained type will cause the validation to run.  This is very light for constructing `Lst<PredList, A>`, but will cause every item in the list to be validated for `Lst<PredList, PredItem, A>`.\n\nAnd so it's possible to do this:\n```c#\n    Lst<int> list = List<int>();\n\n    var res = Product(list);  // ArgumentOutOfRangeException\n```\nThat will throw an `ArgumentOutOfRangeException` because the list is empty.  Whereas this is fine:\n```c#\n    Lst<int> list = List<int>(1, 2, 3, 4, 5);\n\n    var res = Product(list); // 120\n```\nTo construct the predicate list types directly, call:\n```c#\n    Lst<NonEmpty, int> list = List<NonEmpty, int>(1, 2, 3, 4, 5);\n```\nThe second type of predicate `Lst` is `Lst<PredList, PredItem, A>`.  `PredItem` is a predicate that's run against every item being added to the list.  Once the item is in the list it won't be checked again (because it's an immutable list).\n\nFor example, this is a `Lst` that can't be empty and won't accept `null` items.\n```c#\n    var x = List<NonEmpty, NonNullItems<string>, string>(\"1\", \"2\", \"3\");\n```\nObviously declaring types like this gets quite bulky quite quickly.  So only using them for method arguments is definitely a good approach:\n```c#\n    public string Divify(Lst<NonEmpty, NonNullItems<string>, string> items) =>\n        String.Join(items.Map(x => $\"<div>{x}</div>\"));\n```\nThen `Divify` can be invoked thus:\n```c#\n    var res = Divify(List(\"1\", \"2\", \"3\")); \n\n    // \"<div>1</div><div>2</div><div>3</div>\"\n```\nBut as mentioned above, the implicit conversion from `Lst<string>` to `Lst<NonEmpty, NonNullItems<string>, string>` will run the `NonNullItems<string>` predicate for each item in the `Lst`.\n\nBuilt-in are some standard `Pred<ListInfo>` implementations:\n\n* `AnySize` - Always succeeds\n* `CountRange<MIN, MAX>` - Limits the `Count` to be >= MIN and <= MAX\n* `MaxCount<MAX>` - As above but with no lower bound\n* `NonEmpty` - List must have at least one item\n\nAnd by default there are lots of `Pred<A>` implementations.  See the `NewType` discussion later.\n\n### Seq<A>\n\nA new feature is the type [`Seq<A>`](https://github.com/louthy/language-ext/tree/master/LanguageExt.Core/DataTypes/Seq) which derives from [`ISeq<A>`](https://github.com/louthy/language-ext/blob/master/LanguageExt.Core/DataTypes/Seq/ISeq.cs), which in turn is an `IEnumerable<A>`.\n\nIt works very much like `cons` in functional languages (although not a real cons, as that's not a workable solution in C#).  It's a singly-linked list, with two key properties: `Head` which is the item at the head of the sequence, and `Tail` which is the rest of the sequence.  You can convert any existing collection type (as well as `IEnumerable` types) to a `Seq<A>` by calling the `Seq` constructor:\n```c#\n    var seq1 = Seq(List(1, 2, 3, 4, 5));    // Lst<A> -> Seq<A>\n    var seq2 = Seq(Arr(1, 2, 3, 4, 5));     // Arr<A> -> Seq<A>\n    var seq3 = Seq(new [] {1, 2, 3, 4, 5}); // A[] -> Seq<A>\n    ...    \n```\nAs well as construct them directly:\n```c#\n    var seq1 = Seq(1, 2, 3, 4, 5);\n\n    var seq2 = 1.Cons(2.Cons(3.Cons(4.Cons(5.Cons(Empty)))));\n```\nIn practice if you're using `Cons` you don't need to provide `Empty`:\n```c#\n    var seq = 1.Cons();   // Creates a sequence with one item in\n```\nThe primary benefits are:\n* Immutable\n* Thread-safe\n* Much lighter weight than using `Lst<A>` (although `Lst<A>` is very efficient, it is still an AVL tree behind the scenes)\n* Maintains the original type for `Lst<A>`, `Arr<A>`, and arrays.  So if you construct a `Seq` from one of those types, the `Seq` then gains extra powers for random lookups (`Skip`), and length queries (`Count`).\n* If you construct a `Seq` with an `IEnumerable` then it maintains its laziness, but also __guarantees that each item in the original `IEnumerable` is only ever enumerated once.__\n* Obviously easier to type `Seq` than `IEnumerable`!\n* `Count` works by default for all non-`IEnumerable` sources.  If you construct with an `IEnumerable` then `Count` will only cause a single evaluation of the underlying `IEnumerable` (and subsequent access to the seq for anything else doesn't cause additional evaluation)\n* Efficient pattern matching on the `Seq`, which again doesn't cause multiple evaluations of the underling collection.\n\n`Seq` has a bigger interface than `IEnumerable` which allows for various bespoke optimisations depending on the underlying collection; which is especially powerful for the LINQ operators like `Skip`, `Take`, `TakeWhile`, \n\n```c#\n    public interface ISeq<A> : \n        IEnumerable<A>, \n        IEquatable<ISeq<A>>, \n        IComparable<ISeq<A>>\n    {\n        /// <summary>\n        /// Head of the sequence\n        /// </summary>\n        A Head { get; }\n\n        /// <summary>\n        /// Head of the sequence\n        /// </summary>\n        Option<A> HeadOrNone();\n\n        /// <summary>\n        /// Tail of the sequence\n        /// </summary>\n        Seq<A> Tail { get; }\n\n        /// <summary>\n        /// True if this cons node is the Empty node\n        /// </summary>\n        bool IsEmpty { get; }\n\n        /// <summary>\n        /// Returns the number of items in the sequence\n        /// </summary>\n        /// <returns>Number of items in the sequence</returns>\n        int Count { get; }\n\n        /// <summary>\n        /// Match empty sequence, or multi-item sequence\n        /// </summary>\n        /// <typeparam name=\"B\">Return value type</typeparam>\n        /// <param name=\"Empty\">Match for an empty list</param>\n        /// <param name=\"Tail\">Match for a non-empty</param>\n        /// <returns>Result of match function invoked</returns>\n        B Match<B>(\n            Func<B> Empty,\n            Func<A, Seq<A>, B> Tail);\n\n        /// <summary>\n        /// Match empty sequence, or one item sequence, or multi-item sequence\n        /// </summary>\n        /// <typeparam name=\"B\">Return value type</typeparam>\n        /// <param name=\"Empty\">Match for an empty list</param>\n        /// <param name=\"Tail\">Match for a non-empty</param>\n        /// <returns>Result of match function invoked</returns>\n        B Match<B>(\n            Func<B> Empty,\n            Func<A, B> Head,\n            Func<A, Seq<A>, B> Tail);\n\n        /// <summary>\n        /// Match empty sequence, or multi-item sequence\n        /// </summary>\n        /// <typeparam name=\"B\">Return value type</typeparam>\n        /// <param name=\"Empty\">Match for an empty list</param>\n        /// <param name=\"Seq\">Match for a non-empty</param>\n        /// <returns>Result of match function invoked</returns>\n        B Match<B>(\n            Func<B> Empty,\n            Func<Seq<A>, B> Seq);\n\n        /// <summary>\n        /// Match empty sequence, or one item sequence, or multi-item sequence\n        /// </summary>\n        /// <typeparam name=\"B\">Return value type</typeparam>\n        /// <param name=\"Empty\">Match for an empty list</param>\n        /// <param name=\"Tail\">Match for a non-empty</param>\n        /// <returns>Result of match function invoked</returns>\n        B Match<B>(\n            Func<B> Empty,\n            Func<A, B> Head,\n            Func<Seq<A>, B> Tail);\n\n        /// <summary>\n        /// Map the sequence using the function provided\n        /// </summary>\n        /// <typeparam name=\"B\"></typeparam>\n        /// <param name=\"f\">Mapping function</param>\n        /// <returns>Mapped sequence</returns>\n        Seq<B> Map<B>(Func<A, B> f);\n\n        /// <summary>\n        /// Map the sequence using the function provided\n        /// </summary>\n        /// <typeparam name=\"B\"></typeparam>\n        /// <param name=\"f\">Mapping function</param>\n        /// <returns>Mapped sequence</returns>\n        Seq<B> Select<B>(Func<A, B> f);\n\n        /// <summary>\n        /// Filter the items in the sequence\n        /// </summary>\n        /// <param name=\"f\">Predicate to apply to the items</param>\n        /// <returns>Filtered sequence</returns>\n        Seq<A> Filter(Func<A, bool> f);\n\n        /// <summary>\n        /// Filter the items in the sequence\n        /// </summary>\n        /// <param name=\"f\">Predicate to apply to the items</param>\n        /// <returns>Filtered sequence</returns>\n        Seq<A> Where(Func<A, bool> f);\n\n        /// <summary>\n        /// Monadic bind (flatmap) of the sequence\n        /// </summary>\n        /// <typeparam name=\"B\">Bound return value type</typeparam>\n        /// <param name=\"f\">Bind function</param>\n        /// <returns>Flatmapped sequence</returns>\n        Seq<B> Bind<B>(Func<A, Seq<B>> f);\n\n        /// <summary>\n        /// Monadic bind (flatmap) of the sequence\n        /// </summary>\n        /// <typeparam name=\"B\">Bound return value type</typeparam>\n        /// <param name=\"bind\">Bind function</param>\n        /// <returns>Flatmapped sequence</returns>\n        Seq<C> SelectMany<B, C>(Func<A, Seq<B>> bind, Func<A, B, C> project);\n\n        /// <summary>\n        /// Fold the sequence from the first item to the last\n        /// </summary>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <param name=\"state\">Initial state</param>\n        /// <param name=\"f\">Fold function</param>\n        /// <returns>Aggregated state</returns>\n        S Fold<S>(S state, Func<S, A, S> f);\n\n        /// <summary>\n        /// Fold the sequence from the last item to the first\n        /// </summary>\n        /// <typeparam name=\"S\">State type</typeparam>\n        /// <param name=\"state\">Initial state</param>\n        /// <param name=\"f\">Fold function</param>\n        /// <returns>Aggregated state</returns>\n        S FoldBack<S>(S state, Func<S, A, S> f);\n\n        /// <summary>\n        /// Returns true if the supplied predicate returns true for any\n        /// item in the sequence.  False otherwise.\n        /// </summary>\n        /// <param name=\"f\">Predicate to apply</param>\n        /// <returns>True if the supplied predicate returns true for any\n        /// item in the sequence.  False otherwise.</returns>\n        bool Exists(Func<A, bool> f);\n\n        /// <summary>\n        /// Returns true if the supplied predicate returns true for all\n        /// items in the sequence.  False otherwise.  If there is an \n        /// empty sequence then true is returned.\n        /// </summary>\n        /// <param name=\"f\">Predicate to apply</param>\n        /// <returns>True if the supplied predicate returns true for all\n        /// items in the sequence.  False otherwise.  If there is an \n        /// empty sequence then true is returned.</returns>\n        bool ForAll(Func<A, bool> f);\n\n        /// <summary>\n        /// Skip count items\n        /// </summary>\n        Seq<A> Skip(int count);\n\n        /// <summary>\n        /// Take count items\n        /// </summary>\n        Seq<A> Take(int count);\n\n        /// <summary>\n        /// Iterate the sequence, yielding items if they match the predicate \n        /// provided, and stopping as soon as one doesn't\n        /// </summary>\n        /// <returns>A new sequence with the first items that match the \n        /// predicate</returns>\n        Seq<A> TakeWhile(Func<A, bool> pred);\n\n        /// <summary>\n        /// Iterate the sequence, yielding items if they match the predicate \n        /// provided, and stopping as soon as one doesn't.  An index value is \n        /// also provided to the predicate function.\n        /// </summary>\n        /// <returns>A new sequence with the first items that match the \n        /// predicate</returns>\n        Seq<A> TakeWhile(Func<A, int, bool> pred);\n    }\n```\n\n__Breaking changes__\n\n* Previously there were functions in the `Prelude` called `seq` which took many types and turned them into `IEnumerable<A>`.  Now they're constructing `Seq<A>` I have renamed them to `Seq` in line with other constructor functions.  \n* Where sensible in the rest of the API I have changed `AsEnumerable()` to return a `Seq<A>`.  This is for types which are unlikely to have large sequences (like `Option`, `Either`, `Try`, etc.);  You may find casting issues in those situations, but the types returned are obviously more useful, so it feels like a win.  Let me know if you have issues (All the major types have a `ToSeq()` method where appropriate, for convenience).\n* In `LanguageExt.Parsec` any parsers that previously returned `IEnumerable<A>` now return `Seq<A>`; I noticed when using the `Parsec` library extensively that I would often use `ToArray()` or `Freeze()` to force strict evaluation of a `IEnumerable` result.  Now you don't have to, but you may see some casting issues.\n* `Match` and `match` for `IEnumerable` previously allowed for matching up to six items in six separate lambdas.  They're now gone because I doubt anybody uses them, and they're slightly unwieldy.  Now they use `Seq` behind the scenes to remove any multiple evaluations during the matching process:\n```c#\n        static int Sum(Seq<int> seq) =>\n            seq.Match(\n                ()      => 0,\n                x       => x,\n                (x, xs) => x + Sum(xs));\n```\n\n### Non-nullable types: \n\nIn the ongoing quest to make it safer to write C# code, these types are all now structs and therefore can't be `null`:\n```c#\n    Stck<A>, \n    Que<A>, \n    Lst<A>, \n    Map<A, B>, \n    Map<Ord, A, B>, \n    HashMap<A, B>, \n    HashMap<Eq, A, B>, \n    Set<A>, \n    Set<Ord, A>\n    HashSet<A, B>, \n    HashSet<Eq, A, B>, \n    Que<A>, \n    Arr<A>\n```\nThis means you can create a member field and not initialise it and everything will 'just work':\n\n```c#\n    static class Test\n    {\n        public static Map<string, int> Foo;\n    }\n\n    Assert.True(Test.Foo == Map.empty<string, int>());\n    Assert.True(Test.Foo == default(Map<string, int>);\n```\n### Serialisation fixes\n\n`Map`, `Lst`, `Set`, `Option`, `Either`, etc.  All have serialisers that work with Json.NET (finally).  \n\nExamples: https://github.com/louthy/language-ext/blob/type-classes/LanguageExt.Tests/SerialisationTests.cs\n\n### Lazy `Option<A>` and `OptionUnsafe<A>`\n\n`Option<A>` and `OptionUnsafe<A>` have until now been strict types.  They can now support both strict and lazy behaviour in the same type.\n\nFor example:\n```c#\n    var option = from w in Some(_ => 5)\n                 from x in Some(_ => 10)\n                 from y in Some(_ => 15)\n                 from z in Some(_ => 20)\n                 select w + x + y + z;\n\n    // At this point the w + x + y + z expression hasn't run\n```\nAny function that returns a concrete non-Option type will force the expression to be evaluated:\n```c#\n    var result = option.IfNone(0);   // 50\n```\nThe result is memoised and therefore subsequent calls to `Match` or similar won't re-evaluate the expression.  The strict behaviour is unaltered:\n```c#\n    var option = from w in Some(5)\n                 from x in Some(10)\n                 from y in Some(15)\n                 from z in Some(20)\n                 select w + x + y + z;\n\n    // At this point the w + x + y + z expression *has* run\n```\nIf strict and lazy Options are combined, then the whole expression becomes lazy:\n```c#\n    var option = from w in Some(5)\n                 from x in Some(_ => 10)  // lazy expression\n                 from y in Some(15)\n                 from z in Some(20)\n                 select w + x + y + z;\n\n    // At this point the w + x + y + z expression hasn't run\n```\nNote if you want to write functions that return lazy options, then you will need to wrap them in `Optional` or `Some`:\n```c#\n    Option<int> LazyOptionFoo() => Optional(_ => ... );\n```\n\n> Either and EitherUnsafe will have lazy functionality soon\n\n### `NewType`\n\nNewType has gained an extra generic argument.  So this:\n\n```c#\n    class Metres : NewType<double> { ... }\n```\n\nBecomes:\n```c#\n    class Metres : NewType<Metres, double>  { ... } \n```\nThat makes lots of functionality more type-safe for `NewType` derived types.  For example monadic and functor operators like `Select`, `Map`, `Bind`, `SelectMany` can now return `Metres` rather than `NewType<double>`.  Which is very important for the integrity of the type.\n\nThere is a variant that takes an additional generic argument `PRED`.  Which is constrained to be a `struct` of `Pred<A>`.  This is called in the base constructor:\n```c#\n    if (!default(PRED).True(value)) \n        throw new ArgumentOutOfRangeException(nameof(value), value);\n```\nSo you should be able to see that this allows validation to be embedded into the type.  Here's an example from the new Process system client code:\n```c#\n    public class ClientConnectionId : NewType<ClientConnectionId, string, StrLen<I10, I100>>\n    {\n        public ClientConnectionId(string value) : base(value)\n        { }\n    }\n```\n`ClientConnectionId` is like a session token, and `StrLen<I10, I100>` means the string must be `10` to `100` chars long.  It is defined thus:\n```c#\n    public struct StrLen<NMin, NMax> : Pred<string>\n            where NMin : struct, Const<int>\n            where NMax : struct, Const<int>\n    {\n        [Pure]\n        public bool True(string value) =>\n            Range<int, TInt, NMin, NMax>.Is.True(value?.Length ?? 0);\n    }\n```\n`NMin` and `NMax` are constrained to be `Const<int>`, and from the example above are `I10` and `I100`.  They're defined as:\n```c#\n    public struct I10 : Const<int> { public int Value => 10; }\n    public struct I100 : Const<int> { public int Value => 100; }\n```\nYou can define your own `struct` type that derives from `Pred<A>` to provide any common validation primatives that you like.  And defined constants by deriving from `Const<A>`.\n\nThese are the built in predicate types:\n\n* `True<A>` - Always succeeds, no matter what's passed\n* `False<A>` - Always fails, no matter what's passed\n* `Equal<A, EQ, CONST>` - Value `A` must be equal to `CONST`.  `EQ` is a `Eq<A>` instance\n* `Exists<A, Term1, ..., Term5>` - `Term1 - Term5` are predicates.  The test passes if `A` is true when applied to any of the terms.\n* `ForAll<A, Term1, ..., Term5>` - `Term1 - Term5` are predicates.  The test passes if `A` is true when applied to all of the terms.\n* `GreaterThan<A, ORD, CONST>` - Value `A` must be greater than `CONST`.  `ORD` is an `Ord<A>` instance.\n* `GreaterOrEq<A, ORD, CONST>` - Value `A` must be greater than or equal to `CONST`.  `ORD` is an `Ord<A>` instance.\n* `LessThan<A, ORD, CONST>` - Value `A` must be less than `CONST`.  `ORD` is an `Ord<A>` instance.\n* `LessOrEq<A, ORD, CONST>` - Value `A` must be less than or equal to `CONST`.  `ORD` is an `Ord<A>` instance.\n* `Range<A, ORD, MIN, MAX>` - Value `A` must be in the range `MIN` to `MAX`.  `ORD` is an `Ord<A>` instance.\n\nConstants are in the `LanguageExt.ClassInstances.Const` namespace.  Integers are prefixed with `I`;  the most commonly used are already created: `0` to `256`, then powers of two and hundreds, thousands, etc.  `Double` constants are prefixed with `D`.  Only `D0`, `D1`, and `DNeg1` exist.  `Char` constants are `'A'- 'Z'`, `'a' - 'z'`, `'0' - '9'`, `ChSpace`, `ChTab`, `ChCR`, `ChLF`.\n\nBy embedding the validation into the type, there is no 'get out of jail free' cards where a loophole can be found in the type (or sub-type).  And it also becomes fundamentally a different type to (for example) `NewType<ClientConnectionId, string, StrLen<I0, I10>>` _(See the `<I0, I10>` at the end)_; so any function that wants to work with a client connection token must accept either `ClientConnectionId` or its base type of `NewType<ClientConnectionId, string, StrLen<I10, I100>>`.  It gives a small glimpse into the world of dependently typed languages, I think this is a pretty powerful concept for improving the safety of C# types in general (with no runtime costs), and takes the original `NewType` idea to the next level. \n\nThere is now an explicit cast operator.  So for the `Metres` example above:\n```c#\n    Metres m = Metres.New(100);\n    double x = (double)m * 2.0;\n```\n\n### `NumType`\n\nWith the new type-classes and class-instances (see later), it's now possible to write generic code for numeric-types.  And so I have created a variant of `NewType` called `NumType`.  Numeric types like `int` are the kind of types that are very commonly made into `NewType` derived types (along with `string`), but previously there wasn't a good story for doing arithmetic on those types.  Now with the `NumType` it is possible.  They work in exactly the same way as `NewTypes`, but you must specify a `Num<A>` class-instance (below it's `TDouble`):\n```c#\n    public class Metres : NumType<Metres, TDouble, double> { \n        public Metres(double x) : base(x) {}\n    }\n```\nThat gives you these extras over `NewType`:\n```c#\n    operator+\n    operator*\n    operator/\n    operator-\n    Product()\n    Divide()\n    Plus()\n    Subtract()\n    Abs()\n    Signum()\n    Min()\n    Max()\n    Sum()\n```\nAs with `NewType` you can also use a predicate:\n```c#\n    public class Age : NumType<Age, TInt, int, Range<int, TInt, I0, I120>> \n    { \n        public Age(int x) : base(x)  {}\n    }\n```\n### `FloatType`\nEven more specialised than `NumType` and `NewType` in that it only accepts class-instances from the type-class `Floating<A>`.  It adds functionality that are only useful with floating-point number types (along with the functionality from `NumType` and `NewType`):\n```\n Exp(), Sqrt(), Log(), Pow(A exp), LogBase(A y), Sin(), Cos(), Asin(), Acos(), Atan(), Sinh()\n Cosh(), Tanh(), Asinh(), Acosh(), Atanh()\n```\n\n### `ValueTuple` and `Tuple`\n\nA new feature of C# 7 is syntax for tuples.  Instead of:\n```c#\n    Tuple.Create(a, b)\n```\nYou can now:\n```c#\n    (a, b)\n```\nYou can also give them names:\n```c#\n    (K Key, V Value)\n```\nSo wherever in lang-ext tuples are used, they now accept `ValueTuple`.  `ValueTuple` is the `struct` version of `Tuple` that C# is using to back the new syntax.\n\nThis is particularly nice for `Map`:\n```c#\n    var map = Map(\n        (1, \"Paul\"), \n        (2, \"Steve\"), \n        (3, \"Stan\"), \n        (4, \"Tanzeel\"), \n        (5, \"Dan\"), \n        (6, \"Andreas\"));\n```\nAlso `Map` now derives from `IEnumerable<(K Key, V Value)>`.\n\nTuples look like they're going to be a lot more important in C# going forwards, so I have created extension methods and `Prelude` functions for `Tuple` and `ValueTuple` with up to 7 items.\n```c#\n    // Add an item to a tuple\n    var (a,b,c)   = (1, 2).Add(3);\n    var (a,b,c,d) = (1, 2).Add(3).Add(\"Hello\");\n```\nIf your tuple contains Semigroups (like `Lst` and `int` for example) then you can call `Append`:\n```c#\n    var (a, b) = append<TLst<int>, TInt, Lst<int>, int>(\n                    (List(1,2,3), 3),\n                    (List(4,5,6,7), 4));\n\n    // ([1,2,3,4,5,6,7], 7)\n```\nOr:\n```c#\n    var list = append<TLst<int>, Lst<int>>( (List(1,2,3), List(4,5,6,7)) );\n\n    // [1,2,3,4,5,6,7]\n```\n`Head` and `Tail`:\n```c#\n    var a  = (\"a\", 123, true).Head();   // \"a\"\n    var bc = (\"a\", 123, true).Tail();   // (123, true)\n```\n`Sum` and `Product`:\n```c#\n    var a = (100, 200, 300).Sum<TInt, int>();  // 600\n    var b = (10, 10, 10).Product<TInt, int>(); // 1000\n```\n`Contains`:\n```c#\n    var a = (1,2,3,4,5).Contains<EqInt, int>(3);  // true\n```\nMapping:\n```c#\n    x = x.Map( tuple => tuple );\n    \n    x = x.BiMap(a  => a * 2, b => b * 3);\n    x = x.TriMap(a  => a * 2, b => b * 3, c => c + \" add\");\n    x = x.QuadMap(a  => a * 2, b => b * 3, c => \"over\", d => \"ride\");\n    // etc.\n\n    x = x.MapFirst(a => a * 2);  // just maps the first item and leaves the rest alone\n    x = x.MapSecond(b => b * 3);  \n    x = x.MapThird(c => c + \" add\");\n    x = x.MapFourth(d => \"change\");  \n    // etc.\n\n    var (a, b) = (100, \"text\").MapFirst(x => x * 2); // (200, \"text\")\n```\nAlso:\n```c#\n    Iter, Fold, BiFold, BiFoldBack, TriFold, TriFoldBack, etc.\n```\n### `Cond<A>`\n\n`Cond` allows for building conditional expressions that can be used fluently.  It also seamlessly steps between synchronous and asynchronous behaviour without any need for ceremony.  \n\nHere's a simple example:\n```c#\nvar cond = Cond<int>(x => x == 4)\n               .Then(true)\n               .Else(false);\n```\nThat can be run like so:\n```c#\nbool result = cond(4); // True\nbool result = cond(0); // False\n```\nOr,\n```c#\nbool result = 4.Apply(cond); // True\nbool result = 0.Apply(cond); // False\n```\nHere's a slightly more complex  example:\n```c#\n    var vowels = Subj<char>().Map(Char.ToLower)\n                             .Any(x => x == 'a', x => x == 'e', x => x == 'i', x => x == 'o', x => x == 'u')\n                             .Then(\"Is a vowel\")\n                             .Else(\"Is a consonant\");\n\n    var x = vowels('a'); // \"Is a vowel\"\n```\nThis can then be tagged onto anything that returns a char or a `Task<char>`:\n```c#\n    var res = GetCharFromRemoteServer().Apply(vowels);   // Task<string>\n```\nSee the [pull request](https://github.com/louthy/language-ext/pull/179) for the discussion that led to this feature.  Thanks to [@ncthbrt](https://github.com/ncthbrt) for the suggestion and initial implementation.\n\n### Range\n\nContinuing the super generic theme, there is now a new `Range` type that can handle any type (as long as they have `Monoid` and `Ord` instances):\n\n```c#\n    public class Range<SELF, MonoidOrdA, A> : IEnumerable<A>\n        where SELF : Range<SELF, MonoidOrdA, A>\n        where MonoidOrdA : struct, Monoid<A>, Ord<A>, Arithmetic<A>\n    {\n        ...\n    }\n```\nAs with `NewType`, `FloatType`, and `NumType`, anything that derives from it should provide itself as the first generic argument.  This is the definition of `IntegerRange`:\n```c#\n    public class IntegerRange : Range<IntegerRange, TInt, int>\n    {\n        IntegerRange(int min, int max, int step) : base(min, max, step) { }\n    }\n```\nEverything else is handled in the base class, so it's trivial to add your own.  As before they implement `IEnumerable<A>`, and are lazy.  They now support `Overlaps(SELF range)` and `InRange(A x)`.  There are two constructor functions: `Range.FromMinMax(min, max, step)` and `Range.FromCount(min, count, step)`.  There are several provided implementations: `BigIntegerRange`, `CharRange`, `DecimalRange`, `DoubleRange`, `FloatRange`, `IntegerRange`, `LongRange`, `ShortRange`.\n\n#### `Try<A>` and `TryOption<A>`\n\n`Try` and `TryOption` (the lazy monads that catch exceptions) have been improved to memoise everything they do.  So once you run a `Try`, running the same reference again won't re-invoke the computation, it will just return the previously cached value.  This can be useful in LINQ expressions especially.  \n\n#### `TryAsync<A>`\n\nThere is a new monadic type called `TryAsync` which, as you may have guessed, is an asynchronous version of `Try`.  `Try` and `TryAsync` are delegate types that are invoked when you call extension methods like `Match` on them.  By default the `TryAsync` evaluation extension methods will wrap the invocation in a `Task` and will catch any exceptions thrown. \n```c#\n    TryAsync<int> LongRunningOp() => TryAsync(() => 10);\n\n    int x = await LongRunningOp().Match(\n                Succ: y  => y * 2,\n                Fail: ex => 0\n                );\n```\nUnfortunately you must wrap the operation in a `TryAsync(() => ...)` because the compiler can't infer the result-type like it can with `Try`.  However you can promote a `Try` to a `TryAsync`:\n```c#\n    Try<int> LongRunningOp() => () => 10;\n\n    int x = await LongRunningOp().ToAsync().Match(\n                Succ: y  => y * 2,\n                Fail: ex => 0\n                );\n```\nOr use any of the new `Async` extension methods added to `Try`:\n```c#\n    Try<int> LongRunningOp() => () => 10;\n\n    int x = await LongRunningOp().MatchAsync(\n                Succ: y  => y * 2,\n                Fail: ex => 0\n                );\n```\nEvery single method of `Try` now has an `Async` variant.  Also any method of `Try` or `TryAsync` that takes a `Func` (for example `Map(Try<A> x, Func<A, B> f)`), now has a variant that allows a `Task` to be returned instead.  For `Try` methods this will either promote the result to be a `TryAsync` (as is the case with `Map`), or a `Task` (as is the case with `Fold`).  This makes it trivial to deal with asynchronous results, as the `Try` or `TryAsync` will automatically perform the correct synchronisation required to extract a valid result.\n\nFor functions where operations could run in parallel then the type will again handle that automatically.  For example if you use the new `Applicative` functionality, this is possible:\n```c#\n// Placeholder functions.  Imagine they're doing some work to get some remote\n// data lists.\nTryAsync<Lst<int>> GetListOneFromRemote() => TryAsync(List(1, 2, 3));\nTryAsync<Lst<int>> GetListTwoFromRemote() => TryAsync(List(4, 5, 6));\n\n// Combines two lists and sorts them. \npublic static IEnumerable<int> CombineAndOrder(Lst<int> x, Lst<int> y) =>\n    from item in (x + y)\n    orderby item\n    select item;\n\n// Uses the fact that TryAsync is an applicative, and therefore has the \n// apply function available.  The apply function will run all three parts\n// of the applicative asynchronously, will handle errors from any term,\n// and will then apply them to the CombineAndOrder function.\npublic TryAsync<IEnumerable<int>> GetRemoteListsAndCombine() =>\n    apply(\n        CombineAndOrder,\n        GetListOneFromRemote(),\n        GetListTwoFromRemote());\n\n[Fact]\npublic async void ListCombineTest()\n{\n    var res = await GetRemoteListsAndCombine().IfFail(Enumerable.Empty<int>());\n\n    var arr = res.ToArray();\n\n    Assert.True(arr[0] == 1);\n    Assert.True(arr[1] == 2);\n    Assert.True(arr[2] == 3);\n    Assert.True(arr[3] == 4);\n    Assert.True(arr[4] == 5);\n    Assert.True(arr[5] == 6);\n}\n```\n\n#### `TryOptionAsync<A>`\n\nAs `Try` has got its `TryAsync` pairing, so has `TryOption` now got `TryOptionAsync`.  The interface is almost exactly the same as `TryAsync`.  Here are some quick examples:\n\n```c#\n    // Some example method prototypes\n    public TryOptionAsync<int> LongRunningAsyncTaskOp() => TryOptionAsync(10);\n    public Task<TryOption<int>> LongRunningAsyncOp()    => Task.FromResult(TryOption(10));\n    public TryOption<int> LongRunningOp()               => TryOption(10);\n    public Task<int> MapToTask(int x)                   => Task.FromResult(x * 2);\n    public int MapTo(int x)                             => x * 2;\n\n    public async void Test()\n    {\n        TryOptionAsync<int> j = LongRunningOp().ToAsync();\n        TryOptionAsync<int> k = LongRunningAsyncOp().ToAsync();\n\n        // These run synchronously\n        int a = LongRunningOp().IfNoneOrFail(0);\n        TryOption<int> b = LongRunningOp().Map(MapTo);\n\n        // These run asynchronously\n        int u = await LongRunningAsyncTaskOp().IfNoneOrFail(0);\n        int v = await LongRunningAsyncOp().IfNoneOrFail(0);\n        int x = await LongRunningOp().IfNoneOrFailAsync(0);\n        TryOptionAsync<int> y1 = LongRunningOp().MapAsync(MapTo);\n        TryOptionAsync<int> y2 = LongRunningOp().MapAsync(MapToTask);\n        int z1 = await y1.IfNoneOrFail(0);\n        int z2 = await y2.IfNoneOrFail(0);\n    }\n```\n\n### Ad-hoc polymorphism\n\nAd-hoc polymorphism has long been believed to not be possible in C#.  However with some cunning it is.  Ad-hoc polymorphism allows programmers to add traits to a type later.  For example in C# it would be amazing if we had an interface called `INumeric` for numeric types like `int`, `long`, `double`, etc.  The reason this doesn't exist is if you write a function like:\n```c#\n    INumeric Add(INumeric x, INumeric y) => x + y;\n```\nThen it would cause boxing.  Which is slow (well, slower).  I can only assume that's why it wasn't added by the BCL team.  Anyway, it's possible to create a numeric type, very much like a type-class in Haskell, and ad-hoc _instances_ of the numeric _type-class_ that allow for generic numeric operations without boxing.  \n\n> From now on I will call them type-classes and class-instances, or just instances.  This is not exactly the same as Haskell's type-classes.  If anything it's closer to Scala's implicits.  However to make it easier to discuss them I will steal from Haskell's lexicon.\n\n#### `Num<A>`\n\nSo for example, this is how to create a number type-class:\n```c#\n    public interface Num<A>\n    {\n        A Add(A x, A b);\n        A Subtract(A x, A b);\n        ...\n    }\n```\nNotice how there are two arguments to `Add` and `Subtract`.  Normally if I was going to implement this `interface` the left-hand-side of the `Add` and `Subtract` would be `this`.  I will implement the _ad-hoc_ class-instance to demonstrate why that is:\n```c#\n    public struct TInt : Num<int>\n    {\n        public int Add(int x, int b) => x + y;\n        public int Subtract(int x, int b) => x + y;\n        ...\n    }\n```\nSee how `TInt` is a `struct`?  Structs have a useful property in C# in that they can't be `null`.  So we can invoke the operations like so:\n```c#\n    int r = default(TInt).Add(10, 20);\n```\nThe important thing to note is that `default(TInt)` gets optimisied out in a release build, so there's no cost to the invocation of `Add`.  The `Add` and `Subtract` methods both take `int` and return `int`.  So therefore there's no boxing at all.\n\nIf we now implement `TFloat`:\n```c#\n    public struct TFloat : Num<float>\n    {\n        public float Add(float x, float b) => x + y;\n        public float Subtract(float x, float b) => x + y;\n        ...\n    }\n```\nThen we can see how a general function could be written to take any numeric type:\n```c#\n    public A DoubleIt<NumA, A>(A x) where NumA : struct, Num<A> =>\n        default(NumA).Add(x, x);\n```\nThe important bit is the `NumA` generic argument, and the constraint of `struct, Num<A>`.  That allows us to call `default(NumA)` to get the type-class instance and invoke `Add`.\n\nAnd so this can now be called by:\n```c#\n    int a    = DoubleIt<TInt, int>(5);        // 10\n    double b = DoubleIt<TFloat, float>(5.25); // 10.5\n```\nBy expanding the amount of operations that the `Num<A>` type-class can do, you can perform any numeric operation you like.  If you like you can add new numeric types (say for complex numbers, or whatever), where the rules of the type are kept in the _ad-hoc_ instance.\n\nLuckily you don't need to do that, because I have created the `Num<A>` type (in the `LanguageExt.TypeClasses` namespace), as well as `Floating<A>` (with all of the operations from `Math`; like `Sin`, `Cos`, `Exp`, etc.).  `Num<A>` also has a base-type of `Arithmetic<A>` which supports `Plus`, `Subtract`, `Product`, `Negate`.  This is for types which don't need the full spec of the `Num<A>` type.  I have also mapped all of the core numeric types to instances: `TInt`, `TShort`, `TLong`, `TFloat`, `TDouble`, `TDecimal`, `TBigInt`, etc.  So it's possible to write truly generic numeric code once.\n\n> There's no getting around the fact that providing the class-instance in the generic arguments list is annoying (and later you'll see how annoying).  The Roslyn team are looking into a type-classes like feature for a future version of C# (variously named: 'Concepts' or 'Shapes').  So this will I'm sure be rectified, and when it is, it will be implemented exactly as I am using them here.  \n> \n> Until then the pain of providing the generic arguments must continue.  You do however get a _super-powered C#_ in the mean-time.  \n> \n> The need to write this kind of super-generic code is rare; but when you need it, _you need it_ - and right now this is simply the most powerful way.\n\n#### `Eq<A>`\n\nNext up is `Eq<A>`.  Equality testing in C# is an absolute nightmare.  From the different semantics of `Eqauls` and `==`, to `IEqualityComparer`, and the enormous hack which is `EqualityComparer.Default` (which doesn't blow up at compile-time if your code is wrong).\n\nThe `Eq<A>` type-class looks like this:\n```c#\n    public interface Eq<A>\n    {\n        bool Equals(A x, A y);\n        int GetHashCode(A x);\n    }\n```\nThere are `Eq` prefixed instances for all common types (`EqInt`, `EqString`, `EqGuid` etc.), as well as for all of the types in this library (`EqLst`, `EqSet`, `EqTry`, etc).  All of the numeric types (`TInt`, `TDouble`, etc.) also implement `Eq<A>`.\n\nTo make it slightly prettier to use in code, you can use the `Prelude` `equals` function:\n```c#\n    bool x = equals<EqInt>(1, 1); // True\n```\nOr use `default` as shown before:\n```c#\n    bool x = default(EqInt).Equals(1, 1); // True\n```\nOne final way is:\n```c#\n    bool x = EqInt.Inst.Equals(1, 1);\n```\n`Inst` is defined on all of the instances in lang-ext, but it's not an 'official feature'.  Anybody could implement an ad-hoc implementation of `Eq<A>` and not provide an `Inst`. \n\nFor example you may call this directly:\n```c#\n    bool x = EqLst.Inst.Equals(List(1,2,3), List(1,2,3)); // true\n```\nBecause you may be concerned about calling:\n```c#\n    bool x = List(1,2,3) == List(1,2,3); // ?\n```\n... as all C# programmers are at some point, because we have no idea most of the time whether `==` does what we think it should.  \n\n> Just FYI `List(1,2,3) == List(1,2,3)` does work properly!  As do all types in language-ext.\n\nThere are two variants of the immutable `HashSet` in language-ext:\n```c#\n    HashSet<A>\n    HashSet<EqA, A> where EqA : struct, Eq<A>\n```\nWhat's interesting about the second one is that the equality _definition_ is baked into the type.  So this:\n```c#\n    HashSet<EqString, string> \n```\nIs not compatible with:\n```c#\n    HashSet<EqStringOrdinalIgnoreCase, string> \n```\nAnd if you think about that, it's right.  The strings that are used as keys in the `HashSet<EqString, string>` do not have the same properties as the strings in `HashSet<EqStringOrdinalIgnoreCase, string>`.  So even though they're both strings, they have different semantics (which cause wildly different behaviour for things like set intersection, unions, etc.)\n\nNow compare that to `HashSet<T>` in the BCL, or `ImmutableHashSet<T>` in `System.Collections.Immutable`, where two different sets with different `IEqualityComparer` types injected will cause undefined results when used together.\n\n> That's hopefully a small glimpse into the potential for improving type-safeness in C#.\n\n#### `Ord<A>`\n\n`Ord` is for ordering.  i.e. a `IComparable` replacement.  By the way, these names `Eq`, `Ord`, `Num`, are all lifted from Haskell.  I much prefer the short concise names that still convey meaning than the bulky and often clumsy names of the BCL.\n\nThis is `Ord<A>`, it derives from `Eq<A>`\n```c#\n    public interface Ord<A> : Eq<A>\n    {\n        int Compare(A x, A y);\n    }\n```\nUsage should be self-explanatory now, but the important thing to note here is that because 'type classes' are just interfaces, they can also have an inheritance hierarchy.\n\nThis is a slightly more complex example:\n```c#\n    public struct OrdArray<ORD, A> : Ord<A[]>\n        where ORD : struct, Ord<A>\n    {\n        public int Compare(A[] mx, A[] my)\n        {\n            if (ReferenceEquals(mx, my)) return 0;\n            if (ReferenceEquals(mx, null)) return -1;\n            if (ReferenceEquals(my, null)) return 1;\n\n            var cmp = mx.Length.CompareTo(my.Length);\n            if (cmp == 0)\n            {\n                for(var i = 0; i < mx.Length; i++)\n                {\n                    cmp = default(ORD).Compare(mx[i], my[i]);\n                    if (cmp != 0) return cmp;\n                }\n                return 0;\n            }\n            else\n            {\n                return cmp;\n            }\n        }\n\n        public bool Equals(A[] x, A[] y) =>\n            default(EqArray<ORD, A>).Equals(x, y);\n\n        public int GetHashCode(A[] x) =>\n            hash(x);\n    }\n```\nThe `OrdArray` which is an `Ord<A[]>`, does itself also take an `ORD` generic argument, which allows the contents of the array to be compared:\n```c#\n    int x = OrdArray<TInt, int>.Inst.Compare(Array(1,2), Array(1,2)); // 0\n```\n\n#### `Semigroup<A>`\n\nThis is where we start going a little more abstract.  Semigroups are a feature of category theory, which is soooo not important for this discussion.  They represent an associative binary operation, which can be invoked by calling `Append`.\n```c#\n    public interface Semigroup<A>\n    {\n        A Append(A x, A y);\n    }\n```\nPositive numbers (for example) form a semigroup.  I won't dwell on it too long, because although the `Append` function is super-useful, nearly everything that falls into the `Semigroup` category is also a `Monoid`...\n\n#### `Monoid<A>`\n\nA monoid has something that a semigroup doesn't, and that's the concept of identity (often meaning 'empty' or 'zero').  It looks like this:\n\n```c#\n    public interface Monoid<A> : Semigroup<A>\n    {\n        A Empty();\n    }\n```\nThis comes with some helper functions in `LanguageExt.TypeClass`:\n```c#\n    public static partial class TypeClass\n    {\n        public static A mempty<MONOID, A>() where MONOID : struct, Monoid<A> =>\n            default(MONOID).Empty();\n\n        public static A mconcat<MONOID, A>(IEnumerable<A> xs) where MONOID : struct, Monoid<A> =>\n            xs.Fold(mempty<MONOID, A>(), (s, x) => append<MONOID, A>(s, x));\n\n        public static A mconcat<MONOID, A>(params A[] xs) where MONOID : struct, Monoid<A> =>\n            xs.Fold(mempty<MONOID, A>(), (s, x) => append<MONOID, A>(s, x));\n    }\n```\nNow the semigroup `Append` comes to life.  Examples of monoids are: `TInt`, `MLst`, `TString`, etc.  i.e.\n```c#\n    var x = mconcat<TString, string>(\"Hello\", \" \", \"World\");   // \"Hello World\"\n    var y = mconcat<TLst<int>, Lst<int>>(List(1), List(2, 3)); // [1,2,3]\n    var z = mconcat<TInt, int>(1, 2, 3, 4, 5);                 // 15\n```\nThe `Empty()` function is what provides the _identity value_ for the concat operations.  So for `string` it's `\"\"`, for `Lst<T>` it's `[]` and for `int` it's `0`.  So a monoid is a semigroup with a _zero_.\n\nIt's surprising how much _stuff_ just starts working when you know your type is a monoid.  For example in language-ext version 1 there is a monadic type called `Writer<W, T>`.  The writer monad collects a _log_ as well as returning the bound value.  In version 1 the log had to be an `IEnumerable<W>`, which isn't super flexible.  In language-ext version 2 the type looks like this:\n\n```c#\n    public class Writer<MonoidW, W, A> where MonoidW : struct, Monoid<W>\n    {\n        ...\n    }\n```\nSo now it can be a running numeric total, or a `Lst<W>`, or a `Set<W>`, or whatever monoid _you_ dream up.  \n\n### Higher-kinds\n\nHigher-order polymorphism would allow us to define a type like so:\n```c#\n    public interface MyType<M<A>>\n    {\n        M<B> Foo<B>(M<A> ma);\n    }\n```\nWhere not only is the `A` parametric, but so it `M`.  So for example if I wanted to implement `MyType` for `Option<A>` I could do:\n```c#\n    public class MyOptionType<A> : MyType<Option<A>>\n    {\n        public Option<B> Foo<B>(Option<A> ma) => ...;\n    }\n```\nIt would be soooo nice if C# (well, the _immutable_ CLR) would support this.  But it doesn't.  So we need to find ways around it.  The way I am using for language-ext is:\n```c#\n    public interface MyType<MA, A>\n    {\n        MB Foo<MB, B>(MA ma);\n    }\n\n    public class MyOptionType<A> : MyType<Option<A>, A>\n    {\n        public MB Foo<MB, B>(Option<A> ma) => ...;\n    }\n```\n#### `Monad`\nThis is where some of the difficulties come in.  How do we return an `MB` if we don't know what it is?  This is a problem for the `Monad` type.  This is a simplified version:\n```c#\n    public interface Monad<MA, A>\n    {\n        MB Bind<MB, B>(MA ma, Func<B, MB> bind);\n        MA Return(A a);\n        MA Fail(Exception e = null);\n    }\n```\nLooking at the prototype for `Bind` it seems at first glance that the `bind` argument will give us the `MB` value we want.  But an `Option` might be in a `None` state, in which case it shouldn't run `bind`.\n```c#\n    public MB Bind<MB, B>(Option<A> ma, Func<A, MB> bind) =>\n        ma.IsSome\n            ? bind(ma.Value)\n            : ??? ; // What do we return here?\n```\nThe key is to use constraints.  But it also requires an extra generic paramter for `Bind`:\n```c#\n    public interface Monad<MA, A>\n    {\n        MB Bind<MonadB, MB, B>(MA ma, Func<B, MB> bind) \n            where MonadB : struct, Monad<MB, B>;\n\n        MA Return(A a);\n        MA Fail(Exception e = null);\n    }\n```\nSo we now know that `MonadB` is a class-instance of the `Monad<MB, B>` type-class.  So we can now do this:\n```c#\n    public MB Bind<MB, B>(Option<A> ma, Func<A, MB> f) \n        where MonadB : struct, Monad<MB, B> =>\n            ma.IsSome\n                ? f(ma.Value)\n                : default(MonadB).Fail();\n```\nThe eagle eyed reader will notice that this actually allows binding to any resulting monad (not just `Option<B>`).  I'm not an academic, but I'm sure there will be someone throwing their toys out of their prams at this point.  However, it works, it's type-safe, and it's efficient. \n\n[The actual definition of `Monad`](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt.TypeClasses/Monad_Env_Out_MA_A.htm) is more complex than this, in order to unify monadic types that take arguments (`Reader` and `State`) and monads that carry internal state (`Writer` and `State`), as well as to support asynchronous monads (`TryAsync` and `TryOption`).  I won't muddy the waters too much right now, but unified and type-safe they are.  There are no hacks.\n\nYou should see that the `Return` and `Fail` functions are trivial to implement:\n```c#\n    public Option<A> Return(A a) =>\n        Optional(a);\n\n    public Option<A> Fail(Exception e = null) =>\n        None;\n```\nWhat that means is that any function that has been constrained by a monad instance can create new instances of them:\n```c#\n    public M CreateNewIntegerMonad<MonadInt, M, int>(int x) \n        where MonadInt : struct, Monad<M, int> =>\n            default(MonadInt).Return(x);\n```\nThis is one of the key breakthroughs.  Imagine trying to create a `Monad` type the _old way_:\n```c#\n    public interface Monad<A>\n    {\n        Monad<B> Bind<B>(Func<A, Monad<B>> bind);\n    }\n\n    public class Option<A> : Monad<A>\n    {\n        public Monad<B> Bind<B>(Monad<A> ma, Func<A, Monad<B>> bind) =>\n            IsSome\n                ? bind(Value)\n                : None;\n    }\n\n    public Monad<int> CreateNewIntegerMonad(int x) =>\n        ????; // How?\n```\nMaybe we could parameterise it?\n```c#\n    public Monad<int> CreateNewIntegerMonad<M>(int x) where M : Monad<int> =>\n        ????; // We still can't call new M(x)\n```\nBut that doesn't work either because we still can't call `new M(x)`.  Being able to paramterise generic functions at the point where you know the concrete types (and therefore know the concrete class-instance) means that the generic functions can invoke the instance functions to create the concrete types.\n\nHere's a super generic example of a function that takes two monad arguments, they're both of the same type, and their bound values are `Num<A>`.\n```c#\n    public static MA Add<MonadA, MA, NumA, A>(MA ma, MA mb)\n        where MonadA  : struct, Monad<MA, A>\n        where NumA    : struct, Num<A> =>\n            default(MonadA).Bind<MonadA, MA, A>(ma, a =>\n            default(MonadA).Bind<MonadA, MA, A>(mb, b =>\n            default(MonadA).Return(default(NumA).Plus(a, b))));\n```\nYou may notice that the two `Bind` calls followed by the `Return` are basically a much less attractive version of this:\n```c#\n        from a in ma\n        from b in mb\n        select default(NumA).Plus(a, b);\n```\nAnd so I can now add two options:\n```c#\n    var x = Some(10);\n    var y = Some(20);\n    var z = Option<int>.None;\n\n    var r1 = Add<MOption<int>, Option<int>, TInt, int>(x, y); // Some(30)\n    var r2 = Add<MOption<int>, Option<int>, TInt, int>(x, z); // None\n\n    Assert.True(r1 == Some(30));\n    Assert.True(r2 == None);\n```\nOr two lists:\n```c#\n    var x = List(1, 2, 3);\n    var y = List(4, 5, 6);\n    var z = List<int>();\n\n    var r1 = Add<MLst<int>, Lst<int>, TInt, int>(x, y);\n    var r2 = Add<MLst<int>, Lst<int>, TInt, int>(x, z);\n\n    Assert.True(r1 == List(5, 6, 7,  6, 7, 8,  7, 8, 9));\n    Assert.True(r2 == z);\n```\nOr any two monads.  They will follow the built in rules for the type, and produce concrete values efficiently and without any boxing or dynamic casting. \n\n### Transformer types\n\nBecause using the super-generic stuff is hard, and most of the time not needed.  I have kept the transformer types, but they're now implemented in terms of the instance types.  There is a new [`MonadTrans`](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/MonadTrans_OuterMonad_OuterType_InnerMonad_InnerType_A.htm) type-class and a default instance called [`Trans`](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt/Trans_OuterMonad_OuterType_InnerMonad_InnerType_A.htm).\n\nFor every pair of nested monads: `Lst<Option<A>>`, `Try<Either<L, A>>`, etc.  there are the following extension methods (this is for `Arr<Lst<A>>`):\n```c#\nA SumT<NumA, A>(this Arr<Lst<A>> ma);\n\nint CountT<A>(this Arr<Lst<A>> ma);\n\nArr<Lst<B>> BindT<A, B>(this Arr<Lst<A>> ma, Func<A, Lst<B>> f);\n\nLst<Arr<B>> Traverse<A, B>(this Arr<Lst<A>> ma, Func<A, B> f);\n\nLst<Arr<A>> Sequence<A>(this Arr<Lst<A>> ma);\n\nArr<Lst<B>> MapT<A, B>(this Arr<Lst<A>> ma, Func<A, B> f);\n\nS FoldT<S, A>(this Arr<Lst<A>> ma, S state, Func<S, A, S> f);\n\nS FoldBackT<S, A>(this Arr<Lst<A>> ma, S state, Func<S, A, S> f);\n\nbool ExistsT<A>(this Arr<Lst<A>> ma, Func<A, bool> f);\n\nbool ForAllT<A>(this Arr<Lst<A>> ma, Func<A, bool> f);\n\nUnit IterT<A>(this Arr<Lst<A>> ma, Action<A> f);\n\nArr<Lst<A>> FilterT< A>(this Arr<Lst<A>> ma, Func<A, bool> pred);\n\nArr<Lst<A>> Where<A>(this Arr<Lst<A>> ma, Func<A, bool> pred);\n\nArr<Lst<A>> Select<A, B>(this Arr<Lst<A>> ma, Func<A, B> f);\n\nArr<Lst<C>> SelectMany<A, B, C>(\n        this Arr<Lst<A>> ma,\n        Func<A, Lst<B>> bind,\n        Func<A, B, C> project);\n\nArr<Lst<A>> PlusT<NUM, A>(this Arr<Lst<A>> x, Arr<Lst<A>> y) where NUM : struct, Num<A>;\n\nArr<Lst<A>> SubtractT<NUM, A>(this Arr<Lst<A>> x, Arr<Lst<A>> y) where NUM : struct, Num<A>;\n\nArr<Lst<A>> ProductT<NUM, A>(this Arr<Lst<A>> x, Arr<Lst<A>> y) where NUM : struct, Num<A> =>\n        ApplyT(default(NUM).Product, x, y);\n\nArr<Lst<A>> DivideT<NUM, A>(this Arr<Lst<A>> x, Arr<Lst<A>> y) where NUM : struct, Num<A>;\n\nAppendT<SEMI, A>(this Arr<Lst<A>> x, Arr<Lst<A>> y) where SEMI : struct, Semigroup<A>;\n\nint CompareT<ORD, A>(this Arr<Lst<A>> x, Arr<Lst<A>> y) where ORD : struct, Ord<A>;\n\nbool EqualsT<EQ, A>(this Arr<Lst<A>> x, Arr<Lst<A>> y) where EQ : struct, Eq<A>;\n\nArr<Lst<A>> ApplyT<A, B>(this Func<A, B> fab, Arr<Lst<A>> fa);\n\nArr<Lst<C>> ApplyT<A, B, C>(this Func<A, B, C> fabc, Arr<Lst<A>> fa, Arr<Lst<A>> fb);\n```\nThe number of functions has increased dramatically.  Some of the special ones are `Traverse` and `Sequence` which flips the inner and outer types.  So for example:\n```c#\n    Lst<Option<int>> x = List(Some(1), Some(2), Some(3), Some(4), Some(5));\n    Option<Lst<int>> y = x.Sequence();\n\n    Assert.True(y == Some(List(1, 2, 3, 4, 5)));\n```\nAs you can see, the list is now inside the option.\n```c#\n    Lst<Option<int>> x = List(Some(1), Some(2), Some(3), None, Some(5));\n    Option<Lst<int>> y = x.Sequence();\n\n    Assert.True(y == None);\n```\nIn this case there is a `None` in the `Lst` so when the `Lst<Option<>>` becomes a `Option<Lst<>>` the rules of the `Option` take over, and one `None` means all `None`.\n\nThis can be quite useful for `Either`:\n```c#\n    var x = List<Either<string, int>>(1, 2, 3, 4, \"error\");\n\n    var y = x.Sequence();\n\n    Assert.True(y.IsLeft && y == \"error\");\n```\nThis collects the first error it finds, or returns `Right` if there is no error. \n\n`Traverse` is the same as `Sequence` except it applies a mapping function to each bound value as it's transforming the types.  Here's an example that runs 6 tasks in parallel, and collects their results:\n\n```c#\n    var start = DateTime.UtcNow;\n\n    var f1 = Task.Run(() => { Thread.Sleep(3000); return 1; });\n    var f2 = Task.Run(() => { Thread.Sleep(3000); return 2; });\n    var f3 = Task.Run(() => { Thread.Sleep(3000); return 3; });\n    var f4 = Task.Run(() => { Thread.Sleep(3000); return 4; });\n    var f5 = Task.Run(() => { Thread.Sleep(3000); return 5; });\n    var f6 = Task.Run(() => { Thread.Sleep(3000); return 6; });\n\n    var res = await List(f1, f2, f3, f4, f5, f6).Traverse(x => x * 2);\n\n    Assert.True(toSet(res) == Set(2, 4, 6, 8, 10, 12));\n\n    var ms = (int)(DateTime.UtcNow - start).TotalMilliseconds;\n    Assert.True(ms < 3500, $\"Took {ms} ticks\");\n```\nSo there is a List of Tasks that becomes a single awaitable Task of List.\n\nAs well as the extensions, there are also static classes for the transformer types.  There is one for each type of monad.  So for example, `Option` has a `LanguageExt.OptionT` type.  Whenever you have a pair of nested monads, and `Option` is the inner monad, then you would use `OptionT`:\n```c#\n    var ma = List(Some(1),Some(2),Some(3),Some(4),Some(5));\n\n    var total = OptionT.foldT(ma, 0, (s, x) => s + x); // 15\n    var total = OptionT.sumT<TInt, int>(ma); // 15\n    var mb    = OptionT.filterT(ma, x > 3); // List(Some(3), Some(4))\n```\n\nI could go on endlessly about the new types.  There are so many.  But for the release notes I think I should wrap it up.  It's worth taking a look at the API documentation for the [type-classes](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt.TypeClasses/index.htm) and the [instances](https://louthy.github.io/language-ext/LanguageExt.Core/LanguageExt.ClassInstances/index.htm)\n\n### IL.Ctor\n\nAlthough this doesn't really fit with the core message of the library, it is something used internally in the project, and because it's super useful, I've decided to make it `public` rather than `private`.  There are 4 functions for building a `Func<...,R>` which invokes the constructor for a type.  \n```c#\n    var ticks = new DateTime(2017, 1, 1).Ticks;\n\n    // Builds a delegate to call new DateTime(long);\n    var ctor = IL.Ctor<long, DateTime>();\n\n    DateTime res = ctor(ticks);\n\n    Assert.True(res.Ticks == ticks);\n```\nThe generated delegate doesn't use reflection, IL is emitted directly.  So invocation is as fast as calling `new DateTime(ticks)`.  The four `Ctor` functions are for up to four arguments.\n\nThe `NewType` system uses it to build a fast strongly-typed factory function:\n```c#\n    public abstract class NewType<NEWTYPE, A, PRED> :\n        IEquatable<NEWTYPE>,\n        IComparable<NEWTYPE>\n        where PRED    : struct, Pred<A>\n        where NEWTYPE : NewType<NEWTYPE, A, PRED>\n    {\n        protected readonly A Value;\n\n        /// <summary>\n        /// Constructor function\n        /// </summary>\n        public static readonly Func<A, NEWTYPE> New = IL.Ctor<A, NEWTYPE>();\n\n        ...\n    }\n```\nAs you can see, it would be impossible to call `new NEWTYPE(x)` from the `NewType` base-class.\n\nSo for example:\n```c#\n   class Metres : NewType<Metres, float> \n   { \n       public Metres(float x) : base(x) {} \n   }\n\n   var ms = Metres.New(100);\n```\n\n"
  },
  {
    "path": "Major Version Release Notes/Version 2/version-2-migration-notes.md",
    "content": "### language-ext migration notes\n\n> `error CS0305: Using the generic type 'NewType<NEWTYPE, A>' requires 2 type arguments`\n\n`NewType` and the new `NumType` and `FloatType` now have an additional generic argument.  So if you defined your `NewType` in `v1` as this: \n```c#\n    public class Metres : NewType<int>\n    {\n        public Metres(int x) : base(x)\n        {}\n    }\n```\nThen you should add an extra generic argument to the inherited `NewType`:\n```c#\n    public class Metres : NewType<Metres, int>\n    {\n        public Metres(int x) : base(x)\n        {}\n    }\n```\nThis allows the sub-type to be used in the base-type's methods (like `Select`, `Map`, `Where`, etc.) so that they can return `Metres` rather than `NewType<int>`.\n\n> `The type 'ValueTuple<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.ValueTuple,`\n\nThere is new C# language support for tuples (\"like\", \"so\").  Language-Ext adds loads of extension methods to make them even more useful.  However the underlying typle `System.ValueTuple` must be added to your projects from nu-get.\n\n> `error CS0305: Using the generic type 'Trans<OuterMonad, OuterType, InnerMonad, InnerType, A>' requires 5 type arguments`\n\nThe namespace `LanguageExt.Trans` is now deprecated.  Remove any usings.\n\n> `error CS1750: A value of type '<null>' cannot be used as a default parameter because there are no standard conversions to type `\n\nMany types have become structs (like `Map`, `Lst`, etc).  So if you see this error remove the ` = null`.  If you need to assign anything to remove the warnings then either use `default`, or the built-in empty constructors.  e.g.\n```c#\n    Map<string, int> xs = Map<string, int>();        // If you're using static LanguageExt.Prelude\n    Map<string, int> xs = Map.empty<string, int>();\n    Map<string, int> xs = default(Map<string, int>);\n```\n\n> `'Prelude.Map<K, V>(Tuple<K, V>, params Tuple<K, V>[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.`\n\nThe constructor functions for `Map`, `Set`, `List`, etc. have all been standardised.  If you previously passed an `IEnumerable<...>` to any one of them, then you'll now need to either call `TYPE.createRange(...)` on the type, or `toTYPE(...)`.  For example:\n```c#\n    IEnumerable<(int, string)> xs = new [] { (1, \"A\"), (2, \"B\"), (1, \"C\") };\n\n    var m1 = toMap(xs);\n    var m2 = Map.createRange(xs);\n```\n\n> `error CS0104: 'HashSet<>' is an ambiguous reference between 'System.Collections.Generic.HashSet<T>' and 'LanguageExt.HashSet<A>'`\n\n`HSet` has been renamed, because it's a terrible name.  And so having a reference to `System.Collections.Generic` and `LanguageExt` in the same code file will cause ambiguities that the linker can't resolve.\n\nRemove one of the usings, and then use aliases for the type you want.  i.e.\n\n```c#\n    using G = System.Collections.Generic;\n\n    var hs = new G.HashSet<int>();\n```\n\n> `error CS0122: 'NewType<SELF, A, PRED>.Value' is inaccessible due to its protection level`\n\nPreviously the `Value` property was public.  If you want to make it public you should now opt-in by exposing the `protected`  `Value` property.  Alternatives are to use an explicit cast to the bound value type to get at the `Value`, or use `Map(x => ...)`\n"
  },
  {
    "path": "Major Version Release Notes/Version 5/Migration War Stories/README.md",
    "content": "# Migration from V4 to V5 notes\n\n## Migrating `EffectsExamples` from the `Samples` folder\n\n### `Menu.cs`\n\n* Removed: `struct` constraint\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasFile<RT>` constraint to `Has<Eff<RT>, FileIO>`\n* Changed: `HasTextRead<RT>` constraint to `Has<Eff<RT>, TextReadIO>`\n* Changed: `HasTime<RT>` constraint to `Has<Eff<RT>, TimeIO>`\n* Changed: `HasConsole<RT>` constraint to `Has<Eff<RT>, ConsoleIO>`\n* Search and replace: `Aff<RT, ` with `Eff<RT, ` \n* Search and replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n* Replace: `.Sequence` with `.Traverse` (and put `.As()` a the end)\n* Added: `.As()` to the end of the first `from` in `clearConsole`\n* Changed: `ToAff()` to `ToEff()`\n* Added: `.As()` to the end of the first `from` in `logError`\n* Changed: `Time<RT>` to `Time<Eff<RT>, RT>`\n* Added: `using static LanguageExt.UnitsOfMeasure;`\n* Added: `.As()` to the end of the first `from` in `showComplete`\n* Changed: `Seq(...)` to `[...]`\n\n### `CancelExample.cs`\n\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasConsole<RT>` constraint to `Has<Eff<RT>, ConsoleIO>`\n* Search and replace: `Aff<RT, ` with `Eff<RT, ` \n* Search and replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n* Changed: `k.Key == ConsoleKey.Enter ? cancel<RT>() : unitEff` to `k.Key == ConsoleKey.Enter ? cancel : unitIO`\n\n### `ErrorAndGuardExample.cs`\n\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasConsole` to `Has<Eff<RT>, ConsoleIO>`\n* Search and replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n* Added: `using static LanguageExt.UnitsOfMeasure;`\n* Replace: `@catch` with `@catchM` when catching Effs (and changed predicate to use `ex.Is<SystemException>()`)\n\n### `FoldTest.cs`\n\n* Removed: `struct` constraint\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasConsole` to `Has<Eff<RT>, ConsoleIO>`\n* Search and replace: `Aff<RT, ` with `Eff<RT, ` \n* Removed: `ToAff()` from guard, not needed any more\n* Changed: `Effect<RT, Unit>` to `Effect<Eff<RT>, Unit>`\n* Added: `.As()` to the end of the first `RunEffect()`\n\n### `ForkCancelExample.cs`\n\n* Search and replace: `Aff<RT, ` with `Eff<RT, ` \n* Removed: `struct` constraint\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasConsole<RT>` constraint to `Has<Eff<RT>, ConsoleIO>`\n* Changed: `HasTime<RT>` constraint to `Has<Eff<RT>, TimeIO>`\n* Added: `using static LanguageExt.UnitsOfMeasure;`\n* Search and replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n* Change: `fork` now returns `ForkIO`, so update to use `ForkIO.Cancel`\n\n\n### `QueueExample.cs`\n\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasConsole` to `Has<Eff<RT>, ConsoleIO>`\n* Replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n* Changed: `EnqueueEff` with `EnqueueM` and appended `.As()`\n* Changed: `Queue<RT, *>` to `Queue<Eff<RT>, *>`\n* Changed: `Consumer<RT, *, *>` to `Consumer<*, Eff<RT>, *>`\n* Changed: `Pipe<RT, *, *, *>` to `Pipe<*, *, Eff<RT>, *>`\n* Changed: `Producer<RT, *, *>` to `Producer<*, Eff<RT>, *>`\n* Changed: `FailEff<Unit>(Errors.Cancelled)` with `Fail(Errors.Cancelled)`\n* Added: `.As()` to `fork`\n\n### `RetryExample.cs`\n\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasConsole` to `Has<Eff<RT>, ConsoleIO>`\n* Replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n\n### `TextFileChunkStreamExample.cs`\n\n* Removed: `struct` constraint\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasConsole` to `Has<Eff<RT>, ConsoleIO>`\n* Changed: `HasFile<RT>` to `Has<Eff<RT>, FileIO>`\n* Changed: `HasTextRead<RT>` to `Has<Eff<RT>, TextReadIO>`\n* Replace: `Aff<RT, ` with `Eff<RT, ` \n* Replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n* Changed: `Consumer<RT, *, *>` to `Consumer<*, Eff<RT>, *>`\n* Changed: `Pipe<RT, *, *, *>` to `Pipe<*, *, Eff<RT>, *>`\n* Changed: `Effect<RT, *>` to `Effect<Eff<RT>, *>`\n\n### `TextFileLineStreamExample.cs`\n\n* Removed: `struct` constraint\n* Removed: `HasCancel<RT>` constraint \n* Changed: `HasConsole` to `Has<Eff<RT>, ConsoleIO>`\n* Changed: `HasFile<RT>` to `Has<Eff<RT>, FileIO>`\n* Changed: `HasTextRead<RT>` to `Has<Eff<RT>, TextReadIO>`\n* Replace: `Aff<RT, ` with `Eff<RT, ` \n* Replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n* Changed: `Consumer<RT, *, *>` to `Consumer<*, Eff<RT>, *>`\n* Changed: `Pipe<RT, *, *, *>` to `Pipe<*, *, Eff<RT>, *>`\n* Changed: `Effect<RT, *>` to `Effect<Eff<RT>, *>`\n\n### `TimeExample.cs`\n\n* Added: `using static LanguageExt.UnitsOfMeasure;`\n* Removed: `struct` constraint\n* Removed: `HasCancel<RT>` constraint \n* Replace: `HasConsole<RT>` constraint to `Has<Eff<RT>, ConsoleIO>`\n* Replace: `HasTime<RT>` constraint to `Has<Eff<RT>, TimeIO>`\n* Replace: `Time<RT>.now` to `Time<Eff<RT>, RT>.now`\n* Replace: `Console<RT>` with `Console<Eff<RT>, RT>`\n\n### `TimeoutExample.cs`\n\n* Added: `using static LanguageExt.UnitsOfMeasure;`\n* Removed: `struct` constraint\n* Removed: `HasCancel<RT>` constraint \n* Replace: `HasConsole<RT>` constraint to `Has<Eff<RT>, ConsoleIO>`\n* Replace: `HasTime<RT>` constraint to `Has<Eff<RT>, TimeIO>`\n* Replace: `Aff<RT, ` with `Eff<RT, ` \n\n\n## Migrating `LanguageExt.Sys` from the `Samples` folder\n\nThen changed:\n```c#\nuse(startActivity(name, activityKind, activityTags, activityLinks, startTime),\n\tact => localEff<RT, RT, TA>(rt => rt.SetActivity(act.Activity), operation));\n```\nto:\n```c#\nfrom a in startActivity(name, activityKind, activityTags, activityLinks, startTime)\nfrom r in localEff<RT, RT, TA>(rt => rt.WithActivity(a), operation)\nselect r;\n```\n\n3. Changed `Aff` to `Eff`\n\n4. Deleted duplicate methods (due to `Aff` being renamed to `Eff`)\n\n5. Changed `Eff<RT, ...>(rt => ...` to `lift((RT rt) => ...`\n\n6. Changed `cancelToken<RT>()` to `cancelToken` \n\n7. Changed `Producer<RT, OUT, A>` to `Producer<OUT, Eff.R<RT>, A>`\n"
  },
  {
    "path": "Major Version Release Notes/Version 5/README.md",
    "content": "# Version 5.0.0 Major Release Notes\n\n**_WORK IN PROGRESS NOTES_**\n\nVersion 5 of language-ext is huge.  It is both massive in terms of new capabilities delivered but also in _breaking changes_ that will require you to spend some time fixing up compilation failures and making judgements about your code.  An upgrade to `v5` should be considered a significant undertaking for a large code-base - please make sure you have the time before upgrading.  \nI have made copious notes below to help you understand the changes and to ease the migration.  If, during the migration you encounter issues that are not in these notes, please let me know so I can update them for everybody else.  \n\nFurther contextual information about the updates can be [found on my blog](https://paullouth.com/higher-kinds-in-c-with-language-ext/) -- it digs a little deeper into the new capabilities and hopefully explains why these changes are necessary.\n\nLanguage-ext is 10 years old this year, so please consider this my _once per decade refresh_.  It is very much my .NET Framework to .NET Core moment.\n\n\n# Contents\n\n* [Motivations](#motivations)\n\t* [Empower the users](#empower-the-users)\n\t* [Wage war on `async` (green threads)](#wage-war-on-async-green-threads)\n\t* [Leverage modern C# features](#leverage-modern-c-features)\n* [New Features](#new-features)\n\t* [Higher-kinded polymorphism](#higher-kinded-polymorphism)\n\t\t* [Introduction](#introduction)\n\t\t* [Traits](#traits)\n\t\t* [Functor]()\n\t\t* [Applicative]()\n\t\t* [Monad]()\n\t\t* [Foldable]()\n        * [Fallible]()\n\t\t* [Traversable]()\n        * [SemigroupK]()\n\t\t* [MonoidK]()\n\t\t* [SemiAlternative]()\n\t\t* [Alternative]()\n\t\t* [Free monads]()\n \t* [IO monad]()\n       * [Auto-resource managment]() (`use` / `release`)\n\t* [Streaming effects]()\n    * [Monad transformers (MonadT)]()\n      * [OptionT]()\n\t  * [EitherT]()\n\t  * [FinT]()\n\t  * [ValidationT]()\n      * [Reader and ReaderT]()\n      * [Writer and WriterT]()\n      * [State and StateT]()\n      * [StreamT]()\n\t* [All computation based monads rewritten to use transformers]()\n\t* [Infinite recursion in monads]()\n\t* [`Pure` / `Fail` monads]()\n\t* [Lifting]()\n\t* [Improved guards]()\n\t* [Nullable annotations]()\n\t* [Collection initialisers]()\n* [Breaking changes](#breaking-changes)\n\t* [netstandard2.0 no longer supported](#netstandard20-no-longer-supported)\n\t* [`Seq1` made `[Obsolete]`](#seq1-made-obsolete)\n\t* ['Trait' types now use static interface methods](#trait-types-now-use-static-interface-methods)\n\t* [The 'higher-kind' trait types have all been refactored](#the-higher-kind-trait-types-have-all-been-refactored)\n\t* [The `Semigroup<A>` and `Monoid<A>` types have been refactored](#the-semigroupa-and-monoida-types-have-been-refactored)\n\t* [The static `TypeClass` class has been renamed `Trait`](#the-static-typeclass-class-has-been-renamed-trait)\n\t* [`Apply` extensions that use raw `Func` removed](#apply-extensions-that-use-raw-func-removed)\n\t* [Manually written `Sequence` extension methods have been removed (#1)](#manually-written-sequence-extension-methods-have-been-removed-1)\n\t* [Manually written `Sequence` extension methods have been removed (#2)](#manually-written-sequence-extension-methods-have-been-removed-2)\n\t* [Manually written `Sequence` extension methods have been removed (#3)](#manually-written-traverse-extension-methods-have-been-removed-3)\n\t* [`ToComparer` doesn't exist on the `Ord<A>` trait any more](#tocomparer-doesnt-exist-on-the-orda-trait-any-more)\n\t* [Renamed `LanguageExt.ClassInstances.Sum`](#renamed-languageextclassinstancessum)\n\t* [`Guard<E>` has become `Guard<E, A>`](#guarde-has-become-guarde-a)\n\t* [Existing uses of `HasCancel<RT>` should be replaced with `HasIO<RT>`](#existing-uses-of-hascancelrt-should-be-replaced-with-hasiort)\n\t* [`UnitsOfMeasaure` namespace converted to a static class](#unitsofmeasaure-namespace-converted-to-a-static-class)\n\t* [`Either` doesn't support `IEnumerable<EitherData>` any more](#either-doesnt-support-ienumerableeitherdata-any-more)\n\t* [`Either` 'bi' functions have their arguments flipped](#either-bi-functions-have-their-arguments-flipped)\n\t* [Nullable (struct) extensions removed](#nullable-struct-extensions-removed)\n\t* [Support for `Tuple` and `KeyValuePair` removed](#support-for-tuple-and-keyvaluepair-removed)\n\t* [Types removed outright](#types-removed-outright)\n\t\t* [`Some<A>`](#somea)\n\t\t* [`OptionNone`](#optionnone)\n\t\t* [`EitherUnsafe<L, R>`](#eitherunsafel-r)\n\t\t* [`EitherLeft<L>`](#eitherleftl)\n\t\t* [`EitherRight<L>`](#eitherrightl)\n\t\t* [`Try<A>`](#trya)\n\t\t* [`TryOption<A>`](#tryoptiona)\n\t\t* [`TryAsync<A>`](#tryasynca)\n\t\t* [`TryOptionAsync<A>`](#tryoptionasynca)\n\t\t* [`Result<A>`](#resulta)\n\t\t* [`OptionalResult<A>`](#optionalresulta)\n\t\t* [Async extensions for `Option<A>`](#async-extensions-for-optiona)\n\t\t* [`ExceptionMatch`, `ExceptionMatchAsync`, `ExceptionMatchOptionalAsync`](#exceptionmatch-exceptionmatchasync-exceptionmatchoptionalasync)\n        * [`NewType`, `NumType`, `FloatType`]()\n\t* [Libraries removed outright](#libraries-removed-outright)\n\t\t* [`LanguageExt.SysX`](#languageextsysx)\n\t\t* [`LanguageExt.CodeGen`](#languageextcodegen)\t\n\t\t* [`LanguageExt.Transformers`](#languageexttransformers)\t\n\n# Motivations\n\n* Empower the users\n* Wage war on async (green threads)\n* Support for transducers\n* Once per decade refresh\n\n## Empower the users\n\nIf you spend any time with Haskell or other languages with higher-kinds, you'll notice a heavy use of higher-kinded polymorphism.  From functors, applicatives, monads, foldables, traversables, monad transformers, etc.  This flavour of polymorphism allows for compositional superpowers that we can only dream of in C#.\n\n_Composition of pure functional components_ always leads to new, more capable components, that are also **automatically** pure.  This is the true power of pure functional composition; unlike OO composition that just collects potential complexity, pure functional composition abstracts away from it.  You can trust the composition to be sound.\n\nMuch of this library up until this point has been trying to give you the capability to build these compositions.  It's been achieved so far by lots of typing by me and lots of code-gen.  For example, the `LanguageExt.Transformers` library was a code-genned mass of source-code that combined every monadic type with every other monadic type so that you can work on them nested.  It was 200,000 lines of generated code - and was getting exponentially worse.\n\nI've also written 100s (maybe 1000s) of `Select` and `SelectMany` implementations that give you the impression that C# has generalised monads.  But it doesn't, it's just a lot of typing.  If you create your own monadic type it won't magically work with any existing language-ext types and you can't write general functions that accept any monad and have it just work.\n\n> And that is very much because C# doesn't support higher-kinded polymorphism.\n\nThat means that you pretty much only get to use what I provide.  That's not acceptable to me.  I want to empower everybody to be able to leverage pure functional composition in the same way that can be done in Haskell (and other languages that have higher-kinds).  A series of articles on higher-kinds [features on on my blog](https://paullouth.com/higher-kinds-in-c-with-language-ext/).\n\n## Wage war on `async` (green threads)\n\nIf I continued the way I was before then every monadic type would have an `*Async` variant, as would every method and function.  This was getting out of hand.  For something like an IO/effect monad where you could also have an optional error-type and optional runtime-type that meant 8 types.  Each with 1000s of lines of code to define them.  Then, when you think there's 20 or so 30 or so monadic types, it becomes a big maintenence problem.  There's also issues around consistency between each type (making sure everything has a `MapAsync`, `BindAsync`, etc.) - as well as making sure sync types can work with async types, etc.\n\nSo, as of now, this library stands against 'declarative async' - i.e. we are  adopting a _'green threads mentality'_.  That is we will not be giving you `*Async` variants of anything.  All IO computation types (`IO` and `Eff`) will support the _lifting_ of both synchronous and asynchronous functions, but you won't see evidence of asynchronicity in any type-signatures.\n\nThose types each have a `Run()` function which _appear_ to run synchronously, i.e. they don't return a `Task<A>`.  In fact, they don't run synchronously, they run _concurrently_.  Internally, they use similar mechanics to `Task` to yield time to your current thread whilst waiting for their own IO operations to complete.  So, calling `operation.Run()` is the same as calling `await operation.RunAsync()` - you just don't need the rest of your code infected by `async`.\n\nWhen you want an operation not to run concurrently, but in parallel instead (i.e. queue the work to be run on the next available `ThreadPool` thread), you can call `operation.Fork()`.  It supports fire-and-forget, so `operation.Fork().Run()` returns immediately, or you can await the result:\n```c#\nvar forkedOperation = from f in operation.Fork() // runs in parallel\n                      from r in f.Await\t\t     // use the ForkIO to await the result\n                      select r;\n\n// This will yield the current thread to allow concurrency, whilst the forked\n// operation runs on another thread.\nvar result = forkedOperation.Run();\n```\nTo lift an existing `Task` based function into these types you can just call:\n\n* `liftIO(Func<EnvIO, Task<A>> function)`\n* `liftIO(Func<Task<A>> function)`\n\nWhich are both in the `Prelude` and allow an `IO` operation to be lifted into any monad that supports IO.  `EnvIO` gives you access to the `CancellationToken`, `CancellationTokenSource`, and `SynchronizationConrext`.  \n\nFor example:\n\n```c#\nvar operation = from text in liftIO(env => File.ReadAllTextAsync(path, env.Token))\n                let lines = text.Split(\"\\r\\n\").ToSeq()\n                select lines;\n```\nWe can then run that operation:\n```c#\nSeq<string> result = operation.Run();\n```\nAnd we get a concrete `Seq<string>` - not a `Task<Seq<string>>`, but the operation ran concurrently.\n\n\n## Leverage modern C# features\n\nThe library has been held back by the need to support .NET Framework.  As of now this library is .NET (formerly known as .NET Core) only.  Instantly jumping to .NET 8.0 (which has Long Term Support).\n\nThis opens up: static interface members (which allows the trait/ad-hoc polymorphism support to get a power-up) and collection initialisers for all of the immutable collections - amongst others.\n\n\n# New Features\n\n## Higher-kinded polymorphism\n\n### Introduction\nSo, what is higher-kinded polymorphism?  Think of a function like this:\n\n```c#\nstatic Option<int> AddOne(Option<int> mx) =>\n\tmx.Map(x => x + 1);\n```\nThat's a function that takes an `Option` and leverages its `Map` function to add one to the value inside.  The `Map` function makes it a 'Functor'.  Functors map.  \n\nBut, if functors map, and all functors have a `Map` method, why can't I write:\n```c#\nstatic F<int> AddOne<F>(F<int> mx) where F : Functor =>\n\tmx.Map(x => x + 1);\n```\nIt's because we can only make the *lower-kind* polymorphic.  For example, I can write a function like this:\n```c#\nstatic Option<string> Show(Option<A> mx) =>\n\tmx.Map(x => x.ToString());\n```\nWhere the lower-kind, the `A`, is parametric - but not the _higher-kind_ (the `F` in the previous example).\n\nYou might think we could just do this with interfaces:\n\n```c#\n\ninterface Functor<A>\n{\n    Functor<B> Map<B>(Func<A, B> f);\n}\n\npublic class Option<A> : Functor<A>\n{\n    // ...    \n}\npublic class Seq<A> : Functor<A>\n{\n    // ...    \n}\n\n```\nOn the surface, that looks like we can then just accept `Functor<A>` and call map on it.  The problem is that we really shouldn't mix and match different types of functor (same with monads, applicatives, etc).  We've lost the information on what's inside the functor.  Every time we call `Map` on `Option` it stops being an `Option`, so we can't then call `Bind`, or any other useful functions, we're stuck doing `Map` forever.\n\n## Traits\n\nC# has recently [introduced static interface members](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/static-virtual-interface-members).  It allows us to create ['trait types'](https://en.wikipedia.org/wiki/Trait_%28computer_programming%29).  Users of language-ext know this approach from the TypeClasses and ClassInstances technique.  But, with static interface methods the approach has become much more elegant and usable.  \n\n> language-ext is now .NET 8 only - mostly to leverage static interface methods\n\nSo, now what we can do is define a really simple type:\n\n```c#\npublic interface K<F, A>\n```\nThis one type will change your life!\n\nRemember, we could't create a higher-kinded type like `F<A>`, but we can create this: `K<F, A>`.  It has no members, it's a completely empty interface, we simply use this as a 'marker' for our types so that they can leverage higher-kinded polymorphism.  If you look at any of the major types in language-ext `v5` you'll see the `K` type being used (`K` is short for 'Kind'):\n\nThis is `Option<A>`:\n```c#\npublic readonly struct Option<A> :\n    K<Option, A>\n{\n    ...\n}\n```\nIt locks its `F` type to be `Option` (notice the lack of an `A`, it's just `Option`).\n\nIf you then go and look at `Option`, you'll notice it inherits some really interesting interfaces!\n\n```c#\npublic class Option : \n\tMonad<Option>, \n\tTraversable<Option>, \n\tAlternative<Option>\n{\n\t// ...\n}\n```\n* `Monad` inherits `Applicative` and `Functor`\n* `Traversable` inherits `Functor` and `Foldable`\n\nAnd, if you and look at those interfaces you'll see the static interface methods that all leverage the `K` kind-type:\n\n```c#\npublic interface Functor<F>  \n    where F : Functor<F>\n{\n    public static abstract K<F, B> Map<A, B>(Func<A, B> f, K<F, A> ma);\n}\n```\n\nNow, let's look at the Haskell defintion of `Functor`:\n\n```haskell\nclass Functor f where\n    fmap :: (a -> b) -> f a -> f b\n```\n\nNotice how the type is parameterised by `f` (just like `Functor<F>`), and how it takes a higher-kinded value of `f a`, which is the same as our `K<F, A>`, and it returns a higher-kinded value of `f b`, which is our `K<F, B>`.\n\n> We have the same defintion as Haskell.  Exactly the same!\n\nWhat does this mean?  Well, we can now write generic functions that work with functors, applicatives, monads, monad-transformers, traversables, alternatives, foldables, state monads, reader monads, writer monads...\n\nHere's the example from before:\n\n```c#\npublic static K<F, int> AddOne<F>(K<F, int> mx) where F : Functor<F> =>\n\tF.Map(x => x + 1, mx);\n```\nIt calls the **static** `Map` function on the `F` trait, which is implemented by each type.  Here's the implementation for `Option`\n\n```c#\npublic class Option :\n\tMonad<Option>, \n\tTraversable<Option>, \n\tAlternative<Option>\n{\n\t// ...\n\n\tpublic static K<Option, B> Map<A, B>(Func<A, B> f, K<Option, A> ma) => \n\t    ma.As().Map(f);\n\n\t// ...\n\n}\n```\nRemember, `Option<A>` inherits from `K<Option, A>`, so we can just downcast it and call the `Option<A>` implementation of `Map`.  The `As()` method does the downcast from `K<Option, A>` to `Option<A>`.\n\n> You may think downcasting is a bit risky here, but really nothing else should inherit from `K<Option, A>`.  Doing so only makes sense for `Option<A>`.  I think the risk of a casting issue is close to zero.\n\nSo, just to be clear.  Every type, like `Option<A>`, `Seq<A>`, `Eff<A>`, etc. has a sibling type of the same name with the last generic parameter removed. So, `Option<A>` has a sibling type of `Option`, `Seq<A>` has `Seq`, etc.  Those sibling types implement the traits, like `Monad<M>`, `Functor<F>`, etc.  And, because `Option<A>`, `Seq<A>`, etc. all inherit from `K<TRAIT, A>` - where `TRAIT` is `Option`, `Seq`, `Eff`; this allows generic functions that have constriants like `where F : Functor<F>` to 'find' the bespoke implementation.\n\n> Types like `Either<L, R>`, that have multiple generic arguments, again just lose the last argument for their sibling type: `Either<L>`.\n\nInvoking the trait functions directly isn't that elegant - although perfectly usable - so there's extension methods that work with all of the abstract traits.  Here's the above `AddOne` method rewritten to use the `Map` extension instead:\n\n```c#\npublic static K<F, int> AddOne<F>(K<F, int> mx) where F : Functor<F> =>\n\tmx.Map(x => x + 1);\n```\n\nSo, let's try it out by calling it with a number of functors:\n\n```c#\nK<Option, int> mx = AddOne(Option<int>.Some(10));\nK<Seq, int>    my = AddOne(Seq<int>(1, 2, 3, 4));\nK<Fin, int>    mz = AddOne(Fin<int>.Succ(123));\n```\nNote, the return types have the 'trait' baked in.  So you know it's still an option, seq, fin, etc.  \n\n> Without full support for higher-kinds (from the C# language team) we can't do better than that.  \n\nHowever, there are extensions to help get back to the original type.  Just call: `As()`.\n\n```c#\nOption<int> mx = AddOne(Option<int>.Some(10)).As();\nSeq<int>    my = AddOne(Seq<int>(1, 2, 3, 4)).As();\nFin<int>    mz = AddOne(Fin<int>.Succ(123)).As();\n```\nYou only need to do that when you 'realise the concrete type'.  Because the trait (`Option`, `Seq`, `Fin`, etc.) is the type that inherits `Monad`, `Applicative`, `Traversable`, etc. (not `Option<A>`, `Seq<A>`, `Fin<A>`, ) - you can just call their capabilities directly off the `K` value:\n\n```c#\nOption<int> mx = AddOne(Option<int>.Some(10))\n                     .Bind(x => Option<int>.Some(x + 10))\n                     .Map(x => x + 20)\n                     .As();\n\nSeq<int> mx = AddOne(Seq<int>(1, 2, 3, 4))\n                  .Bind(x => Seq(x + 10))\n                  .Map(x => x + 20)\n                  .As();\n\n```\n\n\nJust this capability alone has alowed me [to delete nearly 200,000 lines of generated code](https://github.com/louthy/language-ext/commit/c4c9df3b3b2fd9f0eaf0850742ce309948eea0d7).  That is incredible!\n\n\n************ CONTINUE HERE ***************\n\n\n\n\n\n### Leverage modern C# features\n\nThe library has been held back by the need to support .NET Framework.  As of now this library is .NET (formally known as .NET Core) only.  Instantly jumping to .NET 8.0 (which has Long Term Support).\n\nThis opens up: static interface members (which allows the trait/ad-hoc polymorphism support to get a power-up) and collection initialisers for all of the immutable collections - amongst others.\n\n\n## New Features\n\n- IO monads\n\t- Two new IO effect monads that have parametric errors\n- Transducers\n\t- All computation based monads rewritten to use transducers\n- Infinite recursion in monads\n- Streaming effects\n\t- By calling `many(stream)` in any monad or monad-transformer expression you instantly turn the monad into a stream.\n\t- Supported streams: `IAsyncEnumerable`, `IEnumerable`, `IObservable`\n- Auto-resource managment (`use` / `release`)\n- `Pure` / `Fail` monads\n\t- Allow easy lifting of pure and failure monadic values (a bit like `None`)\n- Lifting\n\t- Allow easy lifting of synchronous functions and asynchronous into computation based monads.\n- Improved guards\n- Nullable annotations\n\t- Everywhere!\n- Collection initialisers\n\t- `Seq<int> xs = [1, 2, 3]` FTW!.\n- Monad transformers\n\t- Yes, for real: stackable, aliasable, monad-transformers!\n\n## Breaking changes\n\n### `netstandard2.0` no longer supported\n\nVersion 5 of language-ext jumps straight to `net8.0` support.\n\n**Motivation**\n\nI held off for as long as I could, but there are lots of new C# features that this library can make use of (primarily static interfaces, but others too like collection initialisers); so it's time to leave .NET Framework behind and focus on .NET [Core].  \n\n**Impact**\n\nHigh (if you're still on .NET Framework)\n\n**Mitigation** \n\nMigrate your application to .NET Core\n\n\n### `Seq1` made `[Obsolete]`\n\nA [previous attempt](https://github.com/louthy/language-ext/releases/tag/v4.0.2) to remove `Seq1` was paused due to [potential migration issues](https://github.com/louthy/language-ext/discussions/931).  \n\n**Motivation**\n\nThe plan to remove the `Seq1` singleton `Seq` constructor was announced a few years ago.  I've taken this opportunity to make it obsolete as we now have collection initialisers and the previous reasons for the delay in making `Seq1` obsolete have subsided (a 3 year window should be enough!).  \n\n**Impact**\n\nLow\n\n**Mitigation** \n\nUse `[x]` or `Seq.singleton(x)`\n\n### `Error` no longer implicitly convertable from `String`\n\nIt seemed like a good idea at the time, but can easily cause problems with `Error` carrying types like `Fin` (`Fin<string>` in particular).  To avoid the confusion I have made it an `explicit` conversion operation.\n\n**Impact**\n\nLow\n\n**Mitigation** \n\nManually cast to `Error` where needed - or call `Error.New(string)`\n\n### 'Trait' types now use static interface methods\n\nBefore static interface methods existed, the technique was to rely on the non-nullable nature of structs to get access to 'static' methods (via interface based constraints), by calling `default(TRAIT_TYPE).StaticMethod()`.\n\nLanguage-ext has many of these 'trait types', like `Eq<A>`, `HasCancel<A>`, etc.  They have all been updated to use `static abstract` methods.\n\n**Motivation**\n\nSo, where before you might call: `default(EqA).Equals(x, y)` (where `EqA` is `struct, Eq<A>`) - you now need to call `EqA.Equals(x, y)` (where `EqA` is `Eq<A>`) .  \n\nThis is obviously much more elegant and removes the need for the `struct` constraint.\n\n**Impact**\n\nMedium - your code will throw up lots of 'Cannot access static method' errors.  It is a fairly mechanical processes to fix them up.  \n\n**Mitigation** \n\nIf you have implemented any of these traits, as instances, then you'll need to implement these changes:\n\n* Remove the `struct` from any constraints (`where X : struct`)\n* Add `static` to trait method implementations\n* Any default `Inst` usages should be removed\n* The types can still be implemented as structs, so that doesn't need to change, but they can now be implemented with any instance type.\n\n### The 'higher-kind' trait types have all been refactored\n\nThe following types have all bee rewritten: `Monad`, `Functor`, `Applicative`, `Alternative`, `Foldable`, etc.\n\n**Motivation**\n\nThe new static interfaces have opened up a more effective approach to higher-kinds in C#.  Instead of doing as much as possible to retain the original types in methods like `Bind`, `Map`, `Apply`, etc. we now expect all types that need to leverage `Monad`, `Functor`, etc. to inherit `K<M, A>`.  \n\nFor example, `Option<A>` inherits `K<Option, A>`, `Seq<A>` inehrits `K<Seq, A>`, `Either<L, R>` inherits `K<Either<L>, R>`.  The `M` in `K<M, A>` is the trait implementation.  So, `Option` (no generic argument) would inherit `Monad<Option>`, `Traversable<Option>`, etc.  \n\nThise truly opens up higher-order generic programming in C#.  \n\n*** TODO: Insert a link here to a tutorial on higher-kinds in C# ***\n\n**Impact**\n\nHigh, if you have built your own `Monad`, `Functor`, `Applicative` implementations; or you have been writing code that leverages the generic nature of the traits.  However, I doubt this impact will be large because the previous approach was cumbersome - hence the refactor.\n\n**Mitigation** \n\nThis is rewrite territory.  I would encourage you to look at the new traits and monad transformers - as they're much more effective.\n\n### Renaming of methods in Arithmetic trait\n\nArithmetic trait: `Plus` renamed `Add`, `Product` renamed `Multiply`.\n\n### The `Semigroup<A>` and `Monoid<A>` types have been refactored\n\nThe `Append` in `Semigroup<A>` (which `Monoid<A>` inherits) is now an instance method.  Meaning you must derive your semigroup and monoidal types from `Monoid<YOUR_TYPE>` to leverage its capabilities.\n\nThe functions in the `TypeClass` static class have been moved to: `Monoid` and `Semigroup` static _module_ classes.  `TypeClass.mappend` is now `Semigroup.append`, `TypeClass.mconcat` is now `Monoid.concat`, etc.\n\nSemigroup also defines `operator+` now.\n\n**Motivation**\n\nMonoids, like the other trait types, were set up work ad-hoc polymorphically.  That is, we could build a `Monoid` instance for a type that we don't own.  And, although we have now lost that capability, we have gained a much easier experience for working with monoidal types.\n\nFor example, `Validation<MonoidFail, Fail, Success>` is now just `Validation<Fail, Success>`.  Previously, you'd have to specify the `MonoidFail` trait all the time because there was no way for C# to infer it.  I suspect most people use the `Validation<Fail, Success>` variant with its built-in `Seq` of `Fail` results.  Now it's just as easy to use any monoid.\n\nThis obviously means that, with types that you don't own, they can't be monoidal directly.  \n\nHowever, you can always wrap existing types with monoidal container:\n```c#\npublic readonly record struct MEnumerable<A>(IEnumerable<A> Items) : \n    Monoid<MEnumerable<A>>\n{\n    public MEnumerable<A> Append(MEnumerable<A> rhs) =>\n        new(Items.Concat(rhs.Items));\n\n    public static MEnumerable<A> Empty =>\n        new(Enumerable.Empty<A>());\n}\n```\nThis lifts an existing type into a monoid that you can then use with generic functions that expect a monoid.  I think that although this is a little bit awkward, it's the scenario that happens then least; most of the time we have control over the type we want to be monoidal and so we can just inherit `Monoid<YOUR_TYPE>`.\n\n**Impact**\n\nMedium - I'm not expecting mass adoption of the previous traits system, so it probably will have a low impact for most.  However, monoids were probably one of the easier traits to use.\n\n**Mitigation**\n\nAny implementations of `Monoid<YOUR_TYPE>` that you have, take the implementation and move the members into `YOUR_TYPE` and `Append` into a non-static method that takes a single argument rather than two (`this` is your first argument now).\n\n### The static `TypeClass` class has been renamed `Trait`\n\n`LanguageExt.TypeClass` is effectively a Prelude for the trait functions, this has been renamed to `LanguageExt.Trait`.\n\n\n**Motivation**\n\nThe name type-class comes from Haskell, which has been a massive influence on this library, however, I think the word 'trait' is more descriptive than 'type class', which is potentially a bit confusing to the average C# developer.\n\n**Impact**\n\nLow\n\n**Mitigation** \n\nSearch and replace `TypeClass` for `Trait`.\n\n### `Apply` extensions that use raw `Func` removed\n\n**Motivation**\n\nThe applicative-functor `Apply` function is supposed to work on lifted functions (i.e. `M<Func<A, B>>` not the raw `Func<A, B>`).  I orignally provided variants that work with the raw `Func` for convenience, but really they're just `Map` by another name.\n\n**Impact**\n\nMedium\n\n**Mitigation** \n\nThe new `Functor` trait gives all functor types a new variant of `Map` which takes the `Func` as the first argument and the functor value as the second (this differs from the existing handwritten `Map` methods which take `this` as the first argument and a `Func` as the second argument).  That, along with new extension methods for `Func<A, ..., J>` have been added that curry the `Func` and then applies the map function.\n\nSo, instead of:\n\n```c#\nFunc<string, string, string> surround = \n\t(str, before, after) => $\"{before} {str} {after}\";\n\nvar mx = Some(\"Paul\");\nvar my = Some(\"Mr.\");\nvar mz = Some(\"Louth\");\n\nsurround.Apply(mx).Apply(my).Apply(mz);\n```\n\nChange the first `Apply` to `Map`:\n\n```c#\nsurround.Map(mx).Apply(my).Apply(mz);\n```\n\nThose of you that have used Haskell will recognise that pattern, as it's commonly used:\n\n```haskell\nsurround <$> mx <*> my <*> mz\n```\n\n### Manually written `Sequence` extension methods have been removed (#1)\n\nThe `Sequence` methods that follow this pattern have been removed:\n\n```c#\npublic static Fin<Lst<B>> Sequence<A, B>(this Lst<A> ta, Func<A, Fin<B>> f) => ...\n```\n\n**Motivation**\n\nBefore being able to formulate the higher-kinds I had to manually write six `Sequence` methods and `Traverse` for every pair of monadic types.  There are 450 of them in total.  As you can imagine that's a real pain to develop and maintain.  \n\nThe other issue is that `Sequence` and `Traverse` don't work for monadic types that you build.  You have to write those extension methods yourself for every pair.  This is hardly approachable.\n\nThere is a new trait type called `Traversable` that generalises traversals. The completely generic functions are available via:\n\n```c#\n    Traversable.traverse(...)\n    Traversable.sequence(...)\n    Traversable.sequenceA(...)\n    Traversable.mapM(...)\n```\nThey will work with *any* pair of traversble and applicatives.\n\nI have also added a `Traverse` method to every traversable type (`Seq`, `Option`, etc.) and those will work with *any* applicative.  Which means if you build your own monads/applicative-functors that have implementations that derive from `Monad<M>` and/or `Applicative<F>` then they will automatically work with the language-ext traversable types.\n\nI have named the new version `Traverse` because that's really what it should have been called in the first place.  So, as this is a big breaking changes release, I decided to bite the bullet and rename it.\n\n**Impact**\n\nHigh: `Sequence` is likely to be used a lot because it's so useful.  Renaming it to `Traverse` will instantly cause your build to fail.  The new version also returns a lifted value that you may need to convert.\n\n**Mitigation**\n\nWhere your build fails due to `Sequence` you should change `Sequence` to `Traverse` and follow the call with `.As()` to lower the generic type:\n\nBefore:\n```c#\n\tvar results = Seq(1,2,3).Sequence(x => x % 2 == 0 : Some(x) : None);\n```\n\nAfter:\n```c#\n\tvar results = Seq(1,2,3).Traverse(x => x % 2 == 0 : Some(x) : None).As();\n```\n\n### Manually written `Sequence` extension methods have been removed (#2)\n\nThe `Sequence` methods that follow this pattern have been removed:\n\n```c#\npublic static Option<Seq<A>> Sequence<A>(this Seq<Option<A>> ta) => ...\n```\n\n**Motivation**\n\nThe motivations are the same as for the other removal of `Sequence`.  By removing it we get to use the generalised version which allows others to build monadic types that be composed with the language-ext types and be traversed.\n\nThe difference with this removal and the last one is that there is no equivalent `Sequence` method added to the monadic types (like `Option`, `Seq`, etc.);  The reason for this is that it's not possible for C# to pick up the nested generics correctly, so it's a waste of time writing them.  \n\nYou can still call `Traversable.sequence` and `Traversable.sequenceA` to do this manually, however it's much easier to call `ma.Traverse(identity)` which is isomorphic.\n\n**Mitigation**\n\nBefore:\n```c#\nvar results = Seq(Some(1), Some(2), None).Sequence();\n```\n\nAfter:\n```c#\nvar results = Seq(Some(1), Some(2), None).Traverse(identity).As();\n```\nIt's not quite as concise obviously, but it is completely generic and extensible which the previous one wasn't.  You can also build your own extension methods for commonly used pairs of monads:\n\n```c#\npublic static Option<Seq<A>> Sequence<A>(this Seq<Option<A>> mx) =>\n    mx.Traverse(identity).As();\n```\nThat will restore the previous functionality.\n\n### Manually written `Traverse` extension methods have been removed (#3)\n\nThe `Traverse` methods that follow this pattern have been removed:\n\n```c#\npublic static Seq<Fin<B>> Traverse<A, B>(this Fin<Seq<A>> ma, Func<A, B> f) => ...\n```\n\n**Motivation**\n\nThe motivations are the same as for the other removals of `Sequence`.  By removing it we get to use the generalised version which allows others to build monadic types that be composed with the language-ext types and be traversed.\n\nAgain, there will be no replacement for this as you can just use a combination of `Sequence` and `Map` to achieve the same goals.\n\n**Mitigation**\n\nBefore:\n```c#\nvar results = Seq(Some(1), Some(2), None).Traverse(x => x * 2);\n```\n\nAfter:\n```c#\nvar results = Seq(Some(1), Some(2), None).Sequence().Map(x => x * 2).As();\n```\nAgain, it's not quite as concise, but it is completely generic and extensible which the previous one wasn't.  You can also build your own extension methods for commonly used pairs of monads:\n\n```c#\npublic static Option<Seq<B>> Traverse<A, B>(this Seq<Option<A>> mx, Func<A, B> f) =>\n    mx.Sequence().Map(f).As();\n```\nThat will restore the previous functionality.\n\n\n### `ToComparer` doesn't exist on the `Ord<A>` trait any more\n\n**Motivation**\n\nBecause the trait types now use `static` methods, we can't now have a `ToComparer()` extension for the `Ord<A>` type.  Instead there's a class called `OrdComparer` that contains a singleton `IComparer` property called `Default`.\n\n**Impact**\n\nLow\n\n**Mitigation** \n\nUse `OrdComparer<OrdA, A>.Default` instead of `<OrdA>.ToComparer()`.\n\n\n### Renamed `LanguageExt.ClassInstances.Sum`\n\nRenamed to `LanguageExt.ClassInstances.Addition<SUM, A>`\n\n**Mitigation** \n\nThere's a new type called `Sum<L, R>` for use with transducers.  \n\n**Impact**\n\nLow\n\n**Mitigation** \n\nRename uses of `Sum<NUM, A>` to `Addition<NUM, A>`\n\n\n###  `Guard<E>` has become `Guard<E, A>`\n\nThe `A` is never used, this just allows guards to work in LINQ by enabling the implementation of `SelectMany`.  The benefit is that a number of guards can be placed together in a LINQ statement, where only one could before.\n\n* Impact: Zero unless you've written your own code to work with `Guard`.  If you only ever used the `guard` Prelude function this will have no impact.\n\n### Existing uses of `HasCancel<RT>` should be replaced with `HasIO<RT>`\n\nThe basic runtime traits needed by the effect monads (`IO`, `Eff`, and `Aff`) has been expanded to `HasCancel<RT>`, `HasFromError<RT, E>`, and `HasSyncContext<RT>`.  These can all be applied manually or you can use the `HasIO<RT, E>` trait which wraps all three traits into a single trait.\n\nSimply search and replace: `HasCancel<RT>` for `HasIO<RT, Error>`.  This will work for all existing `Eff` and `Aff` code.  \n\n* `HasSyncContext<RT>` allows all `IO` and `Eff` monads to use the `post(effect)` function.  This allows the running of an effect on original `SynchronizationContext` (needed for WPF and Windows Form applications).\n* `HasFromErrror<RT, E>` allows conversion of `Error` to `E`.  The new `IO` monads have an parametric error type - and so this allows for exceptional errors and expecteded `Error` values to be converted to the parametric error type: `E`.\n\n### `UnitsOfMeasaure` namespace converted to a static class\n\nThe various utilty fields used for units (`seconds`, `cm`, `kg`, etc.) have been moved out of the `LanguageExt.Prelude` and into `LanguageExt.UnitsOfMeasure` static class.  The unit types (`Length`, `Mass`, etc.) are now all in the `LanguageExt` namespace.\n\n* Impact: Low\n* Mitigation: \n\t* All usages of `using LanguageExt.UnitsOfMeasure` should be converted to `using static LanguageExt.UnitsOfMeasure`\n\t* Any uses of the unit-fields will also need `using static LanguageExt.UnitsOfMeasure` either globally or in each `cs` file.\n\n### `Either` doesn't support `IEnumerable<EitherData>` any more\n\nThis is part of preparing the library for future serialisation improvements.\n\n* Impact: Low\n* Mitigation:\n\t* If you used the feature for serialisation, build your own handler for whatever serialisation library you use.\n\t* If you use it in LINQ expressions, write your own extension method to convert the `Either` to an `IEnumerable` that supports \n\n## `Either` 'bi' functions have their arguments flipped\n\nThere were lots of methods like `BiMap`, `BiBind`, `BiFold` etc. where `Left` and `Right` were in the wrong order in the method argument list.  So, I have flipped them.\n\n* Impact: Low\n* Mitigation: change the argument order of any usages\n\n## Nullable (struct) extensions removed\n\nThese just keep causing problems with resolution of common functions like `Map`, `Bind`, etc.\n\nThe nullable Prelude remains.\n\n## Support for `Tuple` and `KeyValuePair` removed\n\nValueTuple support only from now on.\n\n\n## Types removed outright\n\nOriginally, I was going to just mark these as `[Obsolete]`.  And, for a while, they were.  But after over 1000 files changed with over 100,000 lines of code added or modified, I realised that maintaining these types (updating them to support nullable references and other fixups) was potentially doubling the effort I'd done up to that point.  So, I have just deleted them outright.  It is brutal, but it saved my sanity.\n\nI am very, very, very sorry that this will mean you have to fixup everything before you can work with language-ext `v5`.  But unfortunately, I have to spread the load of this, as it was burning me to the ground!\n\nThis is my '.NET Framework to .NET Core' moment.  I realise that.  And I an truly sorry to those that have to do the migration.  Please make sure you have adequate time set aside for the migration.\n\n### `Some<A>`\n\t* Mitigtation: use nullable references instead\n### `OptionUnsafe<A>`\n\t* Mitigtation: use `Option<A?>` instead\n### `OptionAsync<A>`\n\t* Mitigtation: use `OptionT<IO, A>` instead\n### `OptionNone`:\n\t* Mitigtation: use `Fail<Unit>` instead\n### `EitherUnsafe<L, R>`:\n\t* Mitigtation: use `Either<L?, R?>` instead\n### `EitherLeft<L>`\n\t* Mitigtation: use `Fail<L>` instead\n### `EitherRight<L>`:\n\t* Mitigtation: use `Pure<R>` instead\n### `EitherAsync<L, R>`:\n\t* Mitigtation: use `EitherT<L, IO, R>` instead\n### `Try<A>`\n\t* Mitigtation: use `Eff<A>`\n### `TryOption<A>`\n\t* Mitigtation: use `OptionT<IO, A>`\n### `TryAsync<A>`\n\t* Mitigtation: use `Eff<A>`\n### `TryOptionAsync<A>`\n\t* Mitigtation: use `OptionT<IO, A>`\n### `Result<A>`\n\t* Mitigtation: use `Fin<A>`\n### `OptionalResult<A>`\n\t* Mitigtation: use `Fin<A?>`\n### Async extensions for `Option<A>` and `Either<L, R>`\n\t* Mitigtation: use `ToIO()` to convert to the transformer variants with embedded `IO`\n### `ExceptionMatch`, `ExceptionMatchAsync`, `ExceptionMatchOptionalAsync`\n\t* Mitigtations: \n\t\t* use effect monads with `@catch`\n\t\t* use `switch` expressions\n\n\n## Libraries removed outright\n\n### `LanguageExt.SysX`\n\nthis was only needed to partition newer .NET Core code from .NET Standard.  This has now been merged into `LanguageExt.Sys`\n\n### `LanguageExt.CodeGen` \n\nDeprecated from now.  To be replaced later by `LanguageExt.SourceGen`.  Note, this library has always been standalone and can therefore continue to work without new versions being released.\n\n### `LanguageExt.Transformers` \n\nNo need for them now we have proper higher-kind support.\n\n# TODO\n\n* Traverse / Sequence - generic system using Transducers\n* Make TraverseParallel for Eff\n* ~~Find a way of resolving default implementations for classes now that we're using static interface methods (IL.cs).~~\n* Test that resources are freed correctly in ResourceT when the result of Run is lazy\n\t* `bracket`\n* `EitherT`, `TryT` (derives `EitherT<M, Error, A>)`, `Try` (derives `TryT<Identity, A>`)\n* `yieldAll`, `many`, and `repeat` for Pipes needs tail recursion support\n\t* `yieldAll`, `many` have been temporarily removed\n* `yieldAll` in Pipes has a temporary solution - need proper recursion strategy\n* ~~Use alpha and beta versioning like like: `5.0.0-alpha.1`, `5.0.0-alpha.2`, etc. So we can release `5.0.0` when done~~\n* Make ForkIO.Await respect two cancellation tokens, the original and the one from the runner of Await \n* ~~Make Eff a ReaderM, ResourceM, etc. -- so we don't have to do so much manual lifting~~\n* Overrides of Foldable for the sequence types (`Count()`, `Head()`, `Last()` etc.)\n* Make sure Index is used properly in collections this[] implementations (namely, from end!)\n* Make sure correct trait is used between MonoidK and Alternative -- the collections in particular should be MonoidK as the Combine usually concats the collections (rather than provides an Alternative).\n* Review `Prelude_Collections`\n* Write unit tests (generally!)\n* Write unit tests for index operator on lists and foldables [^1]\n* Add IComparisonOperators / IAdditionOperators / etc. to types\n* Make NewTypes support appropriate traits\n* Add Applicatice.Actions to every applicative that has an error state\n* Exception catching in Producer.merge\n* Implement `TraverseM` for each data-type (like the `Traverse` implementations)\n"
  },
  {
    "path": "Performance.md",
    "content": "# Perfomance benchmarks\n\n** Machine spec **\n\n    BenchmarkDotNet=v0.11.5, OS=Windows 10.0.17134.1184 (1803/April2018Update/Redstone4)\n    Intel Core i5-3470 CPU 3.20GHz (Ivy Bridge), 1 CPU, 4 logical and 4 physical cores\n    Frequency=3117923 Hz, Resolution=320.7263 ns, Timer=TSC\n    .NET Core SDK=3.1.100\n      [Host]     : .NET Core 3.0.1 (CoreCLR 4.700.19.51502, CoreFX 4.700.19.51609), 64bit RyuJIT\n      DefaultJob : .NET Core 3.0.1 (CoreCLR 4.700.19.51502, CoreFX 4.700.19.51609), 64bit RyuJIT\n      \n## Note\n\nReferences to `Sys.Coll.Imm` are Microsoft's `ImmutableCollections` library.\n\n* `Sys.Coll.Imm.List` is `System.Collections.Immutable.ImmutableList`\n* `Sys.Coll.Imm.Dictionary` is `System.Collections.Immutable.ImmutableDictionary`\n* `Sys.Coll.Imm.SortedDictionary` is `System.Collections.Immutable.ImmutableSortedDictionary`\n* `Sys.Coll.Imm.SortedSet` is `System.Collections.Immutable.ImmutableSortedSet`\n      \n\n## Lists\n\n### Lists with value types\n\nType | N | Add | RandomAccess | Iteration\n----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.List` | `100` | `20 us` | `6,016 ns` | `1,021 ns`\n`Sys.Coll.Imm.List` | `1000` | `342 us` | `62,300 ns` | `32,942 ns`\n`Sys.Coll.Imm.List` | `10000` | `5,942 us` | `605,456 ns` | `443,482 ns`\n`Sys.Coll.Imm.List` | `100000` | `87,089 us` | `8,154,876 ns` | `6,146,402 ns`\n`LanguageExt.Lst` | `100` | `17 us` | `1,386 ns` | `1,213 ns`\n`LanguageExt.Lst` | `1000` | `273 us` | `13,455 ns` | `35,304 ns`\n`LanguageExt.Lst` | `10000` | `5,341 us` | `137,278 ns` | `471,614 ns`\n`LanguageExt.Lst` | `100000` | `62,340 us` | `1,696,505 ns` | `6,195,590 ns`\n`LanguageExt.Seq` | `100` | `2 us` | `638 ns` | `359 ns`\n`LanguageExt.Seq` | `1000` | `17 us` | `6,194 ns` | `3,518 ns`\n`LanguageExt.Seq` | `10000` | `205 us` | `61,358 ns` | `35,117 ns`\n`LanguageExt.Seq` | `100000` | `1,879 us` | `613,746 ns` | `351,036 ns`\n\n### Lists with reference types\n\nType | N | Add | RandomAccess | Iteration\n----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.List` | `100` | `22 us` | `10,652 ns` | `1,013 ns`\n`Sys.Coll.Imm.List` | `1000` | `357 us` | `105,946 ns` | `33,410 ns`\n`Sys.Coll.Imm.List` | `10000` | `6,237 us` | `1,069,881 ns` | `448,148 ns`\n`Sys.Coll.Imm.List` | `100000` | `83,450 us` | `13,386,415 ns` | `6,260,259 ns`\n`LanguageExt.Lst` | `100` | `24 us` | `1,547 ns` | `3,561 ns`\n`LanguageExt.Lst` | `1000` | `349 us` | `14,446 ns` | `56,720 ns`\n`LanguageExt.Lst` | `10000` | `6,240 us` | `148,034 ns` | `747,441 ns`\n`LanguageExt.Lst` | `100000` | `75,870 us` | `1,986,228 ns` | `9,194,727 ns`\n`LanguageExt.Seq` | `100` | `3 us` | `888 ns` | `856 ns`\n`LanguageExt.Seq` | `1000` | `28 us` | `8,489 ns` | `8,537 ns`\n`LanguageExt.Seq` | `10000` | `367 us` | `84,479 ns` | `85,092 ns`\n`LanguageExt.Seq` | `100000` | `4,463 us` | `856,149 ns` | `853,446 ns`\n\n## Maps\n\n### Unsorted maps with value types\n\nType | N | Add | ContainsKey | Iterate | RandomRemoval\n----- | ----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.Dictionary` | `100` | `69 us` | `2,348 ns` | `10,647 ns` | `49,871 ns`\n`Sys.Coll.Imm.Dictionary` | `1000` | `1,125 us` | `60,126 ns` | `118,251 ns` | `894,815 ns`\n`Sys.Coll.Imm.Dictionary` | `10000` | `17,785 us` | `958,715 ns` | `1,164,131 ns` | `13,768,680 ns`\n`Sys.Coll.Imm.Dictionary` | `100000` | `298,988 us` | `17,859,368 ns` | `13,715,622 ns` | `242,798,528 ns`\n`LanguageExt.HashMap` | `100` | `15 us` | `2,042 ns` | `3,579 ns` | `14,065 ns`\n`LanguageExt.HashMap` | `1000` | `245 us` | `27,338 ns` | `38,108 ns` | `231,652 ns`\n`LanguageExt.HashMap` | `10000` | `5,023 us` | `354,385 ns` | `459,233 ns` | `3,810,743 ns`\n`LanguageExt.HashMap` | `100000` | `92,372 us` | `7,196,852 ns` | `7,432,346 ns` | `77,218,736 ns`\n\n### Unsorted maps with reference types\n\nType | N | Add | ContainsKey | Iterate | RandomRemoval\n----- | ----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.Dictionary` | `100` | `90 us` | `6 us` | `20,352 ns` | `67 us`\n`Sys.Coll.Imm.Dictionary` | `1000` | `1,481 us` | `104 us` | `202,502 ns` | `1,085 us`\n`Sys.Coll.Imm.Dictionary` | `10000` | `23,336 us` | `1,504 us` | `2,076,426 ns` | `17,480 us`\n`Sys.Coll.Imm.Dictionary` | `100000` | `390,738 us` | `28,854 us` | `26,252,578 ns` | `291,299 us`\n`LanguageExt.HashMap` | `100` | `27 us` | `5 us` | `5,394 ns` | `24 us`\n`LanguageExt.HashMap` | `1000` | `404 us` | `74 us` | `62,036 ns` | `364 us`\n`LanguageExt.HashMap` | `10000` | `7,080 us` | `859 us` | `755,971 ns` | `5,773 us`\n`LanguageExt.HashMap` | `100000` | `138,283 us` | `17,573 us` | `12,049,411 ns` | `114,837 us`\n\n### Sorted maps with value types\n\nType | N | Add | ContainsKey | Iterate | RandomRemoval\n----- | ----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.SortedDictionary` | `100` | `31 us` | `3,814 ns` | `6,140 ns` | `24,785 ns`\n`Sys.Coll.Imm.SortedDictionary` | `1000` | `539 us` | `78,032 ns` | `61,408 ns` | `449,868 ns`\n`Sys.Coll.Imm.SortedDictionary` | `10000` | `9,631 us` | `1,165,587 ns` | `617,841 ns` | `7,246,961 ns`\n`Sys.Coll.Imm.SortedDictionary` | `100000` | `203,653 us` | `19,308,708 ns` | `8,107,066 ns` | `149,215,888 ns`\n`LanguageExt.Map` | `100` | `19 us` | `2,805 ns` | `1,593 ns` | `13,458 ns`\n`LanguageExt.Map` | `1000` | `335 us` | `82,493 ns` | `16,605 ns` | `283,067 ns`\n`LanguageExt.Map` | `10000` | `6,871 us` | `1,272,800 ns` | `190,544 ns` | `5,016,271 ns`\n`LanguageExt.Map` | `100000` | `155,131 us` | `22,845,338 ns` | `3,707,917 ns` | `118,625,112 ns`\n\n### Sorted maps with reference types\n\nType | N | Add | ContainsKey | Iterate | RandomRemoval\n----- | ----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.SortedDictionary` | `100` | `79 us` | `42 us` | `10,449 ns` | `59 us`\n`Sys.Coll.Imm.SortedDictionary` | `1000` | `1,333 us` | `706 us` | `103,676 ns` | `1,069 us`\n`Sys.Coll.Imm.SortedDictionary` | `10000` | `21,790 us` | `10,429 us` | `1,073,453 ns` | `17,848 us`\n`Sys.Coll.Imm.SortedDictionary` | `100000` | `393,881 us` | `164,318 us` | `13,811,388 ns` | `319,229 us`\n`LanguageExt.Map` | `100` | `72 us` | `44 us` | `2,112 ns` | `51 us`\n`LanguageExt.Map` | `1000` | `1,137 us` | `737 us` | `22,033 ns` | `896 us`\n`LanguageExt.Map` | `10000` | `19,178 us` | `10,676 us` | `252,819 ns` | `15,598 us`\n`LanguageExt.Map` | `100000` | `350,295 us` | `171,571 us` | `4,256,098 ns` | `301,462 us`\n\n## Sets\n\n### Unsorted sets with value types\n\nType | N | Add | Contains | Iteration | RandomRemoval\n----- | ----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.HashSet` | `100` | `52 us` | `3 us` | `11,975 ns` | `39,490 ns`\n`Sys.Coll.Imm.HashSet` | `1000` | `878 us` | `65 us` | `118,770 ns` | `702,550 ns`\n`Sys.Coll.Imm.HashSet` | `10000` | `14,230 us` | `1,033 us` | `1,245,373 ns` | `11,267,592 ns`\n`Sys.Coll.Imm.HashSet` | `100000` | `249,189 us` | `17,250 us` | `15,266,368 ns` | `207,453,344 ns`\n`LanguageExt.HashSet` | `100` | `13 us` | `2 us` | `3,366 ns` | `13,782 ns`\n`LanguageExt.HashSet` | `1000` | `224 us` | `23 us` | `34,842 ns` | `221,730 ns`\n`LanguageExt.HashSet` | `10000` | `4,520 us` | `320 us` | `458,131 ns` | `3,744,864 ns`\n`LanguageExt.HashSet` | `100000` | `85,851 us` | `5,648 us` | `6,528,404 ns` | `74,686,456 ns`\n\n### Unsorted sets with reference types\n\nType | N | Add | Contains | Iteration | RandomRemoval\n----- | ----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.HashSet` | `100` | `66 us` | `8 us` | `26,331 ns` | `51 us`\n`Sys.Coll.Imm.HashSet` | `1000` | `1,008 us` | `117 us` | `261,931 ns` | `833 us`\n`Sys.Coll.Imm.HashSet` | `10000` | `15,992 us` | `1,575 us` | `2,660,329 ns` | `12,879 us`\n`Sys.Coll.Imm.HashSet` | `100000` | `271,162 us` | `25,866 us` | `30,410,462 ns` | `224,692 us`\n`LanguageExt.HashSet` | `100` | `21 us` | `6 us` | `3,665 ns` | `21 us`\n`LanguageExt.HashSet` | `1000` | `322 us` | `69 us` | `40,037 ns` | `327 us`\n`LanguageExt.HashSet` | `10000` | `5,761 us` | `820 us` | `488,167 ns` | `4,944 us`\n`LanguageExt.HashSet` | `100000` | `113,138 us` | `13,739 us` | `7,971,738 ns` | `94,890 us`\n\n### Sorted sets with value types\n\nType | N | Add | Contains | Iteration | RandomRemoval\n----- | ----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.SortedSet` | `100` | `29 us` | `3 us` | `6,058 ns` | `23,319 ns`\n`Sys.Coll.Imm.SortedSet` | `1000` | `506 us` | `67 us` | `60,265 ns` | `425,159 ns`\n`Sys.Coll.Imm.SortedSet` | `10000` | `8,748 us` | `1,009 us` | `618,772 ns` | `6,950,004 ns`\n`Sys.Coll.Imm.SortedSet` | `100000` | `195,510 us` | `17,397 us` | `7,341,612 ns` | `145,175,136 ns`\n`LanguageExt.Set` | `100` | `17 us` | `3 us` | `1,575 ns` | `18,006 ns`\n`LanguageExt.Set` | `1000` | `306 us` | `70 us` | `16,889 ns` | `324,040 ns`\n`LanguageExt.Set` | `10000` | `6,199 us` | `1,101 us` | `192,437 ns` | `5,918,020 ns`\n`LanguageExt.Set` | `100000` | `147,726 us` | `20,893 us` | `2,980,587 ns` | `138,141,008 ns`\n\n### Sorted sets with reference types\n\nType | N | Add | Contains | Iteration | RandomRemoval\n----- | ----- | ----- | ----- | ----- | -----\n`Sys.Coll.Imm.SortedSet` | `100` | `72 us` | `40 us` | `10,645 ns` | `60 us`\n`Sys.Coll.Imm.SortedSet` | `1000` | `1,187 us` | `683 us` | `104,584 ns` | `1,022 us`\n`Sys.Coll.Imm.SortedSet` | `10000` | `19,371 us` | `9,842 us` | `1,071,031 ns` | `16,301 us`\n`Sys.Coll.Imm.SortedSet` | `100000` | `329,705 us` | `161,498 us` | `13,185,054 ns` | `288,019 us`\n`LanguageExt.Set` | `100` | `63 us` | `37 us` | `1,644 ns` | `47 us`\n`LanguageExt.Set` | `1000` | `1,001 us` | `629 us` | `17,305 ns` | `854 us`\n`LanguageExt.Set` | `10000` | `16,150 us` | `9,435 us` | `200,705 ns` | `14,227 us`\n`LanguageExt.Set` | `100000` | `307,030 us` | `144,921 us` | `2,834,565 ns` | `272,077 us`\n\n\n"
  },
  {
    "path": "README.md",
    "content": "![lang-ext](https://raw.githubusercontent.com/louthy/language-ext/main/Images/banner.png)\n\nC# Functional Programming Language Extensions\n=============================================\n\nThis library uses and abuses the features of C# to provide a pure functional-programming framework that, if you squint, can look like \nextensions to the language itself. The desire here is to make programming in C# much more robust by helping the engineer's inertia flow \nin the direction of declarative and pure functional code rather than imperative.  Using these techniques for large code-bases can bring \ntangible benefits to long-term maintenance by removing hidden complexity and by easing the engineer's and team's cognitive load.\n\n[![GitHub Discussions](https://raw.githubusercontent.com/louthy/language-ext/main/Images/discussions.svg)](https://github.com/louthy/language-ext/discussions)\n\n__Author on...__\n* __Blog__: [Notes from a Small Functional Island](https://paullouth.com/)\n* __Bluesky__: [@paullouth.bsky.social](https://bsky.app/profile/paullouth.bsky.social)\n* __Mastodon:__ [@louthy@4four.org](https://4four.org/@louthy)\n* __Github ReadME project__: ['Functional programming is finally going mainstream'](https://github.com/readme/featured/functional-programming)\n\n## Contents\n\n* [Reference](#reference)\n* [Nu-get package](#nu-get)\n* [Getting started](#getting-started)\n* [Prologue](#prologue)\n* [**Features**](#features)\n  * [Functional effects and IO](#functional-effects-and-io)\n  * [Atomic concurrency, shared state, and collections](#atomic-concurrency-and-collections)\n  * [Immutable collections](#immutable-collections)\n  * [Functional streams](#functional-streams)\n  * [Optional and Alternative value monads](#optional-and-alternative-value-monads)\n  * [State managing monads](#state-managing-monads)\n  * [Parser combinators](#parser-combinators)\n  * [Pretty: Produce nicely formatted text with smart layouts](#pretty)\n  * [Differencing](#differencing)\n  * [Traits](#traits)\n  * [Value traits](#value-traits)\n* [Contributing & Code of Conduct](#contributing--code-of-conduct)\n\n\n## Reference\n\n* [API Reference](https://louthy.github.io/language-ext/)\n* [Issues that contain documentation and examples](https://github.com/louthy/language-ext/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3A%22examples%20%2F%20documentation%22%20)\n\n## Nu-get\n\nNu-get package | Description\n---------------|-------------\n[LanguageExt.Parsec](https://www.nuget.org/packages/LanguageExt.Parsec) | Port of the [Haskell parsec library](https://hackage.haskell.org/package/parsec)\n[LanguageExt.Streaming](https://www.nuget.org/packages/LanguageExt.Streaming) | A set of compositional streaming types \n[LanguageExt.FSharp](https://www.nuget.org/packages/LanguageExt.FSharp) | F# to C# interop package. Provides interop between the LanguageExt.Core types (like `Option`, `List` and `Map`) to the F# equivalents, as well as interop between core BCL types and F#\n[LanguageExt.Parsec](https://www.nuget.org/packages/LanguageExt.Parsec) | Port of the [Haskell parsec library](https://hackage.haskell.org/package/parsec)\n[LanguageExt.Rx](https://www.nuget.org/packages/LanguageExt.Rx) | Reactive Extensions support for various types within the Core\n[LanguageExt.Sys](https://www.nuget.org/packages/LanguageExt.Sys) | Provides an effects wrapper around the .NET System namespace making common IO operations pure and unit-testable\n\n![lang-ext](https://raw.githubusercontent.com/louthy/language-ext/main/Images/lang-ext-warning.jpg)\n\n## Getting started\n\nTo use this library, simply include `LanguageExt.Core.dll` in your project or grab it from NuGet.  It is also worth setting up some `global using` for your project.  This is the full list that will cover all functionality and bring it into scope:\n```C#\nglobal using LanguageExt;\nglobal using LanguageExt.Common;\nglobal using LanguageExt.Traits;\nglobal using LanguageExt.Effects;\nglobal using LanguageExt.Streaming;\nglobal using LanguageExt.Pretty;\nglobal using LanguageExt.Traits.Domain;\nglobal using static LanguageExt.Prelude;\n```\nA minimum, might be:\n```c#\nglobal using LanguageExt;\nglobal using static LanguageExt.Prelude;\n```\n\nThe namespace `LanguageExt` contains most of the core types; `LanguageExt.Prelude` contains the functions that bring into scope the prelude functions that behave like standalone functions in ML style functional programming languages; `LanguageExt.Traits` brings in the higher-kinded trait-types and many extensions; `LanguageExt.Common` brings in the `Error` type and predefined `Errors`.\n\n## Prologue\nFrom C# 6 onwards we got the ability to treat static classes like namespaces. This means that we can use static \nmethods without qualifying them first. That instantly gives us access to single term method names that look exactly like functions \nin ML-style functional languages. i.e.\n```C#\n    using static System.Console;\n    \n    WriteLine(\"Hello, World\");\n```\nThis library tries to bring some of the functional world into C#. It won't always sit well with the seasoned C# OO programmer, \nespecially the choice of `camelCase` names for a lot of functions and the seeming 'globalness' of a lot of the library. \n\nI can understand that much of this library is non-idiomatic, but when you think of the journey C# has been on, is \"idiomatic\" \nnecessarily right?  A lot of C#'s idioms are inherited from Java and C# 1.0. Since then we've had generics, closures, Func, LINQ, \nasync... C# as a language is becoming more and more like a  functional language on every release. In fact, the bulk of the new \nfeatures are either inspired by or directly taken from features in functional languages. So perhaps it's time to move the C# \nidioms closer to the functional world's idioms?\n\nMy goal with this library is very much to create a whole new community within the larger C# community.  This community is not \nconstrained by the dogma of the past or by the norms of C#.  It understands that the OOP approach to programming has some problems\nand tries to address them head-on.  \n\nAnd for those that say \"just use F#\" or \"just use Haskell\", sure, go do that.  But it's important to remember that C# has a lot\ngoing for it:\n\n* Incredible investment into a state-of-the art compiler\n* Incredible tooling (Visual Studio and Rider)\n* A large ecosystem of open-source libraries\n* A large community of developers already using it\n  * This is also very important for companies that hire engineers\n* It _is_ a functional programming language!  It has first-class functions, lambdas, etc.\n  * And with this library it has a functional-first _Base Class Library_\n\n### A note about naming\n\nOne of the areas that's likely to get seasoned C# heads worked up is my choice of naming style. The intent is to try and make \nsomething that _feels_ like a functional language rather than following rules of naming conventions (mostly set out by \nthe BCL). \n\nThere is, however, a naming guide that will keep you in good stead while reading through this documentation:\n\n* Type names are `PascalCase` in the normal way\n* The types all have constructor functions rather than public constructors that you instantiate with `new`. They will always \nbe `PascalCase`:\n```C#\n    Option<int> x = Some(123);\n    Option<int> y = None;\n    Seq<int> items = Seq(1,2,3,4,5);\n    List<int> items = List(1,2,3,4,5);\n    HashMap<int, string> dict = HashMap((1, \"Hello\"), (2, \"World\"));\n    Map<int, string> dict = Map((1, \"Hello\"), (2, \"World\"));\n```\n* Any (non-type constructor) static function that can be used on its own by `using static LanguageExt.Prelude` are `camelCase`.\n```C#\n    var x = map(opt, v => v * 2);\n```\n* Any extension methods, or anything \"fluent\" are `PascalCase` in the normal way\n```C#\n    var x = opt.Map(v => v * 2);\n```\nEven if you disagree with this non-idiomatic approach, all of the `camelCase` static functions have fluent variants, so you never actually have to see the non-standard stuff. \n\n## Features\n\n### [Functional effects and IO](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/index.html)\n\n| Location | Feature      | Description                                                                                                                                                                                              |\n|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `IO<A>`      | [A synchronous and asynchronous side-effect: an IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/IO/index.html)                                                                  |\n| `Core`   | `Eff<A>`     | [A synchronous and asynchronous side-effect with error handling](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20no%20runtime/index.html)                                       |\n| `Core`   | `Eff<RT, A>` | [Same as `Eff<A>` but with an injectable runtime for dependency-injection: a unit testable IO monad](https://louthy.github.io/language-ext/LanguageExt.Core/Effects/Eff/Eff%20with%20runtime/index.html) |\n\n### [Atomic concurrency and collections](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/index.html)\n\n| Location | Feature                            | Description                                                                                                                                            |\n|----------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Atom<A>`                          | [A lock-free atomically mutable reference for working with shared state](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/Atom)      |\n| `Core`   | `Ref<A>`                           | [An atomic reference to be used in the transactional memory system](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/STM)            |\n| `Core`   | `AtomHashMap<K, V>`                | [An immutable `HashMap` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomHashMap) |\n| `Core`   | `AtomSeq<A>`                       | [An immutable `Seq` with a lock-free atomically mutable reference](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/AtomSeq)         |\n| `Core`   | `VectorClock<A>`                   | [Understand distributed causality](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VectorClock)                                     |\n| `Core`   | `VersionVector<A>`                 | [A vector clock with some versioned data](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionVector)                            |\n| `Core`   | `VersionHashMap <ConflictV, K, V>` | [Distrubuted atomic versioning of keys in a hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Concurrency/VersionHashMap)               |\n\n### [Immutable collections](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/index.html)\n\n| Location | Feature              | Description                                                                                                                                                                                                             |\n|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Arr<A>`             | [Immutable array](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Arr/index.html)                                                                                                        |\n| `Core`   | `Seq<A>`             | [Lazy immutable list, evaluate at-most-once](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Seq/index.html) - very, very fast!                                                          |\n| `Core`   | `Iterable<A>`        | [Wrapper around `IEnumerable` with support for traits](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Iterable/index.html) - enables the higher-kinded traits to work with enumerables. |\n| `Core`   | `Lst<A>`             | [Immutable list](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/List/index.html) - use `Seq` over `Lst` unless you need `InsertAt`                                                      |\n| `Core`   | `Map<K, V>`          | [Immutable map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                                                          |\n| `Core`   | `Map<OrdK, K, V>`    | [Immutable map with Ord constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Map/index.html)                                                                               |\n| `Core`   | `HashMap<K, V>`      | [Immutable hash-map](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                                                 |\n| `Core`   | `HashMap<EqK, K, V>` | [Immutable hash-map with Eq constraint on `K`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashMap/index.html)                                                                       |\n| `Core`   | `Set<A>`             | [Immutable set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                                                          |\n| `Core`   | `Set<OrdA, A>`       | [Immutable set with Ord constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Set/index.html)                                                                               |\n| `Core`   | `HashSet<A>`         | [Immutable hash-set](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                                                 |\n| `Core`   | `HashSet<EqA, A>`    | [Immutable hash-set with Eq constraint on `A`](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/HashSet/index.html)                                                                       |\n| `Core`   | `Que<A>`             | [Immutable queue](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Queue/index.html)                                                                                                      |\n| `Core`   | `Stck<A>`            | [Immutable stack](https://louthy.github.io/language-ext/LanguageExt.Core/Immutable%20Collections/Stack/index.html)                                                                                                      |\n\n### [Functional streams](https://louthy.github.io/language-ext/LanguageExt.Streaming/index.html)\n\n| Location | Feature      | Description                                                                                                                                                                                              |\n|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Streaming` | Pipes        | [Connect reusable streaming components into a closed effect](https://louthy.github.io/language-ext/LanguageExt.Streaming/Pipes/)           |\n| `Streaming` | `Sink` | [Entry point to a channel. Sinks receive values and propagate them through a channel](https://louthy.github.io/language-ext/LanguageExt.Streaming/Sink/) |\n| `Streaming` | `SinkT` | [As above but with effects](https://louthy.github.io/language-ext/LanguageExt.Streaming/SinkT/) |\n| `Streaming` | `Source` | [Stream of synchronous or asynchronous values depending on the construction. Values flow downstream and are aggregated with a reducer.](https://louthy.github.io/language-ext/LanguageExt.Streaming/Source/) |\n| `Streaming` | `SourceT` | [As above but with effects](https://louthy.github.io/language-ext/LanguageExt.Streaming/SourceT/) |\n| `Streaming` | `Conduit` | [Represents a channel with an internal queue. The conduit has a `Sink` and a `Source` allowing items to be posted into the conduit, co-mapped, mapped, and consumed.](https://louthy.github.io/language-ext/LanguageExt.Streaming/Conduit) |\n| `Streaming` | `ConduitT` | [As above but with effects: the conduit has a `SinkT` and a `SourceT` allowing items to be posted into the conduit, co-mapped, mapped, and consumed.](https://louthy.github.io/language-ext/LanguageExt.Streaming/ConduitT) |\n\n### [Optional and alternative value monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/index.html)\n\n| Location | Feature                         | Description                                                                                                                                                                                              |\n|----------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Option<A>`                     | [Option monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Option/index.html)                                                                                     |\n| `Core`   | `OptionT<M, A>`                 | [Option monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/OptionT/index.html)                                                                        |\n| `Core`   | `Either<L,R>`                   | [Right/Left choice monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Either/index.html)                                                                          |\n| `Core`   | `EitherT<L, M, R>`              | [Right/Left choice monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/EitherT/index.html)                                                             |\n| `Core`   | `Fin<A>`                        | [`Error` handling monad, like `Either<Error, A>`](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Fin/index.html)                                                     |\n| `Core`   | `FinT<M, A>`                    | [`Error` handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/FinT/index.html)                                                                 |\n| `Core`   | `Try<A>`                        | [Exception handling monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Try/index.html)                                                                            |\n| `Core`   | `TryT<M, A>`                    | [Exception handling monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/TryT/index.html)                                                               |\n| `Core`   | `Validation<FAIL ,SUCCESS>`     | [Validation applicative and monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/Validation/index.html) for collecting multiple errors before aborting an operation |\n| `Core`   | `ValidationT<FAIL, M, SUCCESS>` | [Validation applicative and monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Monads/ValidationT/index.html)                                                |\n\n### [State managing monads](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/index.html)\n\n| Location | Feature            | Description                                                                                                                                                                             |\n|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Reader<E, A>`     | [Reader monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/Reader/index.html)                                               |\n| `Core`   | `ReaderT<E, M, A>` | [Reader monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Reader/ReaderT/index.html)                                  |\n| `Core`   | `Writer<W, A>`     | [Writer monad that logs to a `W` constrained to be a Monoid](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/Writer/index.html) |\n| `Core`   | `WriterT<W, M, A>` | [Writer monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/Writer/WriterT/index.html)                                  |\n| `Core`   | `State<S, A>`      | [State monad](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/State/index.html)                                                  |\n| `Core`   | `StateT<S, M, A>`  | [State monad-transformer](https://louthy.github.io/language-ext/LanguageExt.Core/Monads/State%20and%20Environment%20Monads/State/StateT/index.html)                                     |\n\n### [Parser combinators](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)\n\n| Location | Feature        | Description                                                                                                                    |\n|----------|----------------|--------------------------------------------------------------------------------------------------------------------------------|\n| `Parsec` | `Parser<A>`    | [String parser monad and full parser combinators library](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html) |\n| `Parsec` | `Parser<I, O>` | [Parser monad that can work with any input stream type](https://louthy.github.io/language-ext/LanguageExt.Parsec/index.html)   |\n\n### [Pretty](https://louthy.github.io/language-ext/LanguageExt.Core/Pretty/index.html)\n\n| Location | Feature  | Description                                      |\n|----------|----------|--------------------------------------------------|\n| `Core`   | `Doc<A>` | Produce nicely formatted text with smart layouts |\n\n### [Differencing](https://louthy.github.io/language-ext/LanguageExt.Core/DataTypes/Patch/index.html)\n\n| Location | Feature         | Description                                                                                                                                                                                                                          |\n|----------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Patch<EqA, A>` | Uses patch-theory to efficiently calculate the difference (`Patch.diff(list1, list2)`) between two collections of `A` and build a patch which can be applied (`Patch.apply(patch, list)`) to one to make the other (think git diff). |\n\n### [Traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/index.html)\n\nThe traits are major feature of `v5`+ language-ext that makes generic programming with higher-kinds a reality.  Check out Paul's [series on Higher Kinds](https://paullouth.com/higher-kinds-in-c-with-language-ext/) to get a deeper insight.\n\n| Location | Feature                                | Description                                                                                                                                                            |\n|----------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `Applicative<F>`                       | [Applicative functor](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Applicative/index.html)                                                            |\n| `Core`   | `Eq<A>`                                | [Ad-hoc equality trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Eq/index.html)                                                                   |\n| `Core`   | `Fallible<F>`                          | [Trait that describes types that can fail](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Fallible/index.html)                                          |\n| `Core`   | `Foldable<T>`                          | [Aggregation over a structure](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Foldable/index.html)                                                      |\n| `Core`   | `Functor<F>`                           | [Functor `Map`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Functor/index.html)                                                                      |\n| `Core`   | `Has<M, TRAIT>`                        | [Used in runtimes to enable DI-like capabilities](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Has/index.html)                                        |\n| `Core`   | `Hashable<A>`                          | [Ad-hoc has-a-hash-code trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Hashable/index.html)                                                      |\n| `Core`   | `Local<M, E>`                          | [Creates a local environment to run a computation ](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Local/index.html)                                    |\n| `Core`   | `Monad<M>`                             | [Monad trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/Monad/index.html)                                                                   |\n| `Core`   | `MonadT<M, N>`                         | [Monad transformer trait](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monads/MonadT/index.html)                                                      |\n| `Core`   | `Monoid<A>`                            | [A monoid is a type with an identity `Empty` and an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Monoid/index.html) |\n| `Core`   | `MonoidK<M>`                           | [Equivalent of monoids for working on higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/MonoidK/index.html)                           |\n| `Core`   | `Mutates<M, OUTER_STATE, INNER_STATE>` | [Used in runtimes to enable stateful operations](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Mutates/index.html)                                     |\n| `Core`   | `Ord<A>`                               | [Ad-hoc ordering / comparisons](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Ord/index.html)                                                          |\n| `Core`   | `Range<SELF, NumOrdA, A>`              | [Abstraction of a range of values](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Range/index.html)                                                     |\n| `Core`   | `Readable<M, Env>`                     | [Generalised Reader monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Readable/index.html)                                              |\n| `Core`   | `Semigroup<A>`                         | [Provides an associative binary operation `+`](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Semigroup/index.html)                                     |\n| `Core`   | `SemigroupK<M>`                        | [Equivalent of semigroups for working with higher-kinded types](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/SemigroupK/index.html)                   |\n| `Core`   | `Stateful<M, S>`                       | [Generalised State monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Stateful/index.html)                                               |\n| `Core`   | `Traversable<T>`                       | [Traversable structures support element-wise sequencing of Applicative effects](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Traversable/index.html)  |\n| `Core`   | `Writable<M, W>`                       | [Generalised Writer monad abstraction](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Writable/index.html)                                              |\n\n### [Value traits](https://louthy.github.io/language-ext/LanguageExt.Core/Traits/Domain/index.html)\n\nThese work a little like type-aliasing but they impart semantic meaning and some common operators for the underlying value.\n\n| Location | Feature                              | Description                                                                                                                                                                                                                                       |\n|----------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Core`   | `DomainType<SELF, REPR>`             | Provides a mapping from `SELF` to an underlying representation: `REPR`                                                                                                                                                                            |\n| `Core`   | `Identifier <SELF>`                  | Identifiers (like IDs in databases: `PersonId` for example), they are equivalent to `DomaintType` with equality.                                                                                                                                  |\n| `Core`   | `VectorSpace<SELF, SCALAR>`          | Scalable values; can add and subtract self, but can only multiply and divide by a scalar. Can also negate.                                                                                                                                        |\n| `Core`   | `Amount <SELF, SCALAR>`              | Quantities, such as the amount of money in USD on a bank account or a file size in bytes. Derives `VectorSpace`, `IdentifierLike`, `DomainType`, and is orderable (comparable).                                                                   |\n| `Core`   | `Locus <SELF, DISTANCE, SCALAR>`     | Works with space-like structures. Spaces have absolute and relative distances. Has an origin/zero point and derives `DomainType`, `IdentifierLike`, `AmountLike` and `VectorSpace`.  `DISTANCE` must also be an `AmountLike<SELF, REPR, SCALAR>`. |\n\n_These features are still a little in-flux as of 17th Oct 2024 - they may evolve, be renamed, or removed - but I like the idea!_\n\n## Further \n\nFor some non-reference like documentation:\n\n* Paul's blog: [Notes from a Small Functional Island](https://paullouth.com/) does deep dives into the philosophy of FP and the inner-workings of language-ext.\n* [The wiki](https://github.com/louthy/language-ext/wiki) has some additional documentation, some might be a little out of date since the big `v5` refactor, but should give some good insights.\n\n## Contributing & Code of Conduct\n\nIf you would like to get involved with this project, please first read the [Contribution Guidelines](https://github.com/louthy/language-ext/blob/main/CONTRIBUTING.md) and the [Code of Conduct](https://github.com/louthy/language-ext/blob/main/CODE_OF_CONDUCT.md).\n\n"
  },
  {
    "path": "Samples/BlazorApp/BlazorApp.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <Nullable>enable</Nullable>\n        <ImplicitUsings>enable</ImplicitUsings>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n      <ProjectReference Include=\"..\\..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Samples/BlazorApp/Components/App.razor",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n    <base href=\"/\"/>\n    <link rel=\"stylesheet\" href=\"bootstrap/bootstrap.min.css\"/>\n    <link rel=\"stylesheet\" href=\"app.css\"/>\n    <link rel=\"stylesheet\" href=\"BlazorApp.styles.css\"/>\n    <link rel=\"icon\" type=\"image/png\" href=\"favicon.png\"/>\n    <HeadOutlet/>\n</head>\n\n<body>\n<Routes/>\n<script src=\"_framework/blazor.web.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "Samples/BlazorApp/Components/Layout/MainLayout.razor",
    "content": "﻿@inherits LayoutComponentBase\n\n<div class=\"page\">\n    <div class=\"sidebar\">\n        <NavMenu/>\n    </div>\n\n    <main>\n        <div class=\"top-row px-4\">\n            <a href=\"https://louthy.github.io/language-ext/\" target=\"_blank\">About</a>\n        </div>\n\n        <article class=\"content px-4\">\n            @Body\n        </article>\n    </main>\n</div>\n\n<div id=\"blazor-error-ui\">\n    An unhandled error has occurred.\n    <a href=\"\" class=\"reload\">Reload</a>\n    <a class=\"dismiss\">🗙</a>\n</div>"
  },
  {
    "path": "Samples/BlazorApp/Components/Layout/MainLayout.razor.css",
    "content": ".page {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n}\n\nmain {\n    flex: 1;\n}\n\n.sidebar {\n    background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);\n}\n\n.top-row {\n    background-color: #f7f7f7;\n    border-bottom: 1px solid #d6d5d5;\n    justify-content: flex-end;\n    height: 3.5rem;\n    display: flex;\n    align-items: center;\n}\n\n    .top-row ::deep a, .top-row ::deep .btn-link {\n        white-space: nowrap;\n        margin-left: 1.5rem;\n        text-decoration: none;\n    }\n\n    .top-row ::deep a:hover, .top-row ::deep .btn-link:hover {\n        text-decoration: underline;\n    }\n\n    .top-row ::deep a:first-child {\n        overflow: hidden;\n        text-overflow: ellipsis;\n    }\n\n@media (max-width: 640.98px) {\n    .top-row {\n        justify-content: space-between;\n    }\n\n    .top-row ::deep a, .top-row ::deep .btn-link {\n        margin-left: 0;\n    }\n}\n\n@media (min-width: 641px) {\n    .page {\n        flex-direction: row;\n    }\n\n    .sidebar {\n        width: 250px;\n        height: 100vh;\n        position: sticky;\n        top: 0;\n    }\n\n    .top-row {\n        position: sticky;\n        top: 0;\n        z-index: 1;\n    }\n\n    .top-row.auth ::deep a:first-child {\n        flex: 1;\n        text-align: right;\n        width: 0;\n    }\n\n    .top-row, article {\n        padding-left: 2rem !important;\n        padding-right: 1.5rem !important;\n    }\n}\n\n#blazor-error-ui {\n    background: lightyellow;\n    bottom: 0;\n    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);\n    display: none;\n    left: 0;\n    padding: 0.6rem 1.25rem 0.7rem 1.25rem;\n    position: fixed;\n    width: 100%;\n    z-index: 1000;\n}\n\n    #blazor-error-ui .dismiss {\n        cursor: pointer;\n        position: absolute;\n        right: 0.75rem;\n        top: 0.5rem;\n    }\n"
  },
  {
    "path": "Samples/BlazorApp/Components/Layout/NavMenu.razor",
    "content": "﻿<div class=\"top-row ps-3 navbar navbar-dark\">\n    <div class=\"container-fluid\">\n        <a class=\"navbar-brand\" href=\"\">BlazorApp</a>\n    </div>\n</div>\n\n<input type=\"checkbox\" title=\"Navigation menu\" class=\"navbar-toggler\"/>\n\n<div class=\"nav-scrollable\" onclick=\"document.querySelector('.navbar-toggler').click()\">\n    <nav class=\"flex-column\">\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"\" Match=\"NavLinkMatch.All\">\n                <span class=\"bi bi-house-door-fill-nav-menu\" aria-hidden=\"true\"></span> Home\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"counter\">\n                <span class=\"bi bi-plus-square-fill-nav-menu\" aria-hidden=\"true\"></span> Counter\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"weather\">\n                <span class=\"bi bi-list-nested-nav-menu\" aria-hidden=\"true\"></span> Weather\n            </NavLink>\n        </div>\n    </nav>\n</div>"
  },
  {
    "path": "Samples/BlazorApp/Components/Layout/NavMenu.razor.css",
    "content": ".navbar-toggler {\n    appearance: none;\n    cursor: pointer;\n    width: 3.5rem;\n    height: 2.5rem;\n    color: white;\n    position: absolute;\n    top: 0.5rem;\n    right: 1rem;\n    border: 1px solid rgba(255, 255, 255, 0.1);\n    background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);\n}\n\n.navbar-toggler:checked {\n    background-color: rgba(255, 255, 255, 0.5);\n}\n\n.top-row {\n    height: 3.5rem;\n    background-color: rgba(0,0,0,0.4);\n}\n\n.navbar-brand {\n    font-size: 1.1rem;\n}\n\n.bi {\n    display: inline-block;\n    position: relative;\n    width: 1.25rem;\n    height: 1.25rem;\n    margin-right: 0.75rem;\n    top: -1px;\n    background-size: cover;\n}\n\n.bi-house-door-fill-nav-menu {\n    background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E\");\n}\n\n.bi-plus-square-fill-nav-menu {\n    background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E\");\n}\n\n.bi-list-nested-nav-menu {\n    background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E\");\n}\n\n.nav-item {\n    font-size: 0.9rem;\n    padding-bottom: 0.5rem;\n}\n\n    .nav-item:first-of-type {\n        padding-top: 1rem;\n    }\n\n    .nav-item:last-of-type {\n        padding-bottom: 1rem;\n    }\n\n    .nav-item ::deep .nav-link {\n        color: #d7d7d7;\n        background: none;\n        border: none;\n        border-radius: 4px;\n        height: 3rem;\n        display: flex;\n        align-items: center;\n        line-height: 3rem;\n        width: 100%;\n    }\n\n.nav-item ::deep a.active {\n    background-color: rgba(255,255,255,0.37);\n    color: white;\n}\n\n.nav-item ::deep .nav-link:hover {\n    background-color: rgba(255,255,255,0.1);\n    color: white;\n}\n\n.nav-scrollable {\n    display: none;\n}\n\n.navbar-toggler:checked ~ .nav-scrollable {\n    display: block;\n}\n\n@media (min-width: 641px) {\n    .navbar-toggler {\n        display: none;\n    }\n\n    .nav-scrollable {\n        /* Never collapse the sidebar for wide screens */\n        display: block;\n\n        /* Allow sidebar to scroll for tall menus */\n        height: calc(100vh - 3.5rem);\n        overflow-y: auto;\n    }\n}\n"
  },
  {
    "path": "Samples/BlazorApp/Components/Pages/Counter.razor",
    "content": "﻿@using LanguageExt\n@using static LanguageExt.Prelude;\n@page \"/counter\"\n@rendermode InteractiveServer\n\n<PageTitle>Counter</PageTitle>\n\n<h1>Counter</h1>\n\n<p role=\"status\">Current count: @currentCount</p>\n\n<button class=\"btn btn-primary\" @onclick=\"IncrementCount\">Click me</button>\n\n@code {\n    Atom<int> currentCount = Atom(0);\n\n    void IncrementCount() =>\n        incrementCount.Run();\n\n    IO<int> incrementCount =>\n        currentCount.SwapIO(x => x + 1);\n}"
  },
  {
    "path": "Samples/BlazorApp/Components/Pages/Error.razor",
    "content": "﻿@page \"/Error\"\n@using System.Diagnostics\n\n<PageTitle>Error</PageTitle>\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n@if (ShowRequestId)\n{\n    <p>\n        <strong>Request ID:</strong> <code>@RequestId</code>\n    </p>\n}\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n    It can result in displaying sensitive information from exceptions to end users.\n    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n    and restarting the app.\n</p>\n\n@code{\n    [CascadingParameter] private HttpContext? HttpContext { get; set; }\n\n    private string? RequestId { get; set; }\n    private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n\n    protected override void OnInitialized() =>\n        RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;\n\n}"
  },
  {
    "path": "Samples/BlazorApp/Components/Pages/Home.razor",
    "content": "﻿@page \"/\"\n\n<PageTitle>Home</PageTitle>\n\n<h1>Hello, world!</h1>\n\nWelcome to your new app."
  },
  {
    "path": "Samples/BlazorApp/Components/Pages/Page.cs",
    "content": "using BlazorApp.Effects;\nusing LanguageExt;\nusing Microsoft.AspNetCore.Components;\nusing static LanguageExt.Prelude;\n\nnamespace BlazorApp.Components.Pages;\n\npublic class Page : ComponentBase\n{\n    protected override async Task OnInitializedAsync() =>\n        (await OnInitialized().RunAsync(AppRuntime.Current!)).SafeError();\n\n    protected override async Task OnAfterRenderAsync(bool firstRender) => \n        (await OnAfterRender(firstRender).RunAsync(AppRuntime.Current!)).SafeError();\n\n    protected override async Task OnParametersSetAsync() => \n        (await OnParametersSet().RunAsync(AppRuntime.Current!)).SafeError();\n\n    public override async Task SetParametersAsync(ParameterView parameters) => \n        (await SetParameters(parameters).RunAsync(AppRuntime.Current!)).SafeError();\n    \n    protected new virtual Eff<Runtime, Unit> OnInitialized() =>\n        liftEff<Runtime, Unit>(async _ =>\n                               {\n                                   await base.OnInitializedAsync();\n                                   return unit;\n                               });\n    \n    protected new virtual Eff<Runtime, Unit> OnAfterRender(bool firstRender) =>\n        liftEff<Runtime, Unit>(async _ =>\n                               {\n                                   await base.OnAfterRenderAsync(firstRender);\n                                   return unit;\n                               });\n\n    protected new virtual Eff<Runtime, Unit> OnParametersSet() =>\n        liftEff<Runtime, Unit>(async _ =>\n                               {\n                                   await base.OnParametersSetAsync();\n                                   return unit;\n                               });\n    \n    protected new virtual Eff<Runtime, Unit> SetParameters(ParameterView parameters) =>\n        liftEff<Runtime, Unit>(async _ =>\n                               {\n                                   await base.SetParametersAsync(parameters);\n                                   return unit;\n                               });\n}\n"
  },
  {
    "path": "Samples/BlazorApp/Components/Pages/Weather.razor",
    "content": "﻿@page \"/weather\"\n@using BlazorApp.Data\n@using BlazorApp.Effects\n@using LanguageExt\n@using static LanguageExt.Prelude\n@attribute [StreamRendering]\n@inherits Page\n\n<PageTitle>Weather</PageTitle>\n<h1>Weather</h1>\n<p>This component demonstrates showing data.</p>\n\n@if (forecasts.IsEmpty)\n{\n    <p>\n        <em>Loading...</em>\n    </p>\n}\nelse\n{\n    <table class=\"table\">\n        <thead>\n        <tr>\n            <th>Date</th>\n            <th>Temp. (C)</th>\n            <th>Temp. (F)</th>\n            <th>Summary</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (var forecast in forecasts)\n        {\n            <tr>\n                <td>@forecast.Date.ToShortDateString()</td>\n                <td>@forecast.Temperature.Celsius</td>\n                <td>@forecast.Temperature.Fahrenheit</td>\n                <td>@forecast.Summary</td>\n            </tr>\n        }\n        </tbody>\n    </table>\n}\n\n@code {\n    AtomSeq<WeatherForecast> forecasts = AtomSeq<WeatherForecast>();\n\n    protected override Eff<Runtime, Unit> OnInitialized() =>\n        from fs in Control.Weather<Runtime>.forecastNextFiveDays\n        from _ in forecasts.SwapIO(_ => fs)\n        select unit;\n}"
  },
  {
    "path": "Samples/BlazorApp/Components/Routes.razor",
    "content": "﻿<Router AppAssembly=\"typeof(Program).Assembly\">\n    <Found Context=\"routeData\">\n        <RouteView RouteData=\"routeData\" DefaultLayout=\"typeof(Layout.MainLayout)\"/>\n        <FocusOnNavigate RouteData=\"routeData\" Selector=\"h1\"/>\n    </Found>\n</Router>"
  },
  {
    "path": "Samples/BlazorApp/Components/_Imports.razor",
    "content": "﻿@using System.Net.Http\n@using System.Net.Http.Json\n@using Microsoft.AspNetCore.Components.Forms\n@using Microsoft.AspNetCore.Components.Routing\n@using Microsoft.AspNetCore.Components.Web\n@using static Microsoft.AspNetCore.Components.Web.RenderMode\n@using Microsoft.AspNetCore.Components.Web.Virtualization\n@using Microsoft.JSInterop\n@using BlazorApp\n@using BlazorApp.Components"
  },
  {
    "path": "Samples/BlazorApp/Control/Weather.cs",
    "content": "using BlazorApp.Data;\nusing BlazorApp.Effects;\nusing BlazorApp.Effects.Interfaces;\nusing LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace BlazorApp.Control;\n\npublic static class Weather<RT>\n    where RT : \n        Has<Eff<RT>, TimeIO>, \n        Has<Eff<RT>, RndIO>\n{\n    /// <summary>\n    /// Some example summaries\n    /// </summary>\n    static readonly Seq<string> summaries =\n        [\"Freezing\", \"Bracing\", \"Chilly\", \"Cool\", \"Mild\", \"Warm\", \"Balmy\", \"Hot\", \"Sweltering\", \"Scorching\"];\n\n    /// <summary>\n    /// Get the next five-days weather forecast\n    /// </summary>\n    public static Eff<RT, Seq<WeatherForecast>> forecastNextFiveDays =>\n        from d in dateNow\n        from f in Range(1, 5).AsIterable()\n                             .Map(d.AddDays)\n                             .Traverse(forecast)\n        select toSeq(f);          \n\n    /// <summary>\n    /// Gets a weather forecast for a given date\n    /// </summary>\n    public static Eff<RT, WeatherForecast> forecast(DateOnly date) =>\n        from t in randomTemperature\n        from s in randomSummary\n        select new WeatherForecast(date, t, s);\n\n    /// <summary>\n    /// Get the date now\n    /// </summary>\n    static Eff<RT, DateOnly> dateNow =>\n        Time<RT>.now.Map(DateOnly.FromDateTime).As();\n    \n    /// <summary>\n    /// Generate a random temperature between -20 and 55 degrees celsius\n    /// </summary>\n    static Eff<RT, Temperature> randomTemperature =>\n        Rnd<RT>.next(-20, 55).Map(c => c.Celsius()).As();\n\n    /// <summary>\n    /// Generate a random summary\n    /// </summary>\n    static Eff<RT, string> randomSummary =>\n        Rnd<RT>.next(summaries.Length).Map(ix => summaries[ix]).As();\n}\n"
  },
  {
    "path": "Samples/BlazorApp/Data/WeatherForecast.cs",
    "content": "using LanguageExt;\n\nnamespace BlazorApp.Data;\n\n/// <summary>\n/// Weather forecast data\n/// </summary>\n/// <param name=\"Date\">Date</param>\n/// <param name=\"Temperature\">Temperature for the day</param>\n/// <param name=\"Summary\">Summary text</param>\npublic record WeatherForecast(\n    DateOnly Date, \n    Temperature Temperature, \n    string Summary);\n"
  },
  {
    "path": "Samples/BlazorApp/Effects/AppRuntime.cs",
    "content": "namespace BlazorApp.Effects;\n\npublic static class AppRuntime\n{\n    /// <summary>\n    /// This will always point to the same runtime in this example, but it should be relatively\n    /// obvious that switching this to a test-runtime, or any alternative with different effects\n    /// implementations is how you would do mocking or DI.\n    ///\n    /// There may well be a more elegant way to make the runtime available to the Razor pages, but\n    /// I have zero experience with Razer/Blazor, so I haven't figured it out yet.  If you know,\n    /// please let me know in the repo Discussions.  Thanks! \n    /// </summary>\n    public static Runtime? Current;\n}\n"
  },
  {
    "path": "Samples/BlazorApp/Effects/Impl/RndImpl.cs",
    "content": "using BlazorApp.Effects.Interfaces;\n\nnamespace BlazorApp.Effects.Impl;\n\npublic class RndImpl : RndIO\n{\n    public static readonly RndIO Default = new RndImpl();\n    \n    public int Next(int min, int max) => \n        Random.Shared.Next(min, max);\n\n    public int Next(int max) => \n        Random.Shared.Next(max);\n}\n"
  },
  {
    "path": "Samples/BlazorApp/Effects/Interfaces/RndIO.cs",
    "content": "namespace BlazorApp.Effects.Interfaces;\n\npublic interface RndIO\n{\n    /// <summary>\n    /// Get a random integer between min and max, inclusive.\n    /// </summary>\n    int Next(int min, int max);\n    \n    /// <summary>\n    /// Get a random integer up to max, inclusive.\n    /// </summary>\n    int Next(int max);    \n}\n\n"
  },
  {
    "path": "Samples/BlazorApp/Effects/Rnd.cs",
    "content": "using BlazorApp.Effects.Interfaces;\nusing LanguageExt;\nusing LanguageExt.Traits;\n\nnamespace BlazorApp.Effects;\n\npublic static class Rnd<M, RT>\n    where M : MonadIO<M>\n    where RT : Has<M, RndIO>\n{\n    static readonly K<M, RndIO> trait = Has<M, RT, RndIO>.ask;\n\n    /// <summary>\n    /// Get a random integer between min and max, inclusive.\n    /// </summary>\n    public static K<M, int> next(int min, int max) =>\n        trait.Map(t => t.Next(min, max));\n    \n    /// <summary>\n    /// Get a random integer up to max, inclusive.\n    /// </summary>\n    public static K<M, int> next(int max) =>\n        trait.Map(t => t.Next(max));\n}\n\n\npublic static class Rnd<RT>\n    where RT : Has<Eff<RT>, RndIO>\n{\n    /// <summary>\n    /// Get a random integer between min and max, inclusive.\n    /// </summary>\n    public static Eff<RT, int> next(int min, int max) =>\n        +Rnd<Eff<RT>, RT>.next(min, max);\n    \n    /// <summary>\n    /// Get a random integer up to max, inclusive.\n    /// </summary>\n    public static Eff<RT, int> next(int max) =>\n        +Rnd<Eff<RT>, RT>.next(max);\n}\n\n"
  },
  {
    "path": "Samples/BlazorApp/Effects/Runtime.cs",
    "content": "using BlazorApp.Effects.Interfaces;\nusing LanguageExt;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace BlazorApp.Effects;\n\n/// <summary>\n/// Concrete runtime for this project\n/// </summary>\npublic record Runtime(RuntimeInterfaces Interfaces) : \n    Has<Eff<Runtime>, TimeIO>,\n    Has<Eff<Runtime>, RndIO>\n{\n    public Runtime(TimeIO timeIO, RndIO rndIO) :\n        this(new RuntimeInterfaces(timeIO, rndIO)){}\n\n    static K<Eff<Runtime>, TimeIO> Has<Eff<Runtime>, TimeIO>.Ask { get; } =\n        liftEff<Runtime, TimeIO>(rt => rt.Interfaces.TimeIO);\n        \n    static K<Eff<Runtime>, RndIO> Has<Eff<Runtime>, RndIO>.Ask { get; } =\n        liftEff<Runtime, RndIO>(rt => rt.Interfaces.RndIO);\n}\n\npublic record RuntimeInterfaces(TimeIO TimeIO, RndIO RndIO);\n"
  },
  {
    "path": "Samples/BlazorApp/Effects/SafeErrorExtensions.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\n\nnamespace BlazorApp.Effects;\n\npublic static class SafeErrorExtensions\n{\n    /// <summary>\n    /// Catch exceptional errors and make them safe errors by wrapping up the exception\n    /// in an `Inner` property and returning with 'There was an error' as the message. \n    /// </summary>\n    /// <param name=\"ma\"></param>\n    /// <typeparam name=\"M\"></typeparam>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    public static K<M, A> SafeError<M, A>(this K<M, A> ma)\n        where M : Fallible<M> =>\n        ma.Catch(e => e.IsExceptional, e => Error.New(\"There was an error\", e));\n}\n"
  },
  {
    "path": "Samples/BlazorApp/Program.cs",
    "content": "using BlazorApp.Components;\nusing BlazorApp.Effects;\nusing BlazorApp.Effects.Impl;\n\n// Set a default runtime for the app\nAppRuntime.Current = new Runtime(\n    LanguageExt.Sys.Live.Implementations.TimeIO.Default,\n    RndImpl.Default\n    );  \n\nvar builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\nbuilder.Services\n       .AddRazorComponents()\n       .AddInteractiveServerComponents();\n\nvar app = builder.Build();\n\n// Configure the HTTP request pipeline.\nif (!app.Environment.IsDevelopment())\n{\n    app.UseExceptionHandler(\"/Error\", createScopeForErrors: true);\n    app.UseHsts();\n}\n\napp.UseHttpsRedirection();\n\napp.UseStaticFiles();\napp.UseAntiforgery();\n\napp.MapRazorComponents<App>()\n   .AddInteractiveServerRenderMode();\n\napp.Run();\n"
  },
  {
    "path": "Samples/BlazorApp/Properties/launchSettings.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/launchsettings.json\",\n    \"iisSettings\": {\n      \"windowsAuthentication\": false,\n      \"anonymousAuthentication\": true,\n      \"iisExpress\": {\n        \"applicationUrl\": \"http://localhost:58079\",\n        \"sslPort\": 44315\n      }\n    },\n    \"profiles\": {\n      \"http\": {\n        \"commandName\": \"Project\",\n        \"dotnetRunMessages\": true,\n        \"launchBrowser\": true,\n        \"applicationUrl\": \"http://localhost:5124\",\n        \"environmentVariables\": {\n          \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n        }\n      },\n      \"https\": {\n        \"commandName\": \"Project\",\n        \"dotnetRunMessages\": true,\n        \"launchBrowser\": true,\n        \"applicationUrl\": \"https://localhost:7126;http://localhost:5124\",\n        \"environmentVariables\": {\n          \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n        }\n      },\n      \"IIS Express\": {\n        \"commandName\": \"IISExpress\",\n        \"launchBrowser\": true,\n        \"environmentVariables\": {\n          \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n        }\n      }\n    }\n  }\n"
  },
  {
    "path": "Samples/BlazorApp/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "Samples/BlazorApp/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "Samples/BlazorApp/wwwroot/app.css",
    "content": "html, body {\n    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n}\n\na, .btn-link {\n    color: #006bb7;\n}\n\n.btn-primary {\n    color: #fff;\n    background-color: #1b6ec2;\n    border-color: #1861ac;\n}\n\n.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {\n  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;\n}\n\n.content {\n    padding-top: 1.1rem;\n}\n\nh1:focus {\n    outline: none;\n}\n\n.valid.modified:not([type=checkbox]) {\n    outline: 1px solid #26b050;\n}\n\n.invalid {\n    outline: 1px solid #e50000;\n}\n\n.validation-message {\n    color: #e50000;\n}\n\n.blazor-error-boundary {\n    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;\n    padding: 1rem 1rem 1rem 3.7rem;\n    color: white;\n}\n\n    .blazor-error-boundary::after {\n        content: \"An error has occurred.\"\n    }\n\n.darker-border-checkbox.form-check-input {\n    border-color: #929292;\n}\n"
  },
  {
    "path": "Samples/CardGame/Card.cs",
    "content": "using LanguageExt;\n\nnamespace CardGame;\n\n/// <summary>\n/// Simple card type. Contains an index that can be converted to a textual\n/// representation of the card.\n/// </summary>\npublic record Card(int Index)\n{\n    public string Name =>\n        (Index % 13) switch\n        {\n            0      => \"Ace\",\n            10     => \"Jack\",\n            11     => \"Queen\",\n            12     => \"King\",\n            var ix => $\"{ix + 1}\"\n        };\n    \n    public string Suit =>\n        Index switch\n        {\n            < 13 => \"Hearts\",\n            < 26 => \"Clubs\",\n            < 39 => \"Spades\",\n            < 52 => \"Diamonds\",\n            _    => throw new NotSupportedException()\n        };\n\n    public override string ToString() =>\n        $\"{Name} of {Suit}\";\n    \n    public Seq<int> FaceValues =>\n        (Index % 13) switch\n        {\n            0     => [1, 11],    // Ace\n            10    => [10],       // Jack\n            11    => [10],       // Queen\n            12    => [10],       // King   \n            var x => [x + 1]\n        };\n}\n"
  },
  {
    "path": "Samples/CardGame/CardGame.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n      <ProjectReference Include=\"..\\..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Samples/CardGame/Console.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace CardGame;\n\n/// <summary>\n/// Simple IO wrappers of Console \n/// </summary>\npublic static class Console\n{\n    public static IO<Unit> emptyLine =>\n        lift(System.Console.WriteLine);\n\n    public static IO<Unit> writeLine(string line) =>\n        lift(() => System.Console.WriteLine(line));\n\n    public static IO<string> readLine =>\n        lift(System.Console.ReadLine).Map(ln => ln ?? \"\");\n\n    public static IO<ConsoleKeyInfo> readKey =>\n        IO.lift(System.Console.ReadKey) >> emptyLine;\n}\n"
  },
  {
    "path": "Samples/CardGame/Deck.cs",
    "content": "using LanguageExt;\nusing LanguageExt.UnsafeValueAccess;\nusing static LanguageExt.Prelude;\n\nnamespace CardGame;\n\n/// <summary>\n/// Deck of cards\n/// </summary>\npublic record Deck(Seq<Card> Cards)\n{\n    public static Deck Empty = new ([]);\n\n    /// <summary>\n    /// Generate a randomly shuffled deck of cards \n    /// </summary>\n    public static Game<Unit> shuffle =>\n        from deck in generate\n        from _    in put(deck)\n        select unit;\n\n    /// <summary>\n    /// Get the deck from the game-state\n    /// </summary>\n    public static Game<Deck> deck =>\n        Game.gets(g => g.Deck);\n\n    /// <summary>\n    /// Return the number of cards remaining in the deck \n    /// </summary>\n    public static Game<int> cardsRemaining =>\n        deck.Map(d => d.Cards.Count);\n\n    /// <summary>\n    /// Deal a card from the deck\n    /// </summary>\n    /// <remarks>When the cards are exhausted the game will cancel</remarks>\n    public static Game<Card> deal =>\n        from d in deck\n        from x in when(d.Cards.IsEmpty, Display.deckFinished) \n        from c in Game.lift(d.Cards.Head)\n        from _ in put(new Deck(d.Cards.Tail))\n        select c;\n\n    /// <summary>\n    /// Update the deck \n    /// </summary>\n    public static Game<Unit> put(Deck deck) =>\n        Game.modify(g => g with { Deck = deck });\n    \n    /// <summary>\n    /// Generate a randomly shuffled deck of cards\n    /// </summary>\n    static IO<Deck> generate =>\n        IO.lift(() =>\n        {\n            var random = new Random((int)DateTime.Now.Ticks);\n            var array  = LanguageExt.List.generate(52, ix => new Card(ix)).ToArray();\n            random.Shuffle(array);\n            return new Deck(array.ToSeqUnsafe());\n        });\n\n    public override string ToString() =>\n        Cards.ToFullArrayString();\n}\n"
  },
  {
    "path": "Samples/CardGame/Display.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace CardGame;\n\n/// <summary>\n/// UI messages\n/// </summary>\npublic static class Display\n{\n    public static readonly Game<Unit> introduction =\n        Console.writeLine(\"Let's play...\");\n\n    public static readonly Game<Unit> askPlayerNames =\n        Console.writeLine(\"Enter a player name, or just press enter complete\");\n    \n    public static readonly Game<Unit> askPlayAgain =\n        Console.writeLine(\"Play again (Y/N)\");\n    \n    public static readonly Game<Unit> deckFinished =\n        Console.writeLine(\"The deck is out of cards\");\n    \n    public static readonly Game<Unit> cardsRemaining =\n        Deck.cardsRemaining.Bind(remain => Console.writeLine($\"{remain} cards remaining in the deck\"));\n\n    public static readonly Game<Unit> bust =\n        Console.writeLine(\"\\tBust!\");\n\n    public static Game<Unit> playerExists(string name) =>\n        Console.writeLine($\"Player '{name}' already exists\") >>\n        Console.writeLine(\"Please pick a unique name\");\n\n    public static Game<Unit> playerAdded(string name) =>\n        Console.writeLine($\"'{name}' added to the game\");\n\n    public static Game<Unit> playerStates(Seq<(Player Player, PlayerState State)> players) =>\n        players.Traverse(p => playerState(p.Player, p.State)).Map(_ => unit).As();\n\n    public static Game<Unit> playerState(Player player, PlayerState state) =>\n        state.StickState\n            ? Console.writeLine($\"{player.Name} {state.Cards}, possible scores {state.Scores} [STICK]\")\n            : Console.writeLine($\"{player.Name} {state.Cards}, possible scores {state.Scores}\");\n\n    public static Game<Unit> winners(Seq<(Player Player, int Score)> winners) =>\n        winners switch\n        {\n            []      => everyoneIsBust,\n            [var p] => Console.writeLine($\"{p.Player.Name} is the winner with {p.Score}!\"),\n            var ps  => Console.writeLine($\"{ps.Map(p => p.Player.Name).ToFullString()} have won with {ps[0].Score}!\")\n        };\n\n    public static Game<Unit> everyoneIsBust =>\n        Console.writeLine(\"Everyone's bust!\");\n    \n    public static readonly Game<Unit> askStickOrTwist =\n        Player.current.Bind(player => Console.writeLine($\"{player.Name}, stick or twist? (S/T)\"));\n    \n    public static readonly Game<Unit> stickOrTwistBerate =\n        Console.writeLine(\"'S' key for stick, 'T' for twist!\");\n\n    public static Game<Unit> showCard(Card card) =>\n        Console.writeLine($\"\\t{card}\");\n\n    public static Game<Unit> showCardsAndScores(Seq<Card> cards, Seq<int> scores, int highScore) =>\n        Console.writeLine($\"\\t{cards}, possible scores {scores}, high-score: {highScore}\");\n}\n"
  },
  {
    "path": "Samples/CardGame/Game.Monad/Game.Extensions.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Traits;\nnamespace CardGame;\n\npublic static class GameExtensions\n{\n    extension<A>(K<Game, A> ma)\n    {\n        public Game<A> As() =>\n            (Game<A>)ma;\n\n        /// <summary>\n        /// Run the Game transformer down to the IO monad\n        /// </summary>\n        public IO<Option<(A Value, GameState State)>> Run(GameState state) =>\n            ma.As().runGame.Run(state).As().Run().As();\n\n        public Game<C> SelectMany<B, C>(Func<A, K<Game, B>> bind, Func<A, B, C> project) =>\n            ma.As().SelectMany(bind, project);\n        \n        public static Game<A> operator + (K<Game, A> lhs) =>\n            (Game<A>)lhs;\n        \n        public static Game<A> operator >> (K<Game, A> lhs, Lower _) =>\n            (Game<A>)lhs;\n    }\n\n    public static Game<C> SelectMany<A, B, C>(\n        this K<IO, A> ma,\n        Func<A, K<Game, B>> bind,\n        Func<A, B, C> project) =>\n        MonadIO.liftIO<Game, A>(ma.As()).SelectMany(bind, project); \n\n    public static Game<C> SelectMany<A, B, C>(\n        this IO<A> ma,\n        Func<A, K<Game, B>> bind,\n        Func<A, B, C> project) =>\n        MonadIO.liftIO<Game, A>(ma).SelectMany(bind, project); \n\n    public static Game<C> SelectMany<A, B, C>(\n        this Pure<A> ma,\n        Func<A, K<Game, B>> bind,\n        Func<A, B, C> project) =>\n        Game.Pure(ma.Value).SelectMany(bind, project);\n}\n"
  },
  {
    "path": "Samples/CardGame/Game.Monad/Game.Module.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\nnamespace CardGame;\n\npublic partial class Game\n{\n    public static Game<A> Pure<A>(A value) =>\n        Game<A>.Pure(value);\n    \n    /// <summary>\n    /// Cached unit returning Game monad\n    /// </summary>\n    public static readonly Game<Unit> unitM = \n        Game<Unit>.Pure(unit);\n\n    /// <summary>\n    /// Use this to cancel the game\n    /// </summary>\n    /// <remarks>Represents a None state in the embedded OptionT transformer.</remarks>\n    public static readonly Game<Unit> cancel =\n        lift(Option<Unit>.None);\n    \n    /// <summary>\n    /// Get the game-state\n    /// </summary>\n    public static Game<GameState> state =>\n        new (StateT.get<OptionT<IO>, GameState>());\n\n    /// <summary>\n    /// Return true if the game is still active\n    /// </summary>\n    public static Game<bool> isGameActive =>\n        from non in nonActivePlayersState\n        from res in non.Exists(p => p.State.Has21 || p.State.StickState)\n                        ? activePlayersState.Map(ps => ps.Count > 0)\n                        : activePlayersState.Map(ps => ps.Count > 1)\n        select res;\n    \n    /// <summary>\n    /// The current high-score\n    /// </summary>\n    public static Game<int> currentHighScore =>\n        playersState.Map(ps => ps.Filter(p => !p.State.IsBust)\n                                 .Choose(p => p.State.MaximumNonBustScore)\n                                 .Max(0));\n\n    /// <summary>\n    /// Get the player's state from the StateT monad-transformer\n    /// </summary>\n    public static Game<Seq<(Player Player, PlayerState State)>> playersState =>\n        state.Map(s => s.State).Map(gs => gs.AsIterable().ToSeq());\n\n    /// <summary>\n    /// Get the player's that are still playing\n    /// </summary>\n    public static Game<Seq<(Player Player, PlayerState State)>> activePlayersState =>\n        playersState.Map(ps => ps.Filter(p => p.State.StillInTheGame()));\n\n    /// <summary>\n    /// Get the player's that are still playing\n    /// </summary>\n    public static Game<Seq<(Player Player, PlayerState State)>> nonActivePlayersState =>\n        playersState.Map(ps => ps.Filter(p => !p.State.StillInTheGame()));\n\n    /// <summary>\n    /// Get the list of players from the StateT monad-transformer\n    /// </summary>\n    public static Game<Seq<Player>> players =>\n        playersState.Map(ps => ps.Map(p => p.Player));\n\n    /// <summary>\n    /// Get the player's that are still playing\n    /// </summary>\n    public static Game<Seq<Player>> activePlayers =>\n        activePlayersState.Map(ps => ps.Map(p => p.Player).Strict());\n\n    /// <summary>\n    /// Initialise the player's state\n    /// </summary>\n    public static Game<Unit> initPlayers =>\n        modifyPlayers(kv => kv.Map(_ => PlayerState.Zero));\n\n    /// <summary>\n    /// Return the winners of the game (there may be multiple winners!)\n    /// </summary>\n    public static Game<Seq<(Player Player, int Score)>> winners =>\n        from ps in playersState\n        select ps.Choose(p => p.State.MaximumNonBustScore.Map(score => (p.Player, Score: score)))\n                 .OrderByDescending(p => p.Score)\n                 .Select(Seq)\n                 .Reduce((ss, sp) => (from s in ss\n                                      from p in sp\n                                      select s.Score == p.Score).ForAll(x => x)\n                                         ? ss + sp\n                                         : ss);\n    \n    /// <summary>\n    /// Discover if a player exists\n    /// </summary>\n    public static Game<bool> playerExists(string name) =>\n        playerExists(new Player(name));\n\n    /// <summary>\n    /// Discover if a player exists\n    /// </summary>\n    public static Game<bool> playerExists(Player player) =>\n        state.Map(s => s.State)\n             .Map(s => s.Find(player).IsSome);\n\n    /// <summary>\n    /// Add a player to the game\n    /// </summary>\n    public static Game<Unit> addPlayer(string name) =>\n        iff(playerExists(name),\n            Then: Display.playerExists(name),\n            Else: from _1 in modifyPlayers(s => s.Add(new Player(name), PlayerState.Zero))\n                  from _2 in Display.playerAdded(name)\n                  select unit)\n           .As();\n\n    /// <summary>\n    /// Lazy wrapper\n    /// </summary>\n    public static Game<A> lazy<A>(Func<Game<A>> f) =>\n        unitM.Bind(_ => f());\n    \n    /// <summary>\n    /// Lift an option into the Game - None will cancel the game\n    /// </summary>\n    public static Game<A> lift<A>(Option<A> ma) =>\n        Game<A>.Lift(ma);\n    \n    /// <summary>\n    /// Lift an IO operation into the Game\n    /// </summary>\n    public static Game<A> liftIO<A>(IO<A> ma) => \n        Game<A>.LiftIO(ma);\n\n    /// <summary>\n    /// Map the game state to a new value\n    /// </summary>\n    public static Game<A> gets<A>(Func<GameState, A> f) =>\n        new (StateT.gets<OptionT<IO>, GameState, A>(f));\n    \n    /// <summary>\n    /// Map the game state to a new value and update it in the monad\n    /// </summary>\n    public static Game<Unit> modify(Func<GameState, GameState> f) =>\n        new (StateT.modify<OptionT<IO>, GameState>(f));\n    \n    /// <summary>\n    /// Modify the player map\n    /// </summary>\n    public static Game<Unit> modifyPlayers(Func<HashMap<Player, PlayerState>, HashMap<Player, PlayerState>> f) =>\n        modify(s => s with { State = f(s.State) });\n}\n"
  },
  {
    "path": "Samples/CardGame/Game.Monad/Game.Monad.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Traits;\nnamespace CardGame;\n\npublic partial class Game :\n    Deriving.Monad<Game, StateT<GameState, OptionT<IO>>>,\n    Deriving.Stateful<Game, StateT<GameState, OptionT<IO>>, GameState>,\n    MonadIO<Game>\n{\n    public static K<StateT<GameState, OptionT<IO>>, A> Transform<A>(K<Game, A> fa) =>\n        fa.As().runGame;\n\n    public static K<Game, A> CoTransform<A>(K<StateT<GameState, OptionT<IO>>, A> fa) => \n        new Game<A>(fa.As());\n\n    public static K<Game, A> LiftIO<A>(IO<A> ma) => \n        new Game<A>(StateT.liftIO<GameState, OptionT<IO>, A>(ma));\n}\n"
  },
  {
    "path": "Samples/CardGame/Game.Monad/Game.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Traits;\n\nnamespace CardGame;\n\npublic record Game<A>(StateT<GameState, OptionT<IO>, A> runGame) : K<Game, A>\n{\n    public static Game<A> Pure(A x) =>\n        new(StateT<GameState, OptionT<IO>, A>.Pure(x));\n    \n    public static Game<A> None =>\n        new(StateT<GameState, OptionT<IO>, A>.Lift(OptionT.None<IO, A>()));\n    \n    public static Game<A> Lift(Option<A> mx) =>\n        new(StateT<GameState, OptionT<IO>, A>.Lift(OptionT.lift<IO, A>(mx)));\n    \n    public static Game<A> LiftIO(IO<A> mx) =>\n        new(StateT<GameState, OptionT<IO>, A>.LiftIO(mx));\n    \n    public Game<B> Map<B>(Func<A, B> f) =>\n        this.Kind().Map(f).As();\n    \n    public Game<B> Select<B>(Func<A, B> f) =>\n        this.Kind().Map(f).As();\n    \n    public Game<B> Bind<B>(Func<A, K<Game, B>> f) =>\n        this.Kind().Bind(f).As();\n    \n    public Game<B> Bind<B>(Func<A, IO<B>> f) =>\n        this.Kind().Bind(f).As();\n\n    public Game<C> SelectMany<B, C>(Func<A, K<Game, B>> bind, Func<A, B, C> project) =>\n        Bind(a => bind(a).Map(b => project(a, b)));\n\n    public Game<C> SelectMany<B, C>(Func<A, IO<B>> bind, Func<A, B, C> project) =>\n        SelectMany(a => MonadIO.liftIO<Game, B>(bind(a)), project);\n\n    public Game<C> SelectMany<B, C>(Func<A, K<IO, B>> bind, Func<A, B, C> project) =>\n        SelectMany(a => MonadIO.liftIO<Game, B>(bind(a).As()), project);\n\n    public Game<C> SelectMany<B, C>(Func<A, Pure<B>> bind, Func<A, B, C> project) =>\n        Map(a => project(a, bind(a).Value));\n\n    public static implicit operator Game<A>(Pure<A> ma) =>\n        Pure(ma.Value);\n\n    public static implicit operator Game<A>(IO<A> ma) =>\n        Game.liftIO(ma);\n\n    public static implicit operator Game<A>(Option<A> ma) =>\n        Game.lift(ma);\n\n    /*\n    public static Game<A> operator >>(Game<A> ma, K<Game, A> mb) =>\n        ma.Bind(_ => mb);\n\n    public static Game<A> operator >>(Game<A> ma, K<Game, Unit> mb) =>\n        ma.Bind(x => mb.Map(_ => x));\n\n    public static Game<A> operator >>(Game<A> ma, K<IO, A> mb) =>\n        ma.Bind(_ => mb.As());\n\n    public static Game<A> operator >>(Game<A> ma, K<IO, Unit> mb) =>\n        ma.Bind(x => mb.As().Map(_ => x));*/\n}\n"
  },
  {
    "path": "Samples/CardGame/Game.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace CardGame;\n\n/// <summary>\n/// Pontoon / Vingt-Un / 21\n/// </summary>\npublic partial class Game\n{\n    /// <summary>\n    /// Play the game!\n    /// </summary>\n    public static Game<Unit> play =>\n        Display.askPlayerNames >>\n        enterPlayerNames       >>\n        Display.introduction   >>\n        Deck.shuffle           >>\n        playHands              >>\n        lower;\n\n    /// <summary>\n    /// Ask the users to enter their names until `enterPlayerName` returns `false`\n    /// </summary>\n    static Game<Unit> enterPlayerNames =>\n        +when(enterPlayerName, lazy(() => enterPlayerNames));\n\n    /// <summary>\n    /// Wait for the user to enter the name of a player, then add them to the game \n    /// </summary>\n    static Game<bool> enterPlayerName =>\n        from name in Console.readLine\n        from _    in when(notEmpty(name), addPlayer(name))\n        select notEmpty(name);\n\n    /// <summary>\n    /// Play many hands until the players decide to quit\n    /// </summary>\n    static Game<Unit> playHands =>\n        from _   in initPlayers >>\n                    playHand >>\n                    Display.askPlayAgain\n        from key in Console.readKey\n        from __  in when(key.Key == ConsoleKey.Y, playHands)\n        select unit;\n\n    /// <summary>\n    /// Play a single hand\n    /// </summary>\n    static Game<Unit> playHand =>\n        dealHands              >>\n        playRound              >>\n        gameOver               >>\n        Display.cardsRemaining >>\n        lower;\n\n    /// <summary>\n    /// Deal the initial cards to the players\n    /// </summary>\n    static Game<Unit> dealHands =>\n        Players.with(players, dealHand);\n\n    /// <summary>\n    /// Deal the two initial cards to a player\n    /// </summary>\n    static Game<Unit> dealHand =>\n        from cs     in dealCard >> dealCard\n        from player in Player.current\n        from state  in Player.state\n        from _      in Display.playerState(player, state)\n        select unit;\n\n    /// <summary>\n    /// Deal a single card\n    /// </summary>\n    static Game<Unit> dealCard =>\n        Deck.deal      >>\n        Player.addCard >>\n        lower;\n    \n    /// <summary>\n    /// For each active player, check if they want to stick or twist\n    /// Keep looping until the game ends\n    /// </summary>\n    static Game<Unit> playRound =>\n        when(isGameActive,\n             from _ in Players.with(activePlayers, stickOrTwist) \n             from r in playRound\n             select r)\n            .As();\n\n    /// <summary>\n    /// Ask the player if they want to stick or twist, then follow their instruction\n    /// </summary>\n    static Game<Unit> stickOrTwist =>\n        when(isGameActive,\n             from _      in Display.askStickOrTwist >>\n                            Player.showCards\n             from key    in Console.readKey\n             from __     in key.Key switch\n                            {\n                                ConsoleKey.S => Player.stick,\n                                ConsoleKey.T => twist,\n                                _            => stickOrTwistBerate\n                            }\n             select unit)\n           .As();\n\n    /// <summary>\n    /// Player wants to twist\n    /// </summary>\n    static Game<Unit> twist =>\n        from card in Deck.deal\n        from _    in Player.addCard(card) >>\n                     Display.showCard(card) >>\n                     when(Player.isBust, Display.bust)\n        select unit;\n\n    /// <summary>\n    /// Berate the user for not following instructions!\n    /// </summary>\n    static K<Game, Unit> stickOrTwistBerate =>\n        Display.stickOrTwistBerate >>\n        stickOrTwist;\n\n    /// <summary>\n    /// Show the game over summary\n    /// </summary>\n    static Game<Unit> gameOver =>\n        from ws in winners\n        from ps in playersState\n        from _  in Display.winners(ws) >>\n                   Display.playerStates(ps)\n        select unit;\n}\n"
  },
  {
    "path": "Samples/CardGame/GameState.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace CardGame;\n\n/// <summary>\n/// The game's internal state\n/// </summary>\npublic record GameState(HashMap<Player, PlayerState> State, Deck Deck, Option<Player> CurrentPlayer)\n{\n    public static readonly GameState Zero = new ([], Deck.Empty, None);\n}\n"
  },
  {
    "path": "Samples/CardGame/Player.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace CardGame;\n\npublic record Player(string Name)\n{\n    public override string ToString() => \n        Name;\n\n    /// <summary>\n    /// Run a computation in a `Player` local context \n    /// </summary>\n    /// <param name=\"player\"></param>\n    /// <param name=\"ma\"></param>\n    /// <typeparam name=\"A\"></typeparam>\n    /// <returns></returns>\n    public static Game<A> with<A>(Player player, Game<A> ma) =>\n        from cp in Game.gets(s => s.CurrentPlayer)\n        from _1 in setCurrent(player)\n        from rs in ma >> setCurrent(cp)\n        select rs;\n\n    /// <summary>\n    /// Get the current player.  If there isn't one, then `Game.cancel` is raised\n    /// </summary>\n    public static Game<Player> current =>\n        from p in Game.gets(s => s.CurrentPlayer)\n        from r in Game.lift(p)\n        select r;\n\n    /// <summary>\n    /// Set the current player\n    /// </summary>\n    public static Game<Unit> setCurrent(Player player) =>\n        Game.modify(s => s with { CurrentPlayer = player }).As();\n\n    /// <summary>\n    /// Set the current player\n    /// </summary>\n    public static Game<Unit> setCurrent(Option<Player> player) =>\n        Game.modify(s => s with { CurrentPlayer = player }).As();\n    \n    /// <summary>\n    /// Get a player's state from the StateT monad-transformer\n    /// </summary>\n    public static Game<PlayerState> state =>\n        from pl in current\n        from s1 in Game.state.Map(s => s.State)\n        from s2 in Game.lift(s1.Find(pl))\n        select s2;\n\n    /// <summary>\n    /// Show the player's cards\n    /// </summary>\n    public static Game<Unit> showCards =>\n        from state in state\n        from score in Game.currentHighScore\n        from cards in Display.showCardsAndScores(state.Cards, state.Scores, score)\n        select unit;\n\n    /// <summary>\n    /// Modify a player's game-state stored in the StateT monad-transformer\n    /// </summary>\n    static Game<Unit> modify(\n        Func<PlayerState, PlayerState> f) =>\n        from p in current\n        from s in state\n        from _ in Game.modifyPlayers(s1 => s1.SetItem(p, f(s)))\n        select unit;\n    \n    /// <summary>\n    /// Add a card to a player's state\n    /// </summary>\n    public static Game<Unit> addCard(Card card) =>\n        modify(p => p.AddCard(card));\n\n    /// <summary>\n    /// Set a player's state to stick\n    /// </summary>\n    public static Game<Unit> stick =>\n        modify(p => p.Stick());\n\n    /// <summary>\n    /// Gets whether the player is bust or not\n    /// </summary>\n    public static Game<bool> isBust =>\n        state.Map(p => p.IsBust);\n}\n"
  },
  {
    "path": "Samples/CardGame/PlayerState.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace CardGame;\n\n/// <summary>\n/// Holds a running sequence of dealt cards and the stick-status\n/// </summary>\npublic record PlayerState(Seq<Card> Cards, bool StickState)\n{\n    public static readonly PlayerState Zero = new ([], false);\n\n    public PlayerState AddCard(Card card) =>\n        this with { Cards = Cards.Add(card) };\n    \n    public PlayerState Stick() =>\n        this with { StickState = true };\n\n    public Seq<int> Scores =>\n        Cards.Map(c => c.FaceValues)\n             .Fold(Seq(Seq<int>()),\n                   (s, vs) =>\n                       from x in s\n                       from v in vs\n                       select x.Add(v))\n             .Map(s => s.Sum<Seq, int>())\n             .Distinct() \n             .OrderBy(s => s)\n             .AsIterable()\n             .ToSeq();\n\n    public bool StillInTheGame() =>\n        !Scores.Exists(s => s == 21) && \n        !StickState && \n        !IsBust;\n\n    public Option<int> MaximumNonBustScore =>\n        Scores.Filter(s => s <= 21).Last;\n\n    public bool Has21 =>\n        Scores.Exists(s => s == 21);\n\n    public bool IsBust =>\n        Scores.ForAll(s => s > 21);\n}\n"
  },
  {
    "path": "Samples/CardGame/Players.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\nnamespace CardGame;\n\n/// <summary>\n/// Bulk management of players\n/// </summary>\npublic static class Players\n{\n    /// <summary>\n    /// For each player in a collection of players:\n    ///\n    ///     * Make into the current player\n    ///     * Rub the  `ma` computation in that context\n    ///     * Reset the current player\n    /// </summary>\n    /// <returns>\n    /// Ignores the results\n    /// </returns>\n    public static Game<Unit> with<A>(Game<Seq<Player>> playersM, Game<A> ma) =>\n        playersM.Bind(ps => with(ps, ma))\n                .IgnoreF()\n                .As();\n    \n    /// <summary>\n    /// For each player in a collection of players:\n    ///\n    ///     * Make into the current player\n    ///     * Rub the  `ma` computation in that context\n    ///     * Reset the current player\n    ///\n    /// Return a sequence of results, one for each player\n    /// </summary>\n    public static Game<Unit> with<A>(Seq<Player> players, Game<A> ma) =>\n        players.TraverseM(p => Player.with(p, ma))\n               .Map(_ => unit)\n               .As();\n    \n    /// <summary>\n    /// For each player in a collection of players:\n    ///\n    ///     * Make into the current player\n    ///     * Rub the  `ma` computation in that context\n    ///     * Reset the current player\n    ///\n    /// </summary>\n    /// <returns>\n    /// Return a sequence of results, one for each player\n    /// </returns>\n    public static Game<Seq<A>> map<A>(Game<Seq<Player>> playersM, Game<A> ma) =>\n        playersM.Bind(ps => map(ps, ma));\n    \n    /// <summary>\n    /// For each player in a collection of players:\n    ///\n    ///     * Make into the current player\n    ///     * Rub the  `ma` computation in that context\n    ///     * Reset the current player\n    ///\n    /// </summary>\n    /// <returns>\n    /// Return a sequence of results, one for each player\n    /// </returns>\n    public static Game<Seq<A>> map<A>(Seq<Player> players, Game<A> ma) =>\n        players.TraverseM(p => Player.with(p, ma))\n               .As();\n}\n"
  },
  {
    "path": "Samples/CardGame/Program.cs",
    "content": "using CardGame;\nusing LanguageExt;\nusing Console = System.Console;\n\n// Play the game!\nGame.play\n    .Run(GameState.Zero) // Runs the Game \n    .Run()               // Runs the IO\n    .Ignore();           // Discard the result\n\nConsole.WriteLine(\"GAME OVER\");\n"
  },
  {
    "path": "Samples/CreditCardValidation/Control/CreditCard.cs",
    "content": "﻿// This is a toy sample that demonstrates credit-card validation.  It shouldn't be considered complete,\n// it simply demonstrates usage of the Validation applicative/monad for capturing multiple errors when\n// doing complex validation.\n//\n// For more information, see Paul Louth's blog article on Validation:\n// https://paullouth.com/higher-kinds-in-c-with-language-ext-part-5-validation/\n\nusing System.Numerics;\nusing CreditCardValidation.Data;\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace CreditCardValidation.Control;\n\npublic static class CreditCard\n{\n    public static Validation<Error, CreditCardDetails> Validate(string cardNo, string expiryDate, string cvv) =>\n        fun<CardNumber, Expiry, CVV, CreditCardDetails>(CreditCardDetails.Make)\n           .Map(ValidateCardNumber(cardNo))\n           .Apply(ValidateExpiryDate(expiryDate))\n           .Apply(ValidateCVV(cvv))\n           .As();\n\n    static Validation<Error, CardNumber> ValidateCardNumber(string cardNo) =>\n        (ValidateAllDigits(cardNo), ValidateLength(cardNo, 16))\n            .Apply((digits, _) => digits.ToSeq())\n            .Bind(ValidateLuhn)\n            .Map(CardNumber.FromUnsafe)\n            .As()\n            .MapFail(e => Error.New(\"card number not valid\", e));    \n\n    static Validation<Error, Expiry> ValidateExpiryDate(string expiryDate) =>\n        expiryDate.Split('\\\\', '/', '-', ' ') switch\n        {\n            [var month, var year] =>\n                from my  in ValidateInt(month) & ValidateInt(year)\n                from exp in Expiry.From(my[0], my[1]).ToValidation()\n                from _   in ValidateInRange(exp, Expiry.NextTenYears)\n                select exp,\n            \n            _ => Fail(Error.New($\"expected expiry-date in the format: MM/YYYY, but got: {expiryDate}\"))\n        };\n\n    static Validation<Error, A> ValidateInRange<A>(A value, Range<A> range)\n        where A : IComparisonOperators<A, A, bool> =>\n        range.InRange(value)\n            ? Pure(value)\n            : Fail(Error.New($\"expected value in range of {range.From} to {range.To}, but got: {value}\"));\n\n    static Validation<Error, CVV> ValidateCVV(string cvv) =>\n        fun<int, string, CVV>((code, _) => new CVV(code))\n           .Map(ValidateInt(cvv).MapFail(_ => Error.New(\"CVV code should be a number\")))\n           .Apply(ValidateLength(cvv, 3).MapFail(_ => Error.New(\"CVV code should be 3 digits in length\")))\n           .As(); \n\n    static Validation<Error, Iterable<int>> ValidateAllDigits(string value) =>\n        value.AsIterable()\n             .Traverse(CharToDigit)\n             .As();\n\nstatic Validation<Error, int> ValidateInt(string value) =>\n    ValidateAllDigits(value).Map(_ => int.Parse(value));\n\n    static Validation<Error, string> ValidateLength(string value, int length) =>\n        ValidateLength(value.AsIterable(), length)\n            .Map(_ => value);\n\n    static Validation<Error, K<F, A>> ValidateLength<F, A>(K<F, A> fa, int length)\n        where F : Foldable<F> =>\n        fa.Count == length\n            ? Pure(fa)\n            : Fail(Error.New($\"expected length to be {length}, but got: {fa.Count}\"));\n\n    static Validation<Error, int> CharToDigit(char ch) =>\n        ch is >= '0' and <= '9'\n            ? Pure(ch - '0')\n            : Fail(Error.New($\"expected a digit, but got: {ch}\"));\n    \n    static Validation<Error, Seq<int>> ValidateLuhn(Seq<int> digits)\n    {\n        var checkDigit = 0;\n        for (var i = digits.Length - 2; i >= 0; --i)\n        {\n            checkDigit += ((i & 1) is 0) switch\n                          {\n                              true  => digits[i] > 4 ? digits[i] * 2 - 9 : digits[i] * 2,\n                              false => digits[i]\n                          };\n        }\n\n        return (10 - checkDigit % 10) % 10 == digits.Last\n                   ? Pure(digits)\n                   : Fail(Error.New(\"invalid card number\"));\n    }\n}\n"
  },
  {
    "path": "Samples/CreditCardValidation/CreditCardValidation.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Samples/CreditCardValidation/Data/Base12.cs",
    "content": "// This is a toy sample that demonstrates credit-card validation.  It shouldn't be considered complete,\n// it simply demonstrates usage of the Validation applicative/monad for capturing multiple errors when\n// doing complex validation.\n//\n// For more information, see Paul Louth's blog article on Validation:\n// https://paullouth.com/higher-kinds-in-c-with-language-ext-part-5-validation/\n\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits.Domain;\n\nnamespace CreditCardValidation.Data;\n\n/// <summary>\n/// Base 12 number\n/// </summary>\n/// <remarks>\n/// Handy for representing years and months\n/// </remarks>\n/// <param name=\"MostSig\">Most significant digits</param>\n/// <param name=\"LeastSig\">Least significant digits</param>\npublic readonly struct Base12(int MostSig, uint LeastSig) :\n    DomainType<Base12, (int MostSig, uint LeastSig)>,\n    Amount<Base12, Base12>\n{\n    public static readonly Base12 Zero = new (0, 0);\n\n    public static Base12 From(int value) =>\n        new (value / 12, (uint)(Math.Abs(value) % 12));\n\n    public static Fin<Base12> From((int MostSig, uint LeastSig) repr) => \n        repr.LeastSig > 11\n            ? Error.New(\"invalid base-12 number\")\n            : new Base12(repr.MostSig, repr.LeastSig);\n\n    public (int MostSig, uint LeastSig) To() => \n        (MostSig, LeastSig);\n    \n    public int ToBase10() =>\n        MostSig * 12 + (int)LeastSig;\n\n    public static bool operator ==(Base12 left, Base12 right) => \n        left.Equals(right);\n\n    public static bool operator !=(Base12 left, Base12 right) => \n        !(left == right);\n\n    public static Base12 operator -(Base12 value) =>\n        value.To() switch\n        {\n            var (ms, ls) => new Base12(-ms, ls)\n        };\n\n    public static Base12 operator +(Base12 left, Base12 right)\n    {\n        var (lm, ll) = left.To();\n        var (rm, rl) = right.To();\n        var most  = lm + rm;\n        var least = ll + rl;\n\n        (var carry, least) = least >= 12\n                                 ? (1, least - 12)\n                                 : (0, least);\n        \n        return new (most + carry, least);\n    }\n\n    public static Base12 operator -(Base12 left, Base12 right)\n    {\n        var (lm, ll) = left.To();\n        var (rm, rl) = right.To();\n        var most   = lm - rm;\n        var least = (int)ll - (int)rl;\n\n        (var carry, least) = least < 0\n                                 ? (-1, least + 12)\n                                 : (0, least);\n        \n        return new (most + carry, (uint)least);\n    }\n\n    public static Base12 operator *(Base12 left, Base12 right)\n    {\n        var (lm, ll) = left.To();\n        var (rm, rl) = right.To();\n\n        var leastQuot = (ll * rl) % 12;\n        var leastRem  = (ll * rl) / 12;\n        var most      = lm * rm + leastRem;\n        return new((int)most, leastQuot);\n    }\n\n    public static Base12 operator /(Base12 left, Base12 right) \n    {\n        var (lm, ll) = left.To();\n        var (rm, rl) = right.To();\n\n        var mostQuot = lm / rm;\n        var mostRem  = lm % rm;\n        var least = (ll / rl + mostRem) % 12;\n        return new(mostQuot, (uint)least);\n    }\n\n    public bool Equals(Base12 other) => \n        To() == other.To();\n\n    public override bool Equals(object? obj) => \n        obj is Base12 other && Equals(other);\n\n    public override int GetHashCode() => \n        HashCode.Combine(MostSig, LeastSig);\n\n    public int CompareTo(Base12 other) =>\n        (To(), other.To()) switch\n        {\n            var ((lm, ll), (rm, rl)) =>\n                lm.CompareTo(rm) switch\n                {\n                    < 0 => -1,\n                    > 0 => 1,\n                    _   => ll.CompareTo(rl)\n                }\n        };\n\n    public static bool operator >(Base12 left, Base12 right) => \n        left.CompareTo(right) > 0;\n\n    public static bool operator >=(Base12 left, Base12 right) => \n        left.CompareTo(right) >= 0;\n\n    public static bool operator <(Base12 left, Base12 right) => \n        left.CompareTo(right) < 0;\n\n    public static bool operator <=(Base12 left, Base12 right) => \n        left.CompareTo(right) <= 0;\n}\n"
  },
  {
    "path": "Samples/CreditCardValidation/Data/CVV.cs",
    "content": "// This is a toy sample that demonstrates credit-card validation.  It shouldn't be considered complete,\n// it simply demonstrates usage of the Validation applicative/monad for capturing multiple errors when\n// doing complex validation.\n//\n// For more information, see Paul Louth's blog article on Validation:\n// https://paullouth.com/higher-kinds-in-c-with-language-ext-part-5-validation/\n\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits.Domain;\n\nnamespace CreditCardValidation.Data;\n\n/// <summary>\n/// CVV code\n/// </summary>\n/// <param name=\"Number\">Integer representation of the code</param>\npublic class CVV(int Number) :\n    DomainType<CVV, int>,\n    Identifier<CVV>\n{\n    public override string ToString() =>\n        $\"{Number:000}\";\n\n    public static Fin<CVV> From(int repr) =>\n        repr is >= 0 and <= 999\n            ? new CVV(repr)\n            : Error.New(\"invalid CVV number\");\n\n    public int To() => \n        Number;\n\n    public override int GetHashCode() => \n        Number.GetHashCode();\n\n    public bool Equals(CVV? other) => \n        To().Equals(other?.To());\n\n    public override bool Equals(object? obj) =>\n        obj is CVV cvv && Equals(cvv);\n\n    public static bool operator ==(CVV? left, CVV? right) => \n        left?.To() == right?.To();\n\n    public static bool operator !=(CVV? left, CVV? right) => \n        !(left == right);\n}\n"
  },
  {
    "path": "Samples/CreditCardValidation/Data/CardNumber.cs",
    "content": "// This is a toy sample that demonstrates credit-card validation.  It shouldn't be considered complete,\n// it simply demonstrates usage of the Validation applicative/monad for capturing multiple errors when\n// doing complex validation.\n//\n// For more information, see Paul Louth's blog article on Validation:\n// https://paullouth.com/higher-kinds-in-c-with-language-ext-part-5-validation/\n\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits.Domain;\n\nnamespace CreditCardValidation.Data;\n\n/// <summary>\n/// Credit card number\n/// </summary>\n/// <param name=\"Number\">Credit card number</param>\npublic class CardNumber(Seq<int> Number) : \n    DomainType<CardNumber, Seq<int>>,\n    Identifier<CardNumber>\n{\n    public override string ToString() =>\n        $\"{Number}\";\n\n    public static Fin<CardNumber> From(Seq<int> repr) =>\n        repr.Count == 16 && repr.ForAll(n => n is >= 0 and <= 9)\n            ? new CardNumber(repr)\n            : Error.New(\"card number not valid\");\n\n    public static CardNumber FromUnsafe(Seq<int> repr) =>\n        new (repr);\n\n    public Seq<int> To() => \n        Number;\n\n    public bool Equals(CardNumber? other) => \n        To() == other?.To();\n\n    public override bool Equals(object? obj) =>\n        obj is CardNumber other && Equals(other);\n\n    public override int GetHashCode() => \n        To().GetHashCode();\n\n    public static bool operator ==(CardNumber? left, CardNumber? right) => \n        left?.To() == right?.To();\n\n    public static bool operator !=(CardNumber? left, CardNumber? right) => \n        !(left == right);\n}\n"
  },
  {
    "path": "Samples/CreditCardValidation/Data/CreditCardDetails.cs",
    "content": "// This is a toy sample that demonstrates credit-card validation.  It shouldn't be considered complete,\n// it simply demonstrates usage of the Validation applicative/monad for capturing multiple errors when\n// doing complex validation.\n//\n// For more information, see Paul Louth's blog article on Validation:\n// https://paullouth.com/higher-kinds-in-c-with-language-ext-part-5-validation/\n\nnamespace CreditCardValidation.Data;\n\n/// <summary>\n/// Complete credit card details\n/// </summary>\n/// <param name=\"CardNumber\">Credit card number</param>\n/// <param name=\"Expiry\">Expiry date</param>\n/// <param name=\"CVV\">Card security code</param>\npublic record CreditCardDetails(CardNumber CardNumber, Expiry Expiry, CVV CVV)\n{\n    public static CreditCardDetails Make(CardNumber cardNo, Expiry expiry, CVV cvv) =>\n        new (cardNo, expiry, cvv);\n    \n    public override string ToString() =>\n        $\"CreditCard({CardNumber}, {Expiry}, {CVV})\";\n}\n"
  },
  {
    "path": "Samples/CreditCardValidation/Data/Expiry.cs",
    "content": "// This is a toy sample that demonstrates credit-card validation.  It shouldn't be considered complete,\n// it simply demonstrates usage of the Validation applicative/monad for capturing multiple errors when\n// doing complex validation.\n//\n// For more information, see Paul Louth's blog article on Validation:\n// https://paullouth.com/higher-kinds-in-c-with-language-ext-part-5-validation/\n\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits.Domain;\n\nnamespace CreditCardValidation.Data;\n\n/// <summary>\n/// Expiry date MM/YYYY\n/// </summary>\n/// <param name=\"Value\">Base12 number representing year and month</param>\npublic readonly struct Expiry(Base12 Value) :\n    DomainType<Expiry, Base12>,\n    Locus<Expiry, MonthSpan, int>\n{\n    public static Expiry AdditiveIdentity { get; } =\n        new (Base12.Zero);\n\n    public static Expiry Now\n    {\n        get\n        {\n            var now = DateTime.Now;\n            return new Expiry(new Base12(now.Year, (uint)(now.Month - 1)));\n        }\n    }\n\n    public static Range<Expiry> NextTenYears =>\n        new (Now, Now + MonthSpan.TenYears, default, NextTenYears1);\n\n    static Fin<Expiry> DomainType<Expiry, Base12>.From(Base12 repr) => \n        new Expiry(repr);\n\n    public static Fin<Expiry> From(int month, int year) => \n        month is >= 1 and <= 12\n            ? new Expiry(new Base12(year, (uint)(month - 1)))\n            : Error.New(\"invalid date: month out of range, should be 1 - 12\");\n\n    public Base12 To() => \n        Value;\n\n    public bool Equals(Expiry other) => \n        To() == other.To();\n\n    public override bool Equals(object? obj) => \n        obj is Expiry other && Equals(other);\n\n    public override int GetHashCode() => \n        To().GetHashCode();\n\n    public int CompareTo(Expiry other) =>\n        To().CompareTo(other.To());\n\n    public static bool operator ==(Expiry left, Expiry right) => \n        left.Equals(right);\n\n    public static bool operator !=(Expiry left, Expiry right) => \n        !(left == right);\n\n    public static Expiry operator +(Expiry left, MonthSpan right) =>\n        new(left.To() + Base12.From(right.To()));\n\n    public static MonthSpan operator -(Expiry left, Expiry right) =>\n        new(left.To().ToBase10() - right.To().ToBase10());\n\n    public static Expiry operator -(Expiry value) =>\n        new(-value.To());\n\n    public static bool operator >(Expiry left, Expiry right) =>\n        left.To() > right.To();\n\n    public static bool operator >=(Expiry left, Expiry right) =>\n        left.To() >= right.To();\n\n    public static bool operator <(Expiry left, Expiry right) =>\n        left.To() < right.To();\n    \n    public static bool operator <=(Expiry left, Expiry right) =>\n        left.To() <= right.To();\n\n    public override string ToString() =>\n        $\"{To().To().LeastSig + 1}/{To().To().MostSig}\";\n\n    static IEnumerable<Expiry> NextTenYears1 \n    {\n        get\n        {\n            var current = Now;\n            for (var i = 0; i < 10; i++)\n            {\n                yield return current;\n                current += MonthSpan.OneYear;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/CreditCardValidation/Data/MonthSpan.cs",
    "content": "// This is a toy sample that demonstrates credit-card validation.  It shouldn't be considered complete,\n// it simply demonstrates usage of the Validation applicative/monad for capturing multiple errors when\n// doing complex validation.\n//\n// For more information, see Paul Louth's blog article on Validation:\n// https://paullouth.com/higher-kinds-in-c-with-language-ext-part-5-validation/\n\nusing LanguageExt;\nusing LanguageExt.Traits.Domain;\n\nnamespace CreditCardValidation.Data;\n\n/// <summary>\n/// Time span in months\n/// </summary>\n/// <param name=\"Value\">Number of months to span</param>\npublic readonly struct MonthSpan(int Value) :\n    DomainType<MonthSpan, int>,\n    Amount<MonthSpan, int>\n{\n    public static readonly MonthSpan OneYear = new(12);\n    public static readonly MonthSpan TenYears = new(12 * 10);\n    \n    static Fin<MonthSpan> DomainType<MonthSpan, int>.From(int repr) => \n        new MonthSpan(repr);\n\n    public static MonthSpan From(int repr) => \n        new (repr);\n\n    public int To() => \n        Value;\n    \n    public bool Equals(MonthSpan other) => \n        To() == other.To();\n\n    public override bool Equals(object? obj) => \n        obj is MonthSpan other && Equals(other);\n\n    public override int GetHashCode() => \n        To().GetHashCode();\n\n    public int CompareTo(MonthSpan other) => \n        To().CompareTo(other.To());\n\n    public static bool operator ==(MonthSpan left, MonthSpan right) => \n        left.To() == right.To();\n\n    public static bool operator !=(MonthSpan left, MonthSpan right) => \n        !(left == right);\n\n    public static MonthSpan operator -(MonthSpan value) =>\n        From(-value.To());\n\n    public static MonthSpan operator +(MonthSpan left, MonthSpan right) => \n        From(left.To() + right.To());\n\n    public static MonthSpan operator -(MonthSpan left, MonthSpan right) => \n        From(left.To() - right.To());\n\n    public static MonthSpan operator *(MonthSpan left, int right) => \n        From(left.To() * right);\n\n    public static MonthSpan operator /(MonthSpan left, int right) => \n        From(left.To() * right);\n\n    public static bool operator >(MonthSpan left, MonthSpan right) => \n        left.To() > right.To();\n\n    public static bool operator >=(MonthSpan left, MonthSpan right) => \n        left.To() >= right.To();\n\n    public static bool operator <(MonthSpan left, MonthSpan right) => \n        left.To() < right.To();\n\n    public static bool operator <=(MonthSpan left, MonthSpan right) => \n        left.To() <= right.To();\n}\n"
  },
  {
    "path": "Samples/CreditCardValidation/Program.cs",
    "content": "﻿using CreditCardValidation.Control;\n\n// This is a toy sample that demonstrates credit-card validation.  It shouldn't be considered complete,\n// it simply demonstrates usage of the Validation applicative/monad for capturing multiple errors when\n// doing complex validation.\n//\n// For more information, see Paul Louth's blog article on Validation:\n// https://paullouth.com/higher-kinds-in-c-with-language-ext-part-5-validation/\n\nConsole.WriteLine(CreditCard.Validate(\"4560005094752584\", \"12-2024\", \"123\"));\nConsole.WriteLine(CreditCard.Validate(\"00000\", \"00-2345\", \"WXYZ\"));\n"
  },
  {
    "path": "Samples/DomainTypesExamples/Dimension.cs",
    "content": "namespace DomainTypesExamples;\n\npublic interface Dimension\n{\n    public static abstract int Size { get; } \n}\n\npublic class D3 : Dimension\n{\n    public static int Size => 3;\n}\n\npublic class D128 : Dimension\n{\n    public static int Size => 128;\n}\n"
  },
  {
    "path": "Samples/DomainTypesExamples/DomainTypesExamples.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Samples/DomainTypesExamples/Program.cs",
    "content": "﻿// See https://aka.ms/new-console-template for more information\n\nusing DomainTypesExamples;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\n\nvar v1 = Vector<D3, double>.From([100, 200, 300]).ThrowIfFail();\nvar v2 = Vector<D3, double>.From([100, 200, 300]).ThrowIfFail();\nvar v3 = v1 + v2;\n\nConsole.WriteLine($\"{v3}\");\n\nvar w1 = Vector<D128, int>.From(Range(0, 128).ToArr()).ThrowIfFail();\nvar w2 = Vector<D128, int>.From(Range(0, 128).ToArr()).ThrowIfFail();\nvar w3 = w1 + w2;\n\nConsole.WriteLine($\"{w3}\");\n\nvar x1 = Vector<D128, int>.From(Range(0, 128).ToArr()).ThrowIfFail();\nvar x2 = Vector<D128, int>.From(Range(0, 128).ToArr()).ThrowIfFail();\nvar x3 = x1 * x2;\n\nConsole.WriteLine($\"{x3}\");\n"
  },
  {
    "path": "Samples/DomainTypesExamples/Time.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Traits.Domain;\n\nnamespace DomainTypesExamples;\n\npublic readonly record struct Time(long Timestamp) :\n    DomainType<Time, long>,\n    Locus<Time, TimeSpan, long>\n{\n    static Fin<Time> DomainType<Time, long>.From(long repr) => \n        new Time(repr);\n\n    public static Time From(long repr) => \n        new (repr);\n\n    public long To() =>\n        Timestamp;\n\n    public int CompareTo(Time other) => \n        Timestamp.CompareTo(other.Timestamp);\n\n    public static bool operator >(Time left, Time right) => \n        left.Timestamp > right.Timestamp;\n\n    public static bool operator >=(Time left, Time right) =>\n        left.Timestamp >= right.Timestamp;\n\n    public static bool operator <(Time left, Time right) => \n        left.Timestamp < right.Timestamp;\n\n    public static bool operator <=(Time left, Time right) =>\n        left.Timestamp <= right.Timestamp;        \n\n    public static Time operator -(Time value) => \n        new (-value.Timestamp);\n\n    public static Time Origin { get; } = \n        new(0L);\n\n    public static Time AdditiveIdentity { get; } = \n        new(0L);\n    \n    public static Time operator +(Time left, TimeSpan right) => \n        new (left.Timestamp + right.Step);\n\n    public static TimeSpan operator -(Time left, Time right) => \n        new(left.Timestamp - right.Timestamp);\n}\n"
  },
  {
    "path": "Samples/DomainTypesExamples/TimeSpan.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Traits.Domain;\n\nnamespace DomainTypesExamples;\n\npublic readonly record struct TimeSpan(long Step) : \n    DomainType<TimeSpan, long>,\n    Amount<TimeSpan, long>\n{\n    static Fin<TimeSpan> DomainType<TimeSpan, long>.From(long repr) => \n        new TimeSpan(repr);\n\n    public static TimeSpan From(long repr) => \n        new (repr);\n\n    public long To() =>\n        Step;\n    \n    public static TimeSpan operator -(TimeSpan value) => \n        new (-value.Step);\n\n    public static TimeSpan operator +(TimeSpan left, TimeSpan right) => \n        new (left.Step + right.Step);\n\n    public static TimeSpan operator -(TimeSpan left, TimeSpan right) => \n        new (left.Step - right.Step);\n\n    public static TimeSpan operator *(TimeSpan left, long right) => \n        new (left.Step * right);\n\n    public static TimeSpan operator /(TimeSpan left, long right) => \n        new (left.Step / right);\n\n    public int CompareTo(TimeSpan other) => \n        Step.CompareTo(other.Step);\n\n    public static bool operator >(TimeSpan left, TimeSpan right) => \n        left.Step > right.Step;\n\n    public static bool operator >=(TimeSpan left, TimeSpan right) => \n        left.Step >= right.Step;\n\n    public static bool operator <(TimeSpan left, TimeSpan right) => \n        left.Step < right.Step;\n\n    public static bool operator <=(TimeSpan left, TimeSpan right) => \n        left.Step <= right.Step;\n}\n"
  },
  {
    "path": "Samples/DomainTypesExamples/Vector.cs",
    "content": "using System.Numerics;\nusing System.Runtime.Intrinsics;\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits.Domain;\nusing static LanguageExt.Prelude;\n\nnamespace DomainTypesExamples;\n\n/// <summary>\n/// Vector type that can be of any dimension `D` and hold any intrinsic value `A`\n/// </summary>\n/// <remarks>\n/// Operations are performed using SIMD instructions for performance, but if `A`\n/// is not an intrinsic then an exception will be thrown.\n/// </remarks>\n/// <typeparam name=\"D\">Dimension type</typeparam>\n/// <typeparam name=\"A\">Value type</typeparam>\npublic class Vector<D, A> :\n    DomainType<Vector<D, A>, Arr<A>>,\n    VectorSpace<Vector<D, A>, A>\n    where A : \n        IAdditiveIdentity<A, A>,\n        IAdditionOperators<A, A, A>,\n        ISubtractionOperators<A, A, A>,\n        IMultiplyOperators<A, A, A>,\n        IDivisionOperators<A, A, A>,\n        IUnaryNegationOperators<A, A>\n    where D : Dimension\n{\n    readonly Arr<A> Values;\n    \n    private Vector(Arr<A> values)\n    {\n        if(values.Count != D.Size) throw new ArgumentException(nameof(values));\n        Values = values;\n    }\n\n    public static Fin<Vector<D, A>> From(Arr<A> repr) =>\n        repr.Count == D.Size\n            ? new Vector<D, A>(repr)\n            : Error.New($\"Array isn't the correct size.  Expected: {D.Size}, got: {repr.Count}\");\n\n    public Arr<A> To() => \n        Values;\n\n    public override bool Equals(object? obj) =>\n        obj is Vector<D, A> rhs && Equals(rhs);\n\n    public virtual bool Equals(Vector<D, A>? other)\n    {\n        var ia = Values.GetEnumerator();\n        var ib = (other?.To() ?? Arr.empty<A>()).GetEnumerator();\n        while (ia.MoveNext() && ib.MoveNext())\n        {\n            if (!ia.Current.Equals(ib.Current)) \n                return false;\n        }\n        return ia.MoveNext() == ib.MoveNext();\n    }\n\n    public override int GetHashCode() =>\n        hash(Values);\n\n    public static bool operator ==(Vector<D, A>? left, Vector<D, A>? right) => \n        left?.Equals(right) ?? right is null;\n\n    public static bool operator !=(Vector<D, A>? left, Vector<D, A>? right) => \n        !(left == right);\n\n    public static Vector<D, A> operator -(Vector<D, A> value)\n    {\n        var vector = new A[D.Size];\n        var ix     = 0;\n        foreach (var x in value.To())\n        {\n            vector[ix++] = -x;\n        }\n        return new(Arr.create(vector));\n    }\n\n    public static Vector<D, A> operator +(Vector<D, A> left, Vector<D, A> right) \n    {\n        var vector = new A[D.Size];\n        var rem    = D.Size % Vector<A>.Count;\n        var total  = D.Size - rem;\n        var larray = left.Values;\n        var rarray = right.Values;\n\n        // Perform the operation using SIMD intrinsics\n        for (var i = 0; i < total; i += Vector<A>.Count)\n        {\n            var v1 = new Vector<A>(larray.AsSpan(i, Vector<A>.Count));\n            var v2 = new Vector<A>(rarray.AsSpan(i, Vector<A>.Count));\n            (v1 + v2).CopyTo(vector, i);\n        }\n\n        // Perform the remainder of the operation that couldn't fit into a SIMD intrinsic\n        for (var i = D.Size - rem; i < D.Size; i++)\n        {\n            vector[i] = left.Values[i] + right.Values[i];\n        }        \n        return new(Arr.create(vector));\n    }\n    \n    public static Vector<D, A> operator -(Vector<D, A> left, Vector<D, A> right) \n    {\n        var vector = new A[D.Size];\n        var rem    = D.Size % Vector<A>.Count;\n        var total  = D.Size - rem;\n        var larray = left.Values;\n        var rarray = right.Values;\n\n        // Perform the operation using SIMD intrinsics\n        for (var i = 0; i < total; i += Vector<A>.Count)\n        {\n            var v1 = new Vector<A>(larray.AsSpan(i, Vector<A>.Count));\n            var v2 = new Vector<A>(rarray.AsSpan(i, Vector<A>.Count));\n            (v1 - v2).CopyTo(vector, i);\n        }\n\n        // Perform the remainder of the operation that couldn't fit into a SIMD intrinsic\n        for (var i = D.Size - rem; i < D.Size; i++)\n        {\n            vector[i] = left.Values[i] - right.Values[i];\n        }        \n        return new(Arr.create(vector));\n    }\n    \n    /// <summary>\n    /// Returns a new vector whose values are the product of each pair of elements in two specified vectors.\n    /// </summary>\n    public static Vector<D, A> operator *(Vector<D, A> left, Vector<D, A> right) \n    {\n        var vector = new A[D.Size];\n        var rem    = D.Size % Vector<A>.Count;\n        var total  = D.Size - rem;\n        var larray = left.Values;\n        var rarray = right.Values;\n\n        // Perform the operation using SIMD intrinsics\n        for (var i = 0; i < total; i += Vector<A>.Count)\n        {\n            var v1 = new Vector<A>(larray.AsSpan(i, Vector<A>.Count));\n            var v2 = new Vector<A>(rarray.AsSpan(i, Vector<A>.Count));\n            (v1 * v2).CopyTo(vector, i);\n        }\n\n        // Perform the remainder of the operation that couldn't fit into a SIMD intrinsic\n        for (var i = D.Size - rem; i < D.Size; i++)\n        {\n            vector[i] = left.Values[i] * right.Values[i];\n        }        \n        return new(Arr.create(vector));\n    }\n\n    public static Vector<D, A> operator *(Vector<D, A> left, A right) \n    {\n        var vector = new A[D.Size];\n        var rem    = D.Size % Vector<A>.Count;\n        var total  = D.Size - rem;\n        var larray = left.Values;\n\n        // Perform the operation using SIMD intrinsics\n        for (var i = 0; i < total; i += Vector<A>.Count)\n        {\n            var v = new Vector<A>(larray.AsSpan(i, Vector<A>.Count));\n            (v * right).CopyTo(vector, i);\n        }\n\n        // Perform the remainder of the operation that couldn't fit into a SIMD intrinsic\n        for (var i = D.Size - rem; i < D.Size; i++)\n        {\n            vector[i] = left.Values[i] * right;\n        }        \n        return new(Arr.create(vector));\n    }\n\n    public static Vector<D, A> operator /(Vector<D, A> left, A right) \n    {\n        var vector = new A[D.Size];\n        var rem    = D.Size % Vector<A>.Count;\n        var total  = D.Size - rem;\n        var larray = left.Values;\n\n        // Perform the operation using SIMD intrinsics\n        for (var i = 0; i < total; i += Vector<A>.Count)\n        {\n            var v = new Vector<A>(larray.AsSpan(i, Vector<A>.Count));\n            (v / right).CopyTo(vector, i);\n        }\n\n        // Perform the remainder of the operation that couldn't fit into a SIMD intrinsic\n        for (var i = D.Size - rem; i < D.Size; i++)\n        {\n            vector[i] = left.Values[i] / right;\n        }        \n        return new(Arr.create(vector));\n    }\n\n    /// <summary>\n    /// Calculate the dot product between two vectors \n    /// </summary>\n    public A Dot(Vector<D, A> rhs) =>\n        (this * rhs).Sum();\n\n    /// <summary>\n    /// Calculate of all values in the vector\n    /// </summary>\n    public A Sum()\n    {\n        var rem   = D.Size % 16;\n        var total = D.Size - rem;\n        var array = Values;\n        var sum   = A.AdditiveIdentity;\n\n        // Perform the operation using SIMD intrinsics\n        for (var i = 0; i < total; i += Vector<A>.Count)\n        {\n            var span = array.AsSpan(i, 16);\n            sum += span[0]  + span[1]  + span[2]  + span[3]  +\n                   span[4]  + span[5]  + span[6]  + span[7]  +\n                   span[8]  + span[9]  + span[10] + span[11] +\n                   span[12] + span[13] + span[14] + span[15];\n        }\n        \n        // Perform the remainder of the operation that couldn't fit into a SIMD intrinsic\n        for (var i = D.Size - rem; i < D.Size; i++)\n        {\n            sum += array[i];\n        }        \n        return sum;\n    }\n\n    public override string ToString() => \n        Values.ToFullArrayString();\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/EffectsExamples.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <LangVersion>default</LangVersion>\n        <RoslynCodeGenVersion>0.6.1</RoslynCodeGenVersion>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.2\" />\n        <PackageReference Include=\"System.Reactive\" Version=\"5.0.0\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.FSharp\\LanguageExt.FSharp.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Parsec\\LanguageExt.Parsec.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Streaming\\LanguageExt.Streaming.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Rx\\LanguageExt.Rx.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    </ItemGroup>\n\n    <ItemGroup>\n      <Compile Update=\"Examples\\ErrorAndGuardExample.cs\">\n        <Generator>MSBuild:GenerateCodeFromAttributes</Generator>\n      </Compile>\n      <Compile Update=\"Examples\\ForkCancelExample.cs\">\n        <Generator>MSBuild:GenerateCodeFromAttributes</Generator>\n      </Compile>\n      <Compile Update=\"Examples\\TimeExample.cs\">\n        <Generator>MSBuild:GenerateCodeFromAttributes</Generator>\n      </Compile>\n      <Compile Update=\"Examples\\TimeoutExample.cs\">\n        <Generator>MSBuild:GenerateCodeFromAttributes</Generator>\n      </Compile>\n      <Compile Update=\"Examples\\RetryExample.cs\">\n        <Generator>MSBuild:GenerateCodeFromAttributes</Generator>\n      </Compile>\n    </ItemGroup>    \n    \n</Project>\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/CancelExample.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Cancel example \n/// </summary>\n/// <remarks>\n/// Accepts key presses and echos them to the console until Enter is pressed.\n/// When Enter is pressed it calls `cancel` to trigger the cancellation token\n/// </remarks>\npublic class CancelExample<RT>\n    where RT: \n    Has<Eff<RT>, ConsoleIO>\n{\n    public static Eff<RT, Unit> main =>\n       +repeat(from k in Console<RT>.readKey\n               from _ in k.Key == ConsoleKey.Enter\n                             ? cancel\n                             : unitIO\n               from w in Console<RT>.write(k.KeyChar)\n               select unit);\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/ErrorAndGuardExample.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Common;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Error handling and guards example\n/// </summary>\n/// <remarks>\n/// Repeats the text you type in until you press Enter on an empty line, which will write a UserExited error - this\n/// will be caught for a safe exit\n/// Or, 'sys' that will throw a SystemException - this will be caught and 'sys error' will be printed\n/// Or, 'err' that will throw an Exception - this will be caught to become 'there was a problem'\n/// </remarks>\npublic static class ErrorAndGuardExample<RT>\n    where RT : \n        Has<Eff<RT>, ConsoleIO>\n{\n    static readonly Error UserExited = Error.New(100, \"user exited\");\n    static readonly Error SafeError = Error.New(200, \"there was a problem\");\n\n    public static Eff<RT, Unit> main =>\n        from _1 in askUser\n                 | @catch(ex => ex.HasException<SystemException>(), Console<RT>.writeLine(\"system error\"))\n                 | SafeError\n        from _2 in Console<RT>.writeLine(\"goodbye\")\n        select unit;\n\n    static Eff<RT, Unit> askUser =>\n        repeat(Schedule.spaced(1 * second) | Schedule.recurs(3),\n               from ln in Console<RT>.readLine\n               from _1 in guard(notEmpty(ln), UserExited)\n               from _2 in guard(ln != \"sys\", () => throw new SystemException())\n               from _3 in guard(ln != \"err\", () => throw new Exception())\n               from _4 in Console<RT>.writeLine(ln)\n               select unit)\n      | @catch(UserExited, pure<Eff<RT>, Unit>(unit));\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/FoldTest.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Pipes;\nusing LanguageExt.Common;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Pipes.Effect;\nusing static LanguageExt.Pipes.Producer;\nusing static LanguageExt.Pipes.Pipe;\nusing static LanguageExt.Pipes.Consumer;\n\nnamespace EffectsExamples\n{\n    /// <summary>\n    /// Fold test\n    /// </summary>\n    /// <remarks>\n    /// Processes keys from the keyboard into words, when a whitespace is encountered the folded word is yielded\n    /// down the pipe \n    /// </remarks>\n    public static class FoldTest<RT>  \n        where RT : \n            Has<Eff<RT>, ConsoleIO>\n    {\n        public static Eff<RT, Unit> main =>\n            mainEffect.Run().As();\n\n        static Effect<RT, Unit> mainEffect =>\n            Console<RT>.readKeys\n              | exitIfEscape\n              | keyChar\n              | words\n              | filterEmpty\n              | writeLine\n              | Schedule.Forever;\n\n        static Pipe<RT, ConsoleKeyInfo, ConsoleKeyInfo, Unit> exitIfEscape =>\n            from k in awaiting<RT, ConsoleKeyInfo, ConsoleKeyInfo>()\n            from x in guard(k.Key != ConsoleKey.Escape, Errors.Cancelled)\n            from _ in yield<RT, ConsoleKeyInfo, ConsoleKeyInfo>(k)\n            select unit;\n        \n        static Pipe<RT, ConsoleKeyInfo, char, Unit> keyChar =>\n            map<RT, ConsoleKeyInfo, char>(k => k.KeyChar);\n    \n        static Pipe<RT, char, string, Unit> words =>\n            foldUntil<RT, char, string>((word, ch) => word + ch, x => char.IsWhiteSpace(x.Value), \"\");\n\n        static Pipe<RT, string, string, Unit> filterEmpty =>\n            filter<RT, string>(notEmpty);\n        \n        static Consumer<RT, string, Unit> writeLine =>\n            from l in awaiting<RT, string>()\n            from _ in Console<RT>.writeLine(l)\n            select unit;\n    }\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/ForkCancelExample.cs",
    "content": "﻿using LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Process forking and cancelling example\n/// </summary>\n/// <remarks>\n/// Forks a process that runs 10 times, summing a value each time.\n/// If you press enter before the 10 iterations then the forked process will be cancelled\n/// </remarks>\npublic static class ForkCancelExample<RT>\n    where RT : \n        Has<Eff<RT>, ConsoleIO>,\n        Has<Eff<RT>, TimeIO>\n{\n    public static Eff<RT, Unit> main =>\n       +from frk in fork(inner)\n        from key in Console<RT>.readKey\n        from _1  in frk.Cancel\n        from _2  in Console<RT>.writeLine(\"done\")\n        select unit;\n\n    static Eff<RT, Unit> inner =>\n        from x in sum\n        from _ in Console<RT>.writeLine($\"total: {x}\")\n        select unit;\n\n    static Eff<RT, int> sum =>\n        +digit.FoldIO(Schedule.recurs(9) | Schedule.spaced(1 * second), 0, (s, x) => s + x);\n\n    static Eff<RT, int> digit =>\n        from one in SuccessEff<RT, int>(1)\n        from _   in Console<RT>.writeLine(\"*\")\n        select one;\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/QueueExample.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Pipes;\nusing LanguageExt.Common;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Queue example\n/// </summary>\n/// <remarks>\n/// Creates two queues.  Queues are Producers that have an Enqueue function.\n/// The two producers are merged into a single producer and piped to a writeLine consumer to create an Effect\n/// The effect is forked to run without awaiting the result\n/// Another effect is created that listens to input from the user and pipes it to queue 1 or 2 depending on if the\n/// text starts with a '1' or a '2'.\n/// If the text starts with anything else, the effect is cancelled.\n/// Then the fork is cancelled. \n/// </remarks>\n/// <typeparam name=\"RT\"></typeparam>\npublic static class QueueExample<RT> \n    where RT : \n        Has<Eff<RT>, ConsoleIO>\n{\n    public static Eff<RT, Unit> main()\n    {\n        // Create two queues.  Queues are Producers that have an Enqueue function\n        var queue1 = Conduit.make<string>();\n        var queue2 = Conduit.make<string>();\n\n        // Compose the queues with a pipe that prepends some text to what they produce\n        var queues = Seq(queue1.ToProducer<RT>() | prepend(\"Queue 1: \"), \n                         queue2.ToProducer<RT>() | prepend(\"Queue 2: \"));\n\n        // Run the queues in a forked task\n        // Repeatedly read from the console and write to one of the two queues depending on\n        // whether the first char is 1 or 2\n        var effect = from f in fork(Producer.merge(queues) | writeLine).As()\n                     from x in Console<RT>.readLines | writeToQueue(queue1, queue2) | Schedule.Forever\n                     from _ in f.Cancel // cancels the forked task\n                     select unit;\n\n        return effect.As().Run();\n    }\n\n    // Consumer of the console.  It enqueues the item to queue1 or queue2 depending\n    // on the first char of the string it awaits\n    static Consumer<RT, string, Unit> writeToQueue(\n        Conduit<string, string> queue1, \n        Conduit<string, string> queue2) =>\n        from x in Consumer.awaiting<RT, string>()\n        from u in guard(x.Length > 0, Error.New(\"exiting\"))\n        from _ in x[0] switch\n                  {\n                      '1' => queue1.Post(x.Substring(1)).As(),\n                      '2' => queue2.Post(x.Substring(1)).As(),\n                      _   => Fail(Errors.Cancelled)\n                  }\n        select unit;\n        \n    /// <summary>\n    /// Pipe that prepends the text provided to the awaited value and then yields it\n    /// </summary>\n    static Pipe<RT, string, string, Unit> prepend(string x) =>\n        from l in Pipe.awaiting<RT, string, string>()\n        from _ in Pipe.yield<RT, string, string>($\"{x}{l}\")\n        select unit;\n        \n    /// <summary>\n    /// Consumer that simply writes to the console\n    /// </summary>\n    static Consumer<RT, string, Unit> writeLine =>\n        from l in Consumer.awaiting<RT, string>()\n        from _ in Console<RT>.writeLine(l)\n        select unit;\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/RetryExample.cs",
    "content": "﻿using LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Sys;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Retry example\n/// </summary>\n/// <remarks>\n/// Asks you to say hello.\n/// If you don't type 'hello' then an error will be raised and it will retry.\n/// </remarks>\n/// <typeparam name=\"RT\"></typeparam>\npublic static class RetryExample<RT> \n    where RT : \n        Has<Eff<RT>, ConsoleIO>\n{\n    static readonly Error Failed = (Error)\"I asked you to say hello, and you can't even do that?!\";\n        \n    public static Eff<RT, Unit> main =>\n       +retry(Schedule.recurs(5),\n              from _ in Console<RT>.writeLine(\"Say hello\")\n              from t in Console<RT>.readLine\n              from e in guard(t == \"hello\", Failed)  \n              from m in Console<RT>.writeLine(\"Hi\")\n              select unit);\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/TextFileChunkStreamExample.cs",
    "content": "using System.Text;\nusing LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Pipes;\nusing LanguageExt.Sys.IO;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Text file chunk streaming example\n/// </summary>\n/// <remarks>\n/// Streams the contents of a text file in chunks of 40 characters\n/// </remarks>\npublic static class TextFileChunkStreamExample<RT> \n    where RT : \n        Has<Eff<RT>, ConsoleIO>,\n        Has<Eff<RT>, FileIO>,\n        Has<Eff<RT>, TextReadIO>,\n        Has<Eff<RT>, EncodingIO>\n{\n    public static Eff<RT, Unit> main =>\n        from _ in Console<RT>.writeLine(\"Please type in a path to a text file and press enter\")\n        from p in Console<RT>.readLine\n        from e in mainEffect(p).Run()\n        select unit;\n        \n    static Effect<RT, Unit> mainEffect(string path) =>\n        File<RT>.openRead(path) \n          | Stream<Eff<RT>>.read(80).ToEff() \n          | decodeUtf8 \n          | writeLine;\n\n    static Pipe<RT, SeqLoan<byte>, string, Unit> decodeUtf8 =>\n        from c in Pipe.awaiting<RT, SeqLoan<byte>, string>()         \n        from _ in Pipe.yield<RT, SeqLoan<byte>, string>(Encoding.UTF8.GetString(c.ToReadOnlySpan()))\n        select unit;\n        \n    static Consumer<RT, string, Unit> writeLine =>\n        from l in Consumer.awaiting<RT, string>()\n        from _ in Console<RT>.writeLine(l)\n        select unit;\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/TextFileLineStreamExample.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Pipes;\nusing LanguageExt.Sys.IO;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Text file line streaming example\n/// </summary>\n/// <remarks>\n/// Streams the contents of a text file, one line at a time\n/// </remarks>\npublic class TextFileLineStreamExample<RT> \n    where RT : \n        Has<Eff<RT>, ConsoleIO>,\n        Has<Eff<RT>, FileIO>,\n        Has<Eff<RT>, TextReadIO>,\n        Has<Eff<RT>, EncodingIO>\n{\n    public static Eff<RT, Unit> main =>\n        from _ in Console<RT>.writeLine(\"Please type in a path to a text file and press enter\")\n        from p in Console<RT>.readLine\n        from e in mainEffect(p).Run()\n        select unit;\n        \n    static Effect<RT, Unit> mainEffect(string path) =>\n        File<RT>.openText(path) \n            | TextRead<RT>.readLine \n            | writeLine;\n\n    static Consumer<RT, string, Unit> writeLine =>\n        from l in Consumer.awaiting<RT, string>()\n        from _ in Console<RT>.writeLine(l)\n        select unit;\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/TimeExample.cs",
    "content": "﻿using LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Clock example\n/// </summary>\n/// <remarks>\n/// Prints the time for 10 repetitions, the space between the prints follows the Fibonacci sequence up to 10 seconds\n/// and then it's clamped\n/// </remarks>\npublic static class TimeExample<RT>\n    where RT : \n        Has<Eff<RT>, TimeIO>, \n        Has<Eff<RT>, ConsoleIO>\n{\n    public static Eff<RT, Unit> main =>\n       +repeat(Schedule.spaced(10 * second) | Schedule.fibonacci(1 * second) | Schedule.recurs(9),\n               from tm in Time<RT>.now\n               from _1 in Console<RT>.writeLine(tm.ToLongTimeString())\n               select unit);\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Examples/TimeoutExample.cs",
    "content": "﻿using LanguageExt;\nusing LanguageExt.Sys;\nusing LanguageExt.Common;\nusing LanguageExt.Sys.Traits;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace EffectsExamples;\n\n/// <summary>\n/// Process timeout example\n/// </summary>\n/// <remarks>\n/// Repeats a backing off process for 1 minutes\n/// The back-off follows the fibonacci sequence in terms of the delay\n/// </remarks>\n/// <typeparam name=\"RT\"></typeparam>\npublic class TimeoutExample<RT>\n    where RT : \n        Has<Eff<RT>, TimeIO>, \n        Has<Eff<RT>, ConsoleIO>\n{\n    public static Eff<RT, Unit> main =>\n        from _1 in timeout(60 * seconds, longRunning)\n                     | @catch(Errors.TimedOut, pure<Eff<RT>, Unit>(unit))\n        from _2 in Console<RT>.writeLine(\"done\")\n        select unit;\n\n    static Eff<RT, Unit> longRunning =>\n        (from tm in Time<RT>.now\n         from _1 in Console<RT>.writeLine(tm.ToLongTimeString())\n         select unit)\n        .RepeatIO(Schedule.fibonacci(1 * second)).As();\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Menu.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Sys;\nusing LanguageExt.Sys.Traits;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.UnitsOfMeasure;\nusing LanguageExt.Traits;\n\nnamespace EffectsExamples;\n\npublic static class Menu<RT>\n    where RT :\n        Has<Eff<RT>, FileIO>,\n        Has<Eff<RT>, TextReadIO>,\n        Has<Eff<RT>, TimeIO>,\n        Has<Eff<RT>, ConsoleIO>,\n        Has<Eff<RT>, EncodingIO>\n{\n    public static Eff<RT, Unit> menu =>\n        repeat(from __0 in clearConsole(ConsoleColor.Green)\n               from __1 in showOptions\n               from key in Console<RT>.readKey\n               from __2 in clearConsole(ConsoleColor.White)\n               from __3 in runExample(key.KeyChar) \n               select unit).As();\n \n    static Eff<RT, Seq<Unit>> showOptions =>\n       +menuItems.Traverse(p => Console<RT>.writeLine($\"{p.Item}. {p.Text}\"));\n\n    static Eff<RT, Unit> clearConsole(ConsoleColor color) =>\n        from _0 in Console<RT>.clear.As()\n        from _1 in Console<RT>.setColour(color)\n        select unit;\n\n    static Eff<RT, Unit> runExample(char ix) =>\n        from exa in findExample(ix)\n        from __0 in Console<RT>.setColour(ConsoleColor.Yellow)\n        from __1 in Console<RT>.writeLine(exa.Desc)\n        from __2 in Console<RT>.resetColour\n        from res in localCancel(exa.Example) | @catch(logError)\n        from __3 in showComplete(5)\n        select res;\n\n    static Eff<(Eff<RT, Unit> Example, string Desc)> findExample(char ix) =>\n        menuItems.Find(item => item.Item == ix)\n                 .Map(item => (Example: item.Example, Desc: item.Desc))\n                 .ToEff()\n      | Pure((Eff.unit<RT>(), \"invalid menu option\"));\n\n    static Eff<RT, Unit> logError(Error e) =>\n        from _0 in Console<RT>.setColour(ConsoleColor.Red).As()\n        from _1 in Console<RT>.writeLine($\"{e}\")\n        from _2 in Console<RT>.setColour(ConsoleColor.Yellow)\n        select unit;\n\n    static Eff<RT, Unit> showComplete(int x) =>\n        x == 0\n            ? unitEff\n            : from _0 in Console<RT>.setColour(ConsoleColor.Cyan).As()\n              from _1 in Console<RT>.writeLine($\"Returning to menu in {x}\")\n              from _2 in Time<RT>.sleepFor(1 * second)\n              from _3 in showComplete(x - 1)\n              select unit;\n        \n    static Seq<(char Item, Eff<RT, Unit> Example, string Text, string Desc)> menuItems =>\n        [('1', ErrorAndGuardExample<RT>.main, \"Error handling and guards example\", \"Repeats the text you type in until you press Enter on an empty line, which will write a UserExited error - this will be caught for a safe exit\\nOr, 'sys' that will throw a SystemException - this will be caught and 'sys error' will be printed\\nOr, 'err' that will throw an Exception - this will be caught to become 'there was a problem'\"),\n         ('2', ForkCancelExample<RT>.main, \"Process forking and cancelling example\", \"Forks a process that runs 10 times, summing a value each time.\\nIf you press enter before the 10 iterations then the forked process will be cancelled\"),\n         ('3', TimeoutExample<RT>.main, \"Process timeout example\", \"Repeats a backing off process for 1 minutes\\nThe back-off delay follows the fibonacci sequence\"),\n         ('4', TimeExample<RT>.main, \"Clock example\", \"Prints the time for 10 repetitions, the space between the prints follows the Fibonacci sequence up to 10 seconds\\nand then it's clamped\"),\n         ('5', CancelExample<RT>.main, \"Cancel example\", \"Accepts key presses and echos them to the console until Enter is pressed.\\nWhen Enter is pressed it calls `cancel<RT>()` to trigger the cancellation token\"),\n         ('6', RetryExample<RT>.main, \"Retry example\", \"Asks you to say hello.\\nIf you don't type 'hello' then an error will be raised and it will retry.\"),\n         ('7', QueueExample<RT>.main(), \"Queue effect example\", \"Creates two queues.  Queues are Producers that have an Enqueue function.\\nThe two producers are merged into a single producer and piped to a writeLine consumer to create an Effect\\nThe effect is forked to run without awaiting the result\\nAnother effect is created that listens to input from the user and pipes it to queue 1 or 2 depending on if the text starts with a '1' or a '2'.\\nIf the text starts with anything else, the effect is cancelled.\\nThen the fork is cancelled.\"),\n         ('8', FoldTest<RT>.main, \"Pipe word folding example\", \"Folds keys from the keyboard into words, when a whitespace is encountered the folded word is yielded\\ndown the pipe\"),\n         ('9', TextFileLineStreamExample<RT>.main, \"Text file line streaming example\", \"Streams the contents of a text file, one line at a time\"), \n         ('a', TextFileChunkStreamExample<RT>.main, \"Text file chunk streaming example\", \"Streams the contents of a text file in chunks of 80 characters\") \n            //('8', ClientServer<RT>.main, \"Client / server effect example\", \"Simple request/response example.  The client sends 3 values to the server and it increments them\"),\n        ];\n}\n"
  },
  {
    "path": "Samples/EffectsExamples/Program.cs",
    "content": "﻿using LanguageExt;\nusing LanguageExt.Sys.Live;\n\nnamespace EffectsExamples;\n\nclass Program\n{\n    static void Main(string[] args) =>\n        Menu<Runtime>\n           .menu\n           .Run(Runtime.New(), EnvIO.New())\n           .ThrowIfFail();\n}\n"
  },
  {
    "path": "Samples/IOExmples/IOExmples.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <LangVersion>default</LangVersion>\n        <RoslynCodeGenVersion>0.6.1</RoslynCodeGenVersion>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.2\" />\n        <PackageReference Include=\"System.Reactive\" Version=\"5.0.0\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.FSharp\\LanguageExt.FSharp.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Parsec\\LanguageExt.Parsec.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Rx\\LanguageExt.Rx.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    </ItemGroup>    \n    \n</Project>\n"
  },
  {
    "path": "Samples/IOExmples/Program.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace IOExamples;\n\nclass Program\n{\n    static void Main(string[] args) =>\n        infiniteIterator();\n        //infiniteLoop(0).Run();\n\n    static void infiniteIterator()\n    {\n        // NOTE: This should be run in Release mode, otherwise you might get a space leak\n        \n        for(var iter = Naturals.GetIterator(); !iter.IsEmpty; iter = iter.Tail)\n        {\n            if (iter.Head % 10000 == 0)\n            {\n                Console.WriteLine(iter.Head);\n            }\n        }\n    }\n    \n    static IO<Unit> infiniteLoop(int value) =>\n        from _ in value % 10000 == 0\n                    ? writeLine($\"{value}\")\n                    : Pure(unit)\n        from r in tail(infiniteLoop(value + 1))\n        select unit;\n\n    static IO<Unit> infiniteLoop1(int value) =>\n        (value % 10000 == 0\n            ? writeLine($\"{value}\")\n            : Pure(unit))\n           .Bind(_ => infiniteLoop1(value + 1));\n    \n    static IO<int> recursiveAskForNumber =>\n        from n in askForNumber(1)\n        from _ in writeLine($\"Your number is: {n}\")\n        select n;\n\n    static IO<int> askForNumber(int attempts) =>\n        from _ in writeLine($\"Enter a number (attempt number: {attempts})\")\n        from l in readLine\n        from n in int.TryParse(l, out var v)\n                      ? Pure(v)\n                      : from _ in writeLine(\"That's not a number!\")\n                        from r in askForNumber(attempts + 1)\n                        select r\n        select n;\n\n    // static readonly Transducer<int, int> folder =\n    //     foldUntil(Schedule.spaced(TimeSpan.FromMilliseconds(100)),\n    //               0,\n    //               (int s, int x) => s + x,\n    //               valueIs: x => x % 10 == 0);\n    //\n    // static IO<Unit> folding =>\n    //     from n in many(Range(1, 25))\n    //     from _ in writeLine($\"item flowing in: {n}\")\n    //     from s in n | folder\n    //     from r in writeLine($\"Total {s}\")\n    //     select unit;\n    \n    // static IO<Unit> retrying =>\n    //     from ix in many(Range(1, 10))\n    //     from _1 in retry(from _2 in writeLine($\"Enter a number to add to {ix}\")\n    //                      from nm in readLine.Map(parseInt)\n    //                      from _3 in guard(nm.IsSome, Error.New(\"Please enter a valid integer\"))\n    //                      from _4 in writeLine($\"Number {ix} + {(int)nm} = {ix + (int)nm}\")\n    //                      select unit)\n    //     from _4 in waitOneSecond\n    //     select unit;\n\n    static IO<Unit> repeating =>\n        repeat(Schedule.recurs(5),\n               from x in readNumber(\"Enter the first number to add\")\n               from y in readNumber(\"Enter the second number to add\")\n               from _ in writeLine($\"{x} + {y} = {x + y}\")\n               from t in waitOneSecond\n               select unit).As()\n      | writeLine(\"Obviously you don't know what a number is so I'm off.\");\n    \n    static IO<int> readNumber(string question) =>\n        retry(Schedule.recurs(3),\n              from _1 in writeLine(question)\n              from nx in readLine.Map(int.Parse)\n              select nx).As();\n    \n    static readonly IO<string> readLine =\n        lift(() => Console.ReadLine() ?? \"\");\n    \n    static IO<Unit> writeLine(string line) =>\n        lift(() =>\n        {\n            Console.WriteLine(line);\n            return unit;\n        });\n    \n    static IO<Unit> waitOneSecond =>\n        wait(1000);\n\n    static IO<Unit> wait(int milliseconds) =>\n        yieldFor(milliseconds);\n\n    static IO<DateTime> now =>\n        lift(() => DateTime.Now);\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Command/Email.cs",
    "content": "using Newsletter.UI;\nusing Newsletter.Data;\nusing Newsletter.Effects;\nusing Newsletter.Effects.Traits;\nusing SendGrid.Helpers.Mail;\n\nnamespace Newsletter.Command;\n\npublic static class Email<M, RT>\n    where RT : \n        Has<M, EmailIO>,\n        Has<M, ConsoleIO>,\n        Has<M, Config>\n    where M :\n        MonadIO<M>,\n        Fallible<M>\n{\n    public static K<M, Unit> sendToAll(Seq<Member> members, Letter letter) =>\n        members.Traverse(m => send(m.Name, m.Email, letter))\n               .IgnoreF();\n\n    public static K<M, Unit> send(string name, string email, Letter letter) =>\n        Effects.Email<M, RT>\n               .send(new EmailAddress(\"noreply@paullouth.com\", \"Notes from a Small Functional Island\"),\n                     new EmailAddress(email, name),\n                     letter.Title,\n                     letter.PlainText,\n                     letter.Html)\n              | @catch(Display<M, RT>.error); \n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Command/Members.cs",
    "content": "using CsvHelper;\nusing CsvHelper.Configuration;\nusing System.Globalization;\nusing Newsletter.Effects;\nusing Newsletter.Data;\n\nnamespace Newsletter.Command;\n\n/// <summary>\n/// Member access\n/// </summary>\npublic static class Members<M, RT>\n    where RT : \n        Has<M, FileIO>,\n        Has<M, EncodingIO>,\n        Has<M, DirectoryIO>,\n        Has<M, Config>\n    where M :\n        MonadIO<M>,\n        Fallible<M>\n{\n    public static K<M, Seq<Member>> readAll =>\n        from folder  in Config<M, RT>.membersFolder\n        from path    in readFirstFile(folder)\n        select readMembers(path).Filter(m => m.SubscribedToEmails);\n\n    static K<M, string> readFirstFile(string folder) =>\n        Directory<M, RT>.enumerateFiles(folder, \"*.csv\")\n                        .Map(fs => fs.OrderDescending()\n                                     .AsIterable()\n                                     .Head)\n                        .Bind(path => path.Match(\n                                  Some: pure<M, string>,\n                                  None: error<M, string>(Error.New($\"no member files found in {folder}\"))));\n\n    static Seq<Member> readMembers(string path)\n    {\n        var       config  = new CsvConfiguration(CultureInfo.InvariantCulture) { HasHeaderRecord = true };\n        using var reader  = new StreamReader(path);\n        using var csv     = new CsvReader(reader, config);\n        return csv.GetRecords<Row>()\n                  .AsIterable()\n                  .Map(r => new Member(r.id, r.email, r.name, r.subscribed_to_emails == \"true\", r.tiers == \"Supporter\"))\n                  .ToSeq()\n                  .Strict();\n    }\n\n    record Row(\n        string id,\n        string email,\n        string name,\n        string note,\n        string subscribed_to_emails,\n        string complimentary_plan,\n        string stripe_customer_id,\n        string created_at,\n        string deleted_at,\n        string labels,\n        string tiers);\n}\n\n\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Command/Newsletter.cs",
    "content": "using System.Web;\nusing System.Text;\nusing Newsletter.Data;\nusing Newsletter.Effects;\n\nnamespace Newsletter.Command;\n\npublic static class Newsletter<M, RT>\n    where RT : \n        Has<M, FileIO>,\n        Has<M, EncodingIO>,\n        Has<M, Config>,\n        Has<M, HttpClient>\n    where M :\n        MonadIO<M>,\n        Fallible<M>\n{\n    /// <summary>\n    /// Builds the newsletter\n    /// </summary>\n    public static K<M, Letter> make(Seq<Post> posts, Templates templates) =>\n        M.Pure(Newsletter.make(posts, templates));\n    \n    /// <summary>\n    /// Saves the newsletter as HTML and plain-text to the letters folder\n    /// </summary>\n    public static K<M, Unit> save(Letter letter) =>\n        from f in Config<M, RT>.lettersFolder\n        from _ in File<M, RT>.writeAllText(Path.Combine(f, $\"letter-{letter.PublishedAt:yyyy-MM-dd}.html\"), letter.Html) >>\n                  File<M, RT>.writeAllText(Path.Combine(f, $\"letter-{letter.PublishedAt:yyyy-MM-dd}.txt\"), letter.PlainText)  \n        select unit;\n}\n\npublic static class Newsletter\n{\n    /// <summary>\n    /// Builds the newsletter\n    /// </summary>\n    public static Letter make(Seq<Post> posts, Templates templates)\n    {\n        var post = posts[0];\n        var recentHtml = new StringBuilder();\n        var recentText = new StringBuilder();\n        \n        foreach(var recent in posts.Tail)\n        {\n            var rhtml = templates.RecentItem\n                                 .Html\n                                 .Replace(\"[TITLE]\", HttpUtility.HtmlEncode(recent.Title))\n                                 .Replace(\"[EXCERPT]\", HttpUtility.HtmlEncode(recent.Excerpt))\n                                 .Replace(\"[URL]\", recent.Url.ToString());\n            \n            if (recent.FeatureImageUrl)\n            {\n                rhtml = rhtml.Replace(\"[IMAGE_URL]\", ((Uri)recent.FeatureImageUrl).ToString());\n            }\n            recentHtml.Append(rhtml);\n            \n            recentText.Append(templates.RecentItem\n                                       .PlainText\n                                       .Replace(\"[TITLE]\", recent.Title)\n                                       .Replace(\"[EXCERPT]\", recent.Excerpt)\n                                       .Replace(\"[URL]\", recent.Url.ToString()));\n        }\n\n        var yearRange = DateTime.Now.Year switch\n                        {\n                            2024  => \"2024\",\n                            var y => $\"2024 - {y}\"\n                        };\n        \n        var html = templates.Email\n                            .Html\n                            .Replace(\"[POST_CONTENT]\", post.Html)\n                            .Replace(\"[POST_DATE]\", $\"{post.PublishedAt.Day} {monthToString(post.PublishedAt.Month)} {post.PublishedAt.Year}\")\n                            .Replace(\"[POST_URL]\", post.Url.ToString())\n                            .Replace(\"[POST_TITLE]\", HttpUtility.HtmlEncode(post.Title))\n                            .Replace(\"[YEAR_RANGE]\", yearRange)\n                            .Replace(\"[RECENT_ARTICLES]\", recentHtml.ToString());\n\n        if (post.FeatureImageUrl)\n        {\n            html = html.Replace(\"[FEATURE_IMAGE_URL]\", ((Uri)post.FeatureImageUrl).ToString());\n        }\n\n        var text = templates.Email\n                            .PlainText\n                            .Replace(\"[POST_CONTENT]\", post.PlainText)\n                            .Replace(\"[POST_DATE]\", $\"{post.PublishedAt.Day} {monthToString(post.PublishedAt.Month)} {post.PublishedAt.Year}\")\n                            .Replace(\"[POST_URL]\", post.Url.ToString())\n                            .Replace(\"[POST_TITLE]\", post.Title)\n                            .Replace(\"[YEAR_RANGE]\", yearRange)\n                            .Replace(\"[RECENT_ARTICLES]\", recentText.ToString());\n\n        return new Letter(post.Title, html, text, post.PublishedAt);\n    }\n\n    /// <summary>\n    /// Convert month integer to a string\n    /// </summary>\n    static string monthToString(int month) =>\n        month switch\n        {\n            1  => \"Jan\",\n            2  => \"Feb\",\n            3  => \"Mar\",\n            4  => \"Apr\",\n            5  => \"May\",\n            6  => \"Jun\",\n            7  => \"Jul\",\n            8  => \"Aug\",\n            9  => \"Sep\",\n            10 => \"Oct\",\n            11 => \"Nov\",\n            12 => \"Dec\",\n            _  => \"?\"\n        };\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Command/Posts.cs",
    "content": "using System.Text.Json;\nusing Newsletter.Data;\nusing Newsletter.Effects;\nusing Newsletter.Effects.Traits;\n\nnamespace Newsletter.Command;\n\npublic static class Posts<M, RT>\n    where RT : \n        Has<M, WebIO>,\n        Has<M, JsonIO>,\n        Has<M, FileIO>,\n        Has<M, EncodingIO>,\n        Has<M, DirectoryIO>,\n        Has<M, Config>,\n        Has<M, HttpClient>\n    where M :\n        MonadIO<M>,\n        Fallible<M>\n{\n    /// <summary>\n    /// Read the latest post from the Ghost API\n    /// </summary>\n    public static K<M, Post> readFromApi =>\n        readAllFromApi.Bind(\n            p => p.Head\n                  .Match(Some: M.Pure,\n                         None: M.Fail<Post>(Error.New(\"no posts found\"))));\n\n    /// <summary>\n    /// Read the last n posts from the Ghost API\n    /// </summary>\n    public static K<M, Seq<Post>> readLastFromApi(int n) =>\n        readAllFromApi.Map(ps => ps.Take(n).ToSeq());\n\n    /// <summary>\n    /// Read all posts from the Ghost API\n    /// </summary>\n    public static K<M, Iterable<Post>> readAllFromApi =>\n        from root    in Config<M, RT>.siteUrl\n        from apiKey  in Config<M, RT>.contentApiKey\n        from text    in Web<M, RT>.downloadText(makePostsUrl(root, apiKey))\n        from element in getPostsElementForApiResult(text)\n        from posts   in readPostsFromText(element)\n        select posts;\n\n    static K<M, string> readFirstFile(string folder) =>\n        from fs in Directory<M, RT>.enumerateFiles(folder, \"*.json\")\n                                   .Bind(fs => fs.OrderDescending()\n                                                 .AsIterable()\n                                                 .Take(1)\n                                                 .Traverse(File<M, RT>.readAllText))\n        from rs in fs.ToSeq() switch\n                   {\n                       [var text, ..] => M.Pure(text),\n                       _              => M.Fail<string>(Error.New($\"no JSON posts file found in {folder}\"))\n                   }\n        select rs;\n\n    static K<M, JsonElement> getPostsElementForApiResult(string text) =>\n        Json<M, RT>.readJson(text)\n                   .Map(doc => doc.RootElement\n                                  .Get(\"posts\"));\n\n    static K<M, JsonElement> getPostsElementForFile(string text) =>\n        Json<M, RT>.readJson(text)\n                   .Map(doc => doc.RootElement\n                                  .Get(\"db\")\n                                  .EnumerateArray()\n                                  .FirstOrDefault()\n                                  .Get(\"data\")\n                                  .Get(\"posts\"));\n\n    static K<M, Iterable<Post>> readPostsFromText(JsonElement postsElement) =>\n        postsElement.Enumerate()\n                    .Traverse(readPost)\n                    .Map(posts => posts.OrderDescending()\n                                       .AsIterable()\n                                       .Filter(p => p.IsPublic));\n\n    static K<M, Post> readPost(JsonElement element) =>\n        Config<M, RT>.siteUrl.Map(siteUrl =>\n        {\n            // Acquire\n            var id = element.Get(\"id\").GetString() ?? throw new Exception(\"failed to read post 'id'\");\n            var title = element.Get(\"title\").GetString() ?? throw new Exception(\"failed to read post 'title'\");\n            var slug = element.Get(\"slug\").GetString() ?? throw new Exception(\"failed to read post 'slug'\");\n            var html = element.Get(\"html\").GetString() ?? throw new Exception(\"failed to read post 'html'\");\n            var plaintext = element.Get(\"plaintext\").GetString() ?? throw new Exception(\"failed to read post 'plaintext'\");\n            var featureImage = element.Get(\"feature_image\")\n                                      .GetString()\n                                     ?.Replace(\"__GHOST_URL__\", siteUrl)\n                                     ?? null;\n            var excerpt     = element.Get(\"custom_excerpt\").GetString() ?? \"\";\n            var publishedAt = element.Get(\"published_at\").GetDateTime();\n\n            var emailRecFilter = element.TryGetProperty(\"email_recipient_filter\", out var value1) switch\n                                 { \n                                     true => value1.GetString() == \"all\",\n                                     _    => true\n                                 };  \n            \n            var status = element.TryGetProperty(\"status\", out var value2) switch\n                                 { \n                                     true => value2.GetString() == \"published\",\n                                     _    => true\n                                 };  \n            \n            var isPublic = emailRecFilter && status;\n            \n            // Fix up\n            var url = new Uri($\"{siteUrl}/{slug}\");\n            var featureImageUrl = featureImage == null ? null : new Uri(featureImage);\n            html = fixupText(html, siteUrl);\n            plaintext = fixupText(plaintext, siteUrl);\n            \n            return new Post(id, title, url, html, plaintext, excerpt, Optional(featureImageUrl), publishedAt, isPublic);\n        });\n    \n    static string fixupText(string text, string siteUrl) =>\n        text.Replace(\"\\\\n\", \"\\n\")\n            .Replace(\"\\\\\\\"\", \"\\\"\")\n            .Replace(\"\\\\\\\\\", \"\\\\\")\n            .Replace(\"<code class=\\\"language-csharp\\\"\", \n                     \"<code class=\\\"language-csharp\\\" style=\\\"color: darkblue\\\"\") \n            .Replace(\"<code>\", \n                     \"<code style=\\\"color: darkblue; background-color:#eee\\\">\") \n            .Replace(\"__GHOST_URL__\", siteUrl);\n\n    /// <summary>\n    /// Generate the Uri for the /posts API for the Ghost CMS platform \n    /// </summary>\n    static Uri makePostsUrl(string root, string apiKey) =>\n        new ($\"{root}/ghost/api/content/posts/?key={apiKey}&formats=html,plaintext\");\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Command/Send.cs",
    "content": "using Newsletter.Data;\nusing Newsletter.Effects;\nusing Newsletter.Effects.Traits;\nusing Newsletter.UI;\n\nnamespace Newsletter.Command;\n\npublic static class Send<M, RT>\n    where RT : \n        Has<M, WebIO>,\n        Has<M, JsonIO>,\n        Has<M, FileIO>,\n        Has<M, EmailIO>,\n        Has<M, ConsoleIO>,\n        Has<M, EncodingIO>,\n        Has<M, DirectoryIO>,\n        Has<M, Config>,\n        Has<M, HttpClient>\n    where M :\n        MonadIO<M>,\n        Fallible<M>\n{\n    public static K<M, Unit> newsletter =>\n        from posts     in Posts<M, RT>.readLastFromApi(4)\n        from members   in Members<M, RT>.readAll\n        from templates in Templates<M, RT>.loadDefault\n        from letter    in Newsletter<M, RT>.make(posts, templates)\n        from _         in Newsletter<M, RT>.save(letter) >>\n                          Display<M, RT>.showWhatsAboutToHappen(members) >>\n                          askUserToConfirmSend >>\n                          Email<M, RT>.sendToAll(members, letter) >>\n                          Display<M, RT>.confirmSent \n        select unit;\n\n    static K<M, Unit> askUserToConfirmSend =>\n        from k in Console<M, RT>.readKey\n        from x in Display<M, RT>.emptyLine\n        from _ in k.Key == ConsoleKey.Y\n                      ? pure<M, Unit>(unit)\n                      : error<M>(Error.New(\"user cancelled\"))\n        select unit;\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Command/Templates.cs",
    "content": "using Newsletter.Data;\nusing Newsletter.Effects;\n\nnamespace Newsletter.Command;\n\n/// <summary>\n/// Loads the templates for the emails\n/// </summary>\npublic static class Templates<M, RT>\n    where RT : \n        Has<M, FileIO>,\n        Has<M, EncodingIO>,\n        Has<M, DirectoryIO>,\n        Has<M, Config>\n    where M :\n        MonadIO<M>,\n        Fallible<M>\n{\n    public static K<M, Templates> loadDefault =>\n        from folder in Config<M, RT>.templateFolder\n        from email in loadTemplate(\"email\")\n        from recnt in loadTemplate(\"recent-item\")\n        select new Templates(email, recnt);\n    \n    public static K<M, Template> loadTemplate(string name) =>\n        from fldr in Config<M, RT>.templateFolder\n        from html in File<M, RT>.readAllText(Path.Combine(fldr, $\"{name}.html\"))\n        from text in File<M, RT>.readAllText(Path.Combine(fldr, $\"{name}.txt\"))\n        select new Template(html, text);\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Data/Letter.cs",
    "content": "namespace Newsletter.Data;\n\npublic record Letter(\n    string Title,\n    string Html, \n    string PlainText, \n    DateTime PublishedAt);\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Data/Members.cs",
    "content": "namespace Newsletter.Data;\n\n/// <summary>\n/// Member record\n/// </summary>\npublic record Member(string Id, string Email, string Name, bool SubscribedToEmails, bool Supporter);\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Data/Posts.cs",
    "content": "namespace Newsletter.Data;\n\npublic record Post(\n    string Id,\n    string Title,\n    Uri Url,\n    string Html,\n    string PlainText,\n    string Excerpt,\n    Option<Uri> FeatureImageUrl,\n    DateTime PublishedAt,\n    bool IsPublic) : IComparable<Post>\n{\n    public int CompareTo(Post? other)\n    {\n        if (ReferenceEquals(this, other)) return 0;\n        if (ReferenceEquals(null, other)) return 1;\n        return PublishedAt.CompareTo(other.PublishedAt);\n    }\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Data/Templates.cs",
    "content": "namespace Newsletter.Data;\n\n/// <summary>\n/// Collection of all the templates\n/// </summary>\npublic record Templates(Template Email, Template RecentItem);\n\n/// <summary>\n/// Single template\n/// </summary>\npublic record Template(string Html, string PlainText);\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Config.cs",
    "content": "namespace Newsletter.Effects;\n\n/// <summary>\n/// Config record\n/// </summary>\npublic record Config(\n    string MembersFolder,         // Location of the exported member list  \n    string TemplateFolder,        // Location of the HTML and plain-text templates  \n    string LettersFolder,         // Location to save the newsletters to\n    string SiteUrl,               // https://paullouth.com site-url\n    int FeatureImageWidth,        // Maximum size of the feature image\n    string ContentApiKey,         // GhostCMS API key (you need to generate this in the Admin console of GhostCMS)\n    Option<string> SendGridApiKey // Api key for SendGrid!  \n);            \n\n/// <summary>\n/// Application configuration\n/// </summary>\npublic static class Config<M, RT>\n    where RT :\n        Has<M, Config>\n    where M :\n        Monad<M>,\n        Fallible<M>\n{\n    static readonly K<M, Config> configIO =\n        RT.Ask;\n\n    /// <summary>\n    /// Location of the exported member list\n    /// </summary>\n    public static K<M, string> membersFolder =>\n        configIO.Map(t => t.MembersFolder);\n\n    /// <summary>\n    /// Location of the HTML and plain-text templates\n    /// </summary>\n    public static K<M, string> templateFolder =>\n        configIO.Map(t => t.TemplateFolder);\n\n    /// <summary>\n    /// Location to save the newsletters to\n    /// </summary>\n    public static K<M, string> lettersFolder =>\n        configIO.Map(t => t.LettersFolder);\n\n    /// <summary>\n    /// https://paullouth.com site-url\n    /// </summary>\n    public static K<M, string> siteUrl =>\n        configIO.Map(t => t.SiteUrl);\n\n    /// <summary>\n    /// Maximum size of the feature image\n    /// </summary>\n    public static K<M, int> featureImageWidth =>\n        configIO.Map(t => t.FeatureImageWidth);\n\n    /// <summary>\n    /// GhostCMS API key (you need to generate this in the Admin console of GhostCMS)\n    /// </summary>\n    public static K<M, string> contentApiKey =>\n        configIO.Map(t => t.ContentApiKey);\n\n    /// <summary>\n    /// Api key for SendGrid!\n    /// </summary>\n    public static K<M, string> sendGridApiKey =>\n        from k in configIO.Map(t => t.SendGridApiKey)\n        from _ in when(k.IsNone, error<M>((Error)\"SendGrid key not set.  No emails will be sent\"))\n        select (string)k;\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Email.cs",
    "content": "using Newsletter.Effects.Traits;\nusing SendGrid.Helpers.Mail;\n\nnamespace Newsletter.Effects;\n\n/// <summary>\n/// Json parser\n/// </summary>\npublic static class Email<M, RT>\n    where RT : \n        Has<M, EmailIO>,\n        Has<M, Config>\n    where M :\n        MonadIO<M>,\n        Fallible<M>\n{\n    static K<M, EmailIO> trait =>\n        Has<M, RT, EmailIO>.ask;\n\n    /// <summary>\n    /// Send an email\n    /// </summary>\n    public static K<M, Unit> send(\n        EmailAddress from,\n        EmailAddress to,\n        string subject,\n        string plainTextContent,\n        string htmlContent) =>\n        from key in Config<M, RT>.sendGridApiKey\n        from eml in trait\n        from res in liftIO(io => eml.Send(key, @from, to, subject, plainTextContent, htmlContent, io.Token))\n        select unit;\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Image.cs",
    "content": "using Newsletter.Effects.Traits;\n\nnamespace Newsletter.Effects;\n\n/// <summary>\n/// Json parser\n/// </summary>\npublic static class Image<M, RT>\n    where RT : \n        Has<M, ImageIO>\n    where M :\n        Monad<M>\n{\n    public static readonly K<M, ImageIO> trait =\n        Has<M, RT, ImageIO>.ask;\n\n    public static K<M, byte[]> scaleToMaximumWidthJpeg(byte[] input, int maxWidthInPixels) =>\n        trait.Map(t => t.ScaleToMaximumWidthJpeg(input, maxWidthInPixels));\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Impl/Email.cs",
    "content": "using SendGrid;\nusing SendGrid.Helpers.Mail;\nusing Newsletter.Effects.Traits;\n\nnamespace Newsletter.Effects.Impl;\n\npublic class Email : EmailIO\n{\n    public static readonly EmailIO Default = new Email();\n    \n    public async Task<Response> Send(\n        string apiKey,\n        EmailAddress from,\n        EmailAddress to,\n        string subject,\n        string plainTextContent,\n        string htmlContent,\n        CancellationToken token)\n    {\n        var client   = new SendGridClient(apiKey);\n        var msg      = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);\n        var response = await client.SendEmailAsync(msg, token);\n        return response;\n    }    \n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Impl/Image.cs",
    "content": "using SixLabors.ImageSharp;\nusing SixLabors.ImageSharp.Processing;\nusing Img = SixLabors.ImageSharp.Image;\nusing Newsletter.Effects.Traits;\n\nnamespace Newsletter.Effects.Impl;\n\npublic class Image : ImageIO\n{\n    public static readonly ImageIO Default = new Image();\n    \n    public byte[] ScaleToMaximumWidthJpeg(ReadOnlySpan<byte> inputBytes, int maxWidthInPixels)\n    {\n        using var image = Img.Load(inputBytes);\n        if (image.Width < maxWidthInPixels) return inputBytes.ToArray();\n        var height = (int)((double)image.Height * maxWidthInPixels / image.Width);\n        image.Mutate(x => x.Resize(maxWidthInPixels,  height));\n        using var stream = new MemoryStream();\n        image.SaveAsJpeg(stream);\n        return stream.ToArray();\n    }\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Impl/Json.cs",
    "content": "using System.Text.Json;\nusing Newsletter.Effects.Traits;\n\nnamespace Newsletter.Effects.Impl;\n\npublic record Json : JsonIO\n{\n    public static readonly JsonIO Default = new Json();\n    \n    public JsonDocument Parse(string text) =>\n        JsonDocument.Parse(text);\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Impl/Web.cs",
    "content": "using Newsletter.Effects.Traits;\n\nnamespace Newsletter.Effects.Impl;\n\npublic record Web : WebIO\n{\n    public static readonly WebIO Default = new Web();\n\n    public async Task<byte[]> Download(Uri uri, HttpClient client) =>\n        await client.GetByteArrayAsync(uri);\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Json.cs",
    "content": "using System.Text.Json;\nusing Newsletter.Effects.Traits;\n\nnamespace Newsletter.Effects;\n\n/// <summary>\n/// Json parser\n/// </summary>\npublic static class Json<M, RT>\n    where RT : \n        Has<M, JsonIO>\n    where M :\n        Monad<M>\n{\n    static readonly K<M, JsonIO> trait =\n        Has<M, RT, JsonIO>.ask;\n\n    public static K<M, JsonDocument> readJson(string text) =>\n        trait.Map(t => t.Parse(text));\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Runtime.cs",
    "content": "using Newsletter.Effects.Traits;\n\nnamespace Newsletter.Effects;\n\npublic record Runtime(RuntimeEnv Env) :\n    Has<Eff<Runtime>, WebIO>,\n    Has<Eff<Runtime>, FileIO>,\n    Has<Eff<Runtime>, JsonIO>,\n    Has<Eff<Runtime>, EmailIO>,\n    Has<Eff<Runtime>, ImageIO>,\n    Has<Eff<Runtime>, ConsoleIO>,\n    Has<Eff<Runtime>, EncodingIO>,\n    Has<Eff<Runtime>, DirectoryIO>,\n    Has<Eff<Runtime>, Config>,\n    Has<Eff<Runtime>, HttpClient>,\n    IDisposable\n{\n    static Config Common(string repoRootFolder, Option<string> sendGridKey) =>\n        new (\"\",\n             Path.Combine(repoRootFolder, \"templates\"),\n             \"\",\n             \"https://paullouth.com\",\n             700,\n             // Public Ghost-API key. It's ok this only accesses public data,\n             // just don't abuse it, or I'll revoke it!\n             \"6d15eacab40271bcdd552306d0\",\n             sendGridKey);\n\n    public static Runtime Test(string repoRootFolder, Option<string> sendGridKey) =>\n        New(new RuntimeEnv(\n                new HttpClient(),\n                Common(repoRootFolder, sendGridKey) with\n                {\n                    MembersFolder = Path.Combine(repoRootFolder, \"members-test\"),\n                    LettersFolder = Path.Combine(repoRootFolder, \"letters-test\")\n                }));\n\n    public static Runtime Live(string repoRootFolder, Option<string> sendGridKey) =>\n        New(new RuntimeEnv(\n                new HttpClient(),\n                Common(repoRootFolder, sendGridKey) with\n                {\n                    MembersFolder = Path.Combine(repoRootFolder, \"members-live\"),\n                    LettersFolder = Path.Combine(repoRootFolder, \"letters-live\")\n                }));\n    \n    public static Runtime New(RuntimeEnv env) =>\n        new (env);\n    \n    static K<Eff<Runtime>, FileIO> Has<Eff<Runtime>, FileIO>.Ask =>\n        pure<Eff<Runtime>, FileIO>(LanguageExt.Sys.Live.Implementations.FileIO.Default);\n\n    static K<Eff<Runtime>, EncodingIO> Has<Eff<Runtime>, EncodingIO>.Ask => \n        pure<Eff<Runtime>, EncodingIO>(LanguageExt.Sys.Live.Implementations.EncodingIO.Default);\n\n    static K<Eff<Runtime>, DirectoryIO> Has<Eff<Runtime>, DirectoryIO>.Ask =>\n        pure<Eff<Runtime>, DirectoryIO>(LanguageExt.Sys.Live.Implementations.DirectoryIO.Default);\n\n    static K<Eff<Runtime>, ConsoleIO> Has<Eff<Runtime>, ConsoleIO>.Ask =>\n        pure<Eff<Runtime>, ConsoleIO>(LanguageExt.Sys.Live.Implementations.ConsoleIO.Default);\n\n    static K<Eff<Runtime>, JsonIO> Has<Eff<Runtime>, JsonIO>.Ask => \n        pure<Eff<Runtime>, JsonIO>(Impl.Json.Default); \n\n    static K<Eff<Runtime>, EmailIO> Has<Eff<Runtime>, EmailIO>.Ask => \n        pure<Eff<Runtime>, EmailIO>(Impl.Email.Default); \n\n    static K<Eff<Runtime>, WebIO> Has<Eff<Runtime>, WebIO>.Ask =>\n        pure<Eff<Runtime>, WebIO>(Impl.Web.Default);\n\n    static K<Eff<Runtime>, ImageIO> Has<Eff<Runtime>, ImageIO>.Ask =>\n        pure<Eff<Runtime>, ImageIO>(Impl.Image.Default);\n\n    static K<Eff<Runtime>, Config> Has<Eff<Runtime>, Config>.Ask { get; } = \n        liftEff<Runtime, Config>(rt => rt.Env.Config);\n\n    static K<Eff<Runtime>, HttpClient> Has<Eff<Runtime>, HttpClient>.Ask { get; } = \n        liftEff<Runtime, HttpClient>(rt => rt.Env.HttpClient);\n\n    public void Dispose() =>\n        Env.Dispose();\n}\n\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/RuntimeEnv.cs",
    "content": "namespace Newsletter.Effects;\n\npublic record RuntimeEnv(HttpClient HttpClient, Config Config) : IDisposable\n{\n    public void Dispose() => \n        HttpClient.Dispose();\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Traits/EmailIO.cs",
    "content": "using SendGrid;\nusing SendGrid.Helpers.Mail;\n\nnamespace Newsletter.Effects.Traits;\n\npublic interface EmailIO\n{\n    Task<Response> Send(\n        string apiKey,\n        EmailAddress from,\n        EmailAddress to,\n        string subject,\n        string plainTextContent,\n        string htmlContent,\n        CancellationToken token);\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Traits/ImageIO.cs",
    "content": "namespace Newsletter.Effects.Traits;\n\npublic interface ImageIO\n{\n    byte[] ScaleToMaximumWidthJpeg(ReadOnlySpan<byte> inputBytes, int maxWidthInPixels);\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Traits/JsonIO.cs",
    "content": "using System.Text.Json;\n\nnamespace Newsletter.Effects.Traits;\n\npublic interface JsonIO\n{\n    public JsonDocument Parse(string text);\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Traits/WebIO.cs",
    "content": "namespace Newsletter.Effects.Traits;\n\npublic interface WebIO\n{\n    public Task<byte[]> Download(Uri uri, HttpClient client);\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Effects/Web.cs",
    "content": "using Newsletter.Effects.Traits;\n\nnamespace Newsletter.Effects;\n\n/// <summary>\n/// Web downloader\n/// </summary>\npublic static class Web<M, RT>\n    where RT : \n        Has<M, WebIO>,\n        Has<M, EncodingIO>,\n        Has<M, HttpClient>\n    where M :\n        MonadIO<M>\n{\n    static K<M, WebIO> trait =>\n        Has<M, RT, WebIO>.ask;\n\n    static K<M, HttpClient> client =>\n        Has<M, RT, HttpClient>.ask;\n\n    public static K<M, string> downloadText(Uri uri) =>\n        from en in Enc<M, RT>.encoding\n        from bs in download(uri)\n        select en.GetString(bs);\n    \n    public static K<M, string> downloadBase64(Uri uri) =>\n        download(uri).Map(Convert.ToBase64String);\n    \n    public static K<M, byte[]> download(Uri uri) =>\n        from c in client\n        from t in trait\n        from r in liftIO(() => t.Download(uri, c))\n        select r;\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/GlobalUsings.cs",
    "content": "global using LanguageExt;\nglobal using LanguageExt.Sys;\nglobal using LanguageExt.Sys.IO;\nglobal using LanguageExt.Traits;\nglobal using LanguageExt.Common;\nglobal using LanguageExt.Sys.Traits;\nglobal using static LanguageExt.Prelude;\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/JsonExtensions.cs",
    "content": "using System.Text.Json;\n\nnamespace Newsletter;\n\npublic static class JsonExtensions\n{\n    public static JsonElement Get(this JsonElement element, string key)\n    {\n        try\n        {\n            return element.GetProperty(key);\n        }\n        catch (KeyNotFoundException)\n        {\n            throw new KeyNotFoundException($\"'{key}' not found\");\n        }\n    }\n\n    public static Iterable<JsonElement> Enumerate(this JsonElement element) =>\n        element\n            .EnumerateArray()\n            .AsIterable();\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Newsletter.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n        <UserSecretsId>fbefbe46-9ced-4f15-92b1-db45597ea1e3</UserSecretsId>\n    </PropertyGroup>\n    <ItemGroup>\n      <PackageReference Include=\"CsvHelper\" Version=\"33.0.1\" />\n      <PackageReference Include=\"Microsoft.Extensions.Configuration.UserSecrets\" Version=\"8.0.0\" />\n      <PackageReference Include=\"SendGrid\" Version=\"9.29.3\" />\n      <PackageReference Include=\"SixLabors.ImageSharp\" Version=\"3.1.11\" />\n      <DotNetCliToolReference Include=\"Microsoft.Extensions.SecretManager.Tools\" Version=\"2.0.2\" />\n    </ItemGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n      <ProjectReference Include=\"..\\..\\..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Newsletter.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Newsletter\", \"Newsletter.csproj\", \"{C6A964F8-57F7-4AA6-8A4F-A5847CDB4F9B}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{C6A964F8-57F7-4AA6-8A4F-A5847CDB4F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C6A964F8-57F7-4AA6-8A4F-A5847CDB4F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C6A964F8-57F7-4AA6-8A4F-A5847CDB4F9B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C6A964F8-57F7-4AA6-8A4F-A5847CDB4F9B}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/Program.cs",
    "content": "﻿using System.Text.Json;\nusing Microsoft.Extensions.Configuration.UserSecrets;\nusing Newsletter.Command;\nusing Newsletter.Effects;\n\n// Setup\nvar path        = args is [_, var p] ? p : Environment.CurrentDirectory;\nvar secrets     = loadUserSecrets();\nvar sendGridKey = secrets.Find(\"SendGridKey\");\nvar runtime     = args is [\"live\", ..]\n                     ? Runtime.Live(path, sendGridKey)\n                     : Runtime.Test(path, sendGridKey);\n\n// Run\nvar result = Send<Eff<Runtime>, Runtime>\n                .newsletter\n                .Run(runtime);\n\n// Show results\nswitch (result)\n{\n    case Fin<Unit>.Succ:\n        Console.WriteLine(\"Complete\");\n        break;\n    \n    case Fin<Unit>.Fail (var error):\n        Console.WriteLine(error);\n        break;\n}\n\n// Loads the user-secrets controlled by \"dotnet user-secrets\" \nHashMap<string, string> loadUserSecrets()\n{\n    var userSecretsId = \"fbefbe46-9ced-4f15-92b1-db45597ea1e3\";\n    var path          = PathHelper.GetSecretsPathFromSecretsId(userSecretsId);\n    var text          = File.ReadAllText(path);\n    var json          = JsonDocument.Parse(text);\n    return json.RootElement\n               .EnumerateObject()\n               .AsIterable()\n               .Map(e => (e.Name, e.Value.GetString() ?? \"\"))\n               .ToHashMap();\n}\n"
  },
  {
    "path": "Samples/Newsletter/Newsletter/UI/Display.cs",
    "content": "using Newsletter.Data;\n\nnamespace Newsletter.UI;\n\npublic static class Display<M, RT>\n    where RT : \n        Has<M, ConsoleIO>\n    where M :\n        MonadIO<M>,\n        Fallible<M>\n{\n    public static K<M, Unit> emptyLine =>\n        Console<M, RT>.writeEmptyLine;\n    \n    public static K<M, Unit> writeLine(string line) =>\n        Console<M, RT>.writeLine(line);\n    \n    public static K<M, Unit> confirmSent =>\n        Console<M, RT>.writeLine(\"Newsletter successfully sent to members\");\n    \n    public static K<M, Unit> error(Error err) =>\n        Console<M, RT>.writeLine(err.ToString());\n\n    public static K<M, Unit> showWhatsAboutToHappen(Seq<Member> members) =>\n        from _1 in writeLine($\"You're about to send the newsletter to {members.Count} members\")\n        from _2 in emptyLine\n        from _3 in writeLine(\"Below are some email addresses from the batch:\")\n        from _4 in members.Take(10)\n                          .Map(m => $\"\\t{m.Email}\")\n                          .Traverse(writeLine)\n        from _5 in emptyLine\n        from _6 in writeLine(\"Are you sure you want to send the emails? (y/n)\")\n        select unit;\n}\n"
  },
  {
    "path": "Samples/Newsletter/README.md",
    "content": "# newsletter\n\nNewsletter generator for my paullouth.com site\n\nThis shows off the effect system of language-ext and how to create and use runtimes."
  },
  {
    "path": "Samples/Newsletter/members-test/members.2024-07-29.csv",
    "content": "id,email,name,note,subscribed_to_emails,complimentary_plan,stripe_customer_id,created_at,deleted_at,labels,tiers\n65f31f852ac0342e8bc9373e,paul@example.com,Paul Louth,,true,,,2024-03-14T16:02:13.000Z,,,\n66a73e0798be6a03e27d0e12,alan@example.com,Alan Turing,,true,,,2024-07-29T07:00:23.000Z,,,\n65ddcee799e5fbe500fe8da7,isaac@example.com,Isaac Newton,,true,,,2024-02-27T12:00:39.000Z,,,\n65de0dd899e5fbe500fe8e7f,sophie@example.com,Sophie Wilson,,true,,,2024-02-27T16:29:12.000Z,,,\n65de17aa99e5fbe500fe8e87,delia@example.com,\"Delia Derbyshire\",,true,,,2024-02-27T17:11:06.000Z,,,\n"
  },
  {
    "path": "Samples/Newsletter/templates/email.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Notes from a Small Functional Island</title>\n</head>\n<body>\n  <div style=\"background-color: rgb(255, 255, 255); font-family: sans-serif\">\n    <div>\n      <div style=\"text-align: center;\">\n        <h3>Notes from a Small Functional Island by Paul Louth</h3>\n        <h2>[POST_TITLE]</h2>\n        <div>\n          <p>\n            By Paul Louth\n            <span>[POST_DATE]</span>\n          </p>\n        </div>\n      </div>\n      <div style=\"text-align: center;\">\n        <a href=\"[POST_URL]\"><img alt=\"Feature\" src=\"[FEATURE_IMAGE_URL]\" style=\"width: 400px\"></a>\n      </div>\n      <div>\n        <div style=\"margin:20px; border: solid 10px darkred; border-radius: 5px; text-align: center;\">\n          <p>\n            <b>A short message from Paul</b>\n          </p>\n          <p>\n            I thought it would be novel to include the full article as the email newsletter.\n            I don't really care about clicks or any of that nonsense and so this is another\n            potential way to consume the article (that may even be more accessible for some)!\n          </p>\n          <p>\n            However, due to the way that email clients format and butcher HTML, the experience might not be as good. I have noticed that, on my iPhone, the code snippets get line-wrapped, making them pretty hard to decipher.  Still, I like the idea that if you've downloaded emails to your device, you can read the article offline, so I'm going to go with it for now. Feel free to let me know what you think.\n          </p>\n          <p>\n            <a href=\"[POST_URL]\"><span>But it is better to read the original article on paullouth.com</span></a>\n          </p>\n          <p>\n            The formatting is much better there!\n          </p>\n        </div>\n      </div>\n      <div>\n        [POST_CONTENT]\n      </div>\n      <div>\n        <h3>Keep reading</h3>\n        <div>\n          [RECENT_ARTICLES]\n        </div>\n      </div>\n      <div>\n        <div style=\"color:#777; text-align: center; margin-top: 30px;\">\n          <p>Paul Louth © [YEAR_RANGE]</p>\n          <p>\n            <span>You're receiving this email because you signed up to the newsletter at <a href=\"https://paullouth.com\">paullouth.com</a>.</span>\n            <span>You can unsubscribe by going to the site, logging in, and toggling the 'Email Newsletter' option.</span>\n            <span>Any problems or if you need to reach out for any reason, drop me an email to: paul@paullouth.com</span>\n          </p>\n        </div>\n      </div>\n    </div>\n  </div>  \n</body>\n</html>"
  },
  {
    "path": "Samples/Newsletter/templates/email.txt",
    "content": "# Notes from a Small Functional Island\n\n## [POST_TITLE]\n\nBy Paul Louth - [POST_DATE]\n\nRead the original article on paullouth.com at: [POST_URL]\n\n[POST_CONTENT]\n\n## Keep reading\n\n[RECENT_ARTICLES]\n\nPaul Louth © [YEAR_RANGE]\n\nYou're receiving this email because you signed up to the newsletter at https://paullouth.com.  \nYou can unsubscribe by going to the site, logging in, and toggling the 'Email Newsletter' option.  Any problems or if you need to reach out for any reason, drop me an email to: paul@paullouth.com\n"
  },
  {
    "path": "Samples/Newsletter/templates/recent-item.html",
    "content": "      <div style=\"border:solid 1px gray; margin: 2px; border-radius: 4px;\">\n        <div style=\"display: flex; flex-direction: row\">\n          <div style=\"padding: 10px; flex-grow: 1\">\n            <div><a href=\"[URL]\"><h4>[TITLE]</h4></a></div>\n            <div>[EXCERPT]</div>\n          </div>  \n          <div style=\"padding: 10px; width:170px; vertical-align: middle; background-color: #eee;\">\n            <a href=\"[URL]\">\n              <img alt=\"[TITLE]\" src=\"[IMAGE_URL]\" style=\"width:170px\">\n            </a>\n          </div>  \n        </div>  \n      </div>\n"
  },
  {
    "path": "Samples/Newsletter/templates/recent-item.txt",
    "content": "* [TITLE]\n  [EXCERPT]\n  [URL]\n\n"
  },
  {
    "path": "Samples/PipesExamples/PipesExamples.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n      <ProjectReference Include=\"..\\..\\LanguageExt.Streaming\\LanguageExt.Streaming.csproj\" />\n      <ProjectReference Include=\"..\\..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Samples/PipesExamples/Program.cs",
    "content": "using System.Diagnostics;\nusing System.Net.Sockets;\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing static LanguageExt.Pipes.ProducerT;\nusing static LanguageExt.Pipes.PipeT;\nusing static LanguageExt.Pipes.ConsumerT;\nusing static LanguageExt.Prelude;\n\nvar prod = yieldAll<IO, int>(Range(1, 100));\n\nvar pipe = from x in awaiting<IO, int, int>()\n           from _ in x == 10\n                         ? endOfStream<int, int>()\n                         : yield<IO, int, int>(x)\n           select unit;\n\nvar cons = from x in awaiting<IO, int>()\n           from _ in writeLine(x)\n           select unit;\n\nvar effect = prod | pipe | cons;\n\nvar result = effect.RunToEnd().Run();\n\nstatic PipeT<IN, OUT, IO, Unit> endOfStream<IN, OUT>() =>\n    error<IN, OUT, IO, Unit>(Errors.EndOfStream);\n\nstatic IO<Unit> writeLine(object? value) =>\n    IO.lift(() => Console.Write($\"{value} \"));\n\npublic record Slice<A>(int Length, int Offset, byte[] Buffer);\n\npublic static class EffectExtensions\n{\n    public static K<M, Unit> RunToEnd<M>(this EffectT<M, Unit> effect)\n        where M : MonadIO<M>, Fallible<M> =>\n        effect.Run()\n      | @catch(Errors.EndOfStream, pure<M, Unit>(unit));\n}\n\n\n/*\nvar p = yieldAll<IO, int>(Range(1, 10000000));\n\nvar o = foldUntil(Time: Schedule.spaced(10) | Schedule.recurs(3), \n                  Fold: (s, v) => s + v,\n                  Pred: v => v.Value % 10000 == 0,\n                  Init: 0,\n                  Item: awaiting<IO, int, int>());\n\nvar c = from x in awaiting<IO, int>()\n        from _ in writeLine($\"{x}\")\n        select unit;\n\nvar e = p | o | c;\n\nvar r = e.Run().Run();\n\nConsole.WriteLine(\"Done\");\n\nstatic IO<Unit> writeLine(object? value) =>\n    IO.lift(() => Console.WriteLine(value));\n    */\n"
  },
  {
    "path": "Samples/Streams/Console.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\n// Simple IO wrappers of Console \npublic static class Console\n{\n    public static readonly IO<Unit> emptyLine =\n        lift(System.Console.WriteLine);\n\n    public static IO<Unit> setForegroundColour(ConsoleColor colour) =>\n        lift(() => System.Console.ForegroundColor = colour).Map(_ => unit);\n\n    public static IO<ConsoleColor> colour =>\n        lift(() => System.Console.ForegroundColor);\n    \n    public static readonly IO<Unit> red =\n        setForegroundColour(ConsoleColor.Red);\n\n    public static readonly IO<Unit> green =\n        setForegroundColour(ConsoleColor.Green);\n\n    public static readonly IO<Unit> yellow =\n        setForegroundColour(ConsoleColor.Yellow);\n\n    public static readonly IO<Unit> cyan =\n        setForegroundColour(ConsoleColor.Cyan);\n\n    public static readonly IO<Unit> magenta =\n        setForegroundColour(ConsoleColor.Magenta);\n\n    public static IO<Unit> writeLine<A>(A? line) =>\n        lift(() => System.Console.WriteLine(line?.ToString() ?? \"(null)\"));\n\n    public static IO<Unit> write<A>(A? text) =>\n        lift(() => System.Console.Write(text?.ToString() ?? \"(null)\"));\n\n    public static IO<string> readLine =>\n        lift(() => System.Console.ReadLine() ?? \"\");\n\n    public static IO<ConsoleKeyInfo> readKey =>\n        IO.lift(System.Console.ReadKey) >> writeLine(\"\");\n}\n"
  },
  {
    "path": "Samples/Streams/CountForever.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Pipes;\nusing static LanguageExt.Prelude;\nusing static Streams.Console;\n\nnamespace Streams;\n\npublic static class CountForever\n{\n    public static IO<Unit> run =>\n        from f in fork(example.Iter()).As()\n        from k in readKey\n        from r in f.Cancel \n        select unit;\n\n    static SourceT<IO, long> naturals =>\n        SourceT.lift<IO, long>(Range(0, long.MaxValue));\n    \n    static SourceT<IO, Unit> example =>\n        from v in naturals\n        where v % 10000 == 0\n        from _ in writeLine($\"{v:N0}\")\n        where false\n        select unit;\n}\n"
  },
  {
    "path": "Samples/Streams/CountForeverAsync.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\nusing static Streams.Console;\n\nnamespace Streams;\n\npublic static class CountForeverAsync\n{\n    public static IO<Unit> run =>\n        from f in fork(example.Iter()).As()\n        from k in readKey\n        from r in f.Cancel \n        select unit;\n\n    static SourceT<IO, long> naturals =>\n        SourceT.lift<IO, long>(naturalsEnum());\n    \n    static SourceT<IO, Unit> example =>\n        from v in naturals\n        from _ in writeLine($\"{v:N0}\")\n        where false\n        select unit;\n\n    static async IAsyncEnumerable<long> naturalsEnum()\n    {\n        for (var i = 0L; i < long.MaxValue; i++)\n        {\n            yield return i;\n            await Task.Delay(1000);\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/Streams/Folding.cs",
    "content": "using LanguageExt;\nusing static Streams.Console;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\npublic static class Folding\n{\n    public static IO<Unit> run =>\n        example(1000).Iter().As();\n\n    static SourceT<IO, int> naturals(int n) =>\n        Range(0, n).AsSourceT<IO, int>();\n    \n    static SourceT<IO, Unit> example(int n) =>\n        from v in naturals(n).FoldUntil((s, x) => s + x, s => s.State % 4 == 0, 0)\n        where v % 10 == 0\n        from _ in writeLine(v)\n        select unit;\n}\n"
  },
  {
    "path": "Samples/Streams/Grouping.cs",
    "content": "using LanguageExt;\nusing static Streams.Console;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\n/// <summary>\n/// Based on 'Grouping effects' from 'ListT done right'\n///\n/// https://wiki.haskell.org/ListT_done_right\n/// </summary>\npublic static class Grouping\n{\n    public static IO<Unit> run =>\n        runTestIO(\"test 1\", test1) >>\n        runTestIO(\"test 2\", test2);\n\n    static IO<Unit> runTestIO(string name, SourceT<IO, int> test) =>\n        runTest(name, test1).Iter().As() >> emptyLine;\n\n    static SourceT<IO, Unit> runTest(string name, SourceT<IO, int> test) =>\n        from t in writeLine($\"{name}\")\n        from r in test\n        from _ in write($\"{r} \")\n        where false\n        select unit;\n\n    static SourceT<IO, int> test1 =\n        from r in atomIO(0)\n        from n in next(r) + next(r) >> (next(r) + next(r) >> next(r) + next(r))\n        select n;\n\n    static SourceT<IO, int> test2 =\n        from r in atomIO(0)\n        from n in (next(r) + next(r) >> next(r) + next(r)) >> next(r) + next(r)\n        select n;\n\n    static SourceT<IO, int> next(Atom<int> atom) =>\n        from x in valueIO(atom)\n        from _ in writeIO(atom, x + 1)\n        select x;\n}\n"
  },
  {
    "path": "Samples/Streams/HeadsAndTails.cs",
    "content": "/*\nusing LanguageExt;\nusing LanguageExt.Streaming;\nusing static Streams.Console;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\npublic static class HeadsAndTails\n{\n    static readonly StreamT<IO, int> collection = \n        from item in Iterable(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).AsStream<IO, int>()\n        from col  in colour >> \n                     red\n        from _    in writeLine($\"\\tEvaluated item: {item}\") >> \n                     setForegroundColour(col)\n        select item;\n\n    public static IO<Unit> run =>\n        headExample >>\n        tailExample.Run();\n\n    static IO<Unit> headExample =>\n        from _ in writeLine(\"Head example\")\n        from h in collection.Head()\n        from x in writeLine($\"\\tHead is: {h}\")\n        select unit;\n\n    static StreamT<IO, Unit> tailExample =>\n        from _ in writeLine(\"Tail example\")\n        from x in collection.Tail()\n        from y in writeLine($\"\\tYielded: {x}\")\n        where false\n        select unit;\n    \n}\n*/\n"
  },
  {
    "path": "Samples/Streams/Menu.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\nusing static Streams.Console;\n\nnamespace Streams;\n\npublic static class Menu\n{\n    public static IO<Unit> run =>\n        from _  in introduction\n        from ky in readKey >> green\n        from ex in ky.Key switch\n                   {\n                       ConsoleKey.D1 => CountForever.run,\n                       ConsoleKey.D2 => CountForeverAsync.run,\n                       ConsoleKey.D3 => SumOfSquares.run,\n                       ConsoleKey.D4 => Grouping.run,\n                    // ConsoleKey.D5 => HeadsAndTails.run,\n                       ConsoleKey.D6 => Folding.run,\n                       ConsoleKey.D7 => Merging.run,\n                       ConsoleKey.D8 => Zipping.run,\n                       ConsoleKey.D9 => OptionalItems.run,\n                       ConsoleKey.D0 => SourceStream.run,\n                       ConsoleKey.X  => RecursionIO.run,\n                       _             => unitIO\n                   }\n        from _1 in run\n        select ex;\n\n    static IO<Unit> introduction =>\n        cyan                                                          >>\n        writeLine(\"Examples\")                                         >>\n        writeLine(\"1. Count forever\")                                 >>\n        writeLine(\"2. Count forever (async, with per-item 1s delay)\") >>\n        writeLine(\"3. Sum of squares\")                                >>\n        writeLine(\"4. Grouping test\")                                 >>\n        writeLine(\"5. Heads and tails [DEPRECATED]\")                  >>\n        writeLine(\"6. Folding\")                                       >>\n        writeLine(\"7. Merging\")                                       >>\n        writeLine(\"8. Zipping\")                                       >>\n        writeLine(\"9. Optional items\")                                >>\n        writeLine(\"0. Source stream\")                                 >>\n        writeLine(\"Enter a number for the example you wish to run\");\n}\n"
  },
  {
    "path": "Samples/Streams/Merging.cs",
    "content": "using LanguageExt;\nusing static Streams.Console;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\npublic static class Merging\n{\n    public static IO<Unit> run =>\n        example(20).Iter().As() >>\n        emptyLine;\n\n    static SourceT<IO, Unit> example(int n) =>\n        from v in evens(n) | odds(n)\n        where false\n        select unit;\n    \n    static SourceT<IO, int> evens(int n) =>\n        from x in Range(0, n).AsSourceT<IO, int>()\n        where isEven(x)\n        from _ in magenta >> write($\"{x} \")\n        select x;\n\n    static SourceT<IO, int> odds(int n) =>\n        from x in Range(0, n).AsSourceT<IO, int>()\n        where isOdd(x)\n        from _ in yellow >> write($\"{x} \")\n        select x;\n    \n    static bool isOdd(int n) =>\n        (n & 1) == 1;\n\n    static bool isEven(int n) =>\n        !isOdd(n);\n}\n"
  },
  {
    "path": "Samples/Streams/OptionalItems.cs",
    "content": "using LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\npublic static class OptionalItems\n{\n    public static IO<Unit> run =>\n        from _0 in Console.writeLine(\"starting\")\n        from _1 in example(100).Iter()\n        from _2 in Console.writeLine(\"done\")\n        select unit;\n\n    static SourceT<OptionT<IO>, Unit> example1(int n) =>\n        from x in SourceT.liftM(asyncStream(n))\n        from _ in Console.write($\"{x} \")\n        where false\n        select unit;    \n\n    static SourceT<IO, Unit> example(int n) =>\n        from x in asyncStream(n).SomeSource()\n        from _ in Console.write($\"{x} \")\n        where false\n        select unit;\n\n    static bool isAllowed(int x) =>\n        (x & 1) == 1;\n    \n    static async IAsyncEnumerable<OptionT<IO, int>> asyncStream(int n) \n    {\n        foreach (var x in Range(1, n))\n        {\n            var option = isAllowed(x)\n                             ? OptionT.lift(IO.pure(x))\n                             : OptionT<IO, int>.None;\n\n            var r = await Task.FromResult(option);\n            yield return r;\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/Streams/Program.cs",
    "content": "﻿using Streams;\n\nMenu.run.Run();\n"
  },
  {
    "path": "Samples/Streams/RecursionIO.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Common;\nusing static Streams.Console;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\npublic static class RecursionIO\n{\n    public static IO<Unit> run =>\n        from _ in writeLine(\"Enter a number to count from\")\n        from s in readLine\n        from n in parseInt<IO>(s) | IO.fail<int>(\"expected a number!\")\n        from r in recurse(n) >>\n                  emptyLine\n        select r;\n\n    public static IO<Unit> recurse(int n) =>\n        from _ in write($\"{n} \")\n        from r in when(n > 0, recurse(n - 1))\n        select r;\n}\n"
  },
  {
    "path": "Samples/Streams/SourceStream.cs",
    "content": "using LanguageExt;\nusing static Streams.Console;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\npublic class SourceStream\n{\n    public static IO<Unit> run =>\n        from c in ConduitT.makeM<IO, string>()\n        from f in fork(subscribe(c.Source).Iter())\n        from _ in writeLine(\"Type something and press enter (empty-line ends the demo)\") >>\n                  interaction(c.Sink)\n        select unit;\n\n    static IO<Unit> interaction(SinkT<IO, string> sink) =>\n        repeat(from l in readLine\n               from _ in deliver(sink, l)\n               select unit) \n      | @catch(unitIO);\n\n    static IO<Unit> deliver(SinkT<IO, string> sink, string line) =>\n        guardIO(line != \"\") >>\n        sink.Post(line);\n\n    static SourceT<IO, Unit> subscribe(SourceT<IO, string> source) =>\n        from v in source\n        from _ in writeLine(v)\n        where false\n        select unit;\n}\n"
  },
  {
    "path": "Samples/Streams/Streams.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n        <RootNamespace>Streams</RootNamespace>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n      <ProjectReference Include=\"..\\..\\LanguageExt.Streaming\\LanguageExt.Streaming.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Samples/Streams/SumOfSquares.cs",
    "content": "using LanguageExt;\nusing LanguageExt.Traits;\nusing static Streams.Console;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\n/// <summary>\n/// Based on 'Sum of squares' from 'ListT done right'\n///\n/// https://wiki.haskell.org/ListT_done_right\n/// </summary>\npublic static class SumOfSquares\n{\n    public static IO<Unit> run =>\n        from _ in writeLine(\"Enter a number to find the sum of squares\")\n        from s in readLine\n        from n in parseLong<IO>(s) | IO.fail<long>(\"expected a number!\")\n        from x in example(n).Iter()\n        select unit;\n\n    static SourceT<M, long> squares<M>(long n)\n        where M : MonadIO<M>, Alternative<M> =>\n        SourceT.lift<M, long>(Range(0, n).Select(v => v * v).Where(v => v <= n));\n\n    static SourceT<IO, (long X, long Y)> example(long n) =>\n        from x in squares<IO>(n)\n        from y in squares<IO>(n)\n        where x + y == n\n        from _ in writeLine($\"Sum of squares! {(x, y)}\")\n        where false\n        select (x, y);\n}\n"
  },
  {
    "path": "Samples/Streams/Zipping.cs",
    "content": "using LanguageExt;\nusing static Streams.Console;\nusing static LanguageExt.Prelude;\n\nnamespace Streams;\n\npublic static class Zipping\n{\n    public static IO<Unit> run =>\n        example(10).Iter().As();\n\n    static SourceT<IO, Unit> example(int n) =>\n        from v in evens(n).Zip(odds(n))\n        from _ in writeLine(v)\n        select unit;\n\n    static SourceT<IO, int> evens(int n) =>\n        from x in Range(0, n).AsSourceT<IO, int>()\n        where isEven(x)\n        select x;\n\n    static SourceT<IO, int> odds(int n) =>\n        from x in Range(0, n).AsSourceT<IO, int>()\n        where isOdd(x)\n        select x;\n    \n    static bool isOdd(int n) =>\n        (n & 1) == 1;\n\n    static bool isEven(int n) =>\n        !isOdd(n);\n}\n"
  },
  {
    "path": "Samples/TestBed/ApplicativeTest.cs",
    "content": "﻿using LanguageExt.Common;\n\nnamespace TestBed;\n\nusing System;\nusing System.Diagnostics;\nusing LanguageExt;\nusing System.Threading.Tasks;\nusing static LanguageExt.Prelude;\n\npublic static class ApplicativeTest\n{\n    static Eff<Unit> delay(int milliseconds) =>\n        liftIO(async () =>\n            {\n                await Task.Delay(milliseconds);\n                return unit;\n            });\n\n    static Eff<int> parse(string str) =>\n        from x in parseInt(str).ToEff(Error.New($\"parse error: expected int, got: '{str}'\"))\n        from _ in delay(10000)\n        select x;\n\n    static Eff<int> add(string sa, string sb, string sc, string sd, string se, string sf) =>\n        SuccessEff(curry<int, int, int, int, int, int, int>(addPure)) \n            .Apply(parse(sa))\n            .Apply(parse(sb))\n            .Apply(parse(sc))\n            .Apply(parse(sd))\n            .Apply(parse(se))\n            .Apply(parse(sf));\n\n    static int addPure(int a, int b, int c, int d, int e, int f) =>\n        a + b + c + d + e + f;\n\n    public static void Test()\n    {\n        report(add(\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"));\n        report(add(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"));\n    }\n\n    static void report<A>(Eff<A> ma)\n    {\n        var sw = Stopwatch.StartNew();\n        var r = ma.Run();\n        sw.Stop();\n        Console.WriteLine($\"Result: {r} in {sw.ElapsedMilliseconds}ms\");\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/AtomHashMapTests.cs",
    "content": "using System;\nusing System.Reactive.Linq;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic class AtomHashMapTests\n{\n    public static void Test()\n    {\n        var thm = TrackingHashMap<int, string>();\n\n        Console.WriteLine(thm);\n\n        thm = thm.Add(100, \"World\");\n        thm = thm.Snapshot();\n        thm = thm.SetItem(100, \"Hello\");\n\n        Console.WriteLine(thm.Changes);\n \n        var xs = AtomHashMap<string, int>();\n\n        xs.OnEntryChange().Subscribe(pair => Console.WriteLine(pair));\n            \n        xs.Add(\"Hello\", 456);\n        xs.SetItem(\"Hello\", 123);\n        xs.Remove(\"Hello\");\n        xs.Remove(\"Hello\");\n\n        var rx = Ref(\"Hello\");\n        var ry = Ref(\"World\");\n\n        Observable.Merge(rx.OnChange(), \n                         ry.OnChange())\n                  .Subscribe(Console.WriteLine);\n\n        atomic(() =>\n               {\n                   swap(rx, x => $\"1. {x}\");\n                   swap(ry, y => $\"2. {y}\");\n               });\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/AwaitAnyTest.cs",
    "content": "using System;\nusing LanguageExt;\nusing System.Threading.Tasks;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic class AwaitAnyTest\n{\n    public static void Run()\n    {\n        Console.WriteLine(\"Started\");\n\n        var eff = awaitAny(uninterruptible(delayed(\"A\", 9)),\n                           uninterruptible(delayed(\"B\", 7)),\n                           uninterruptible(delayed(\"C\", 5)));\n\n        using var env = EnvIO.New();\n        ignore(eff.Run(env));\n        \n        Console.ReadKey();\n        env.Source.Cancel();\n        Console.WriteLine(\"Cancellation trigger, press any key to exit\");\n        Console.ReadKey();\n    }\n\n    static Eff<Unit> delayed(string info, int time) =>\n        Eff.lift(async e =>\n                 {\n                     await Task.Delay(time * 1000, e.Token);\n                     Console.WriteLine(info);\n                     return unit;\n                 });\n}\n"
  },
  {
    "path": "Samples/TestBed/BracketTest.cs",
    "content": "using System;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic class BracketTest\n{\n    class Test : IDisposable\n    {\n        public void Dispose()\n        {\n            Console.WriteLine(\"Disposing Test\");\n        }\n    }\n\n    public static void Run()\n    {\n        var workflow = bracketIO(\n            from d in use(() => new Test())\n          //from _ in fail()\n            select d\n        );\n        ignore(workflow.Run());\n    }\n\n    static IO<Unit> fail() =>\n        IO.lift(() => throw new Exception(\"boom\"));\n\n}\n"
  },
  {
    "path": "Samples/TestBed/FreeTests.cs",
    "content": "﻿using System;\nusing System.IO;\nusing LanguageExt;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic abstract record Op<A> : K<Op, A>;\npublic record ReadLinesOp<A>(string Path, Func<Seq<string>, A> Next): Op<A>;\npublic record WriteLinesOp<A>(string Path, Seq<string> Lines, Func<Unit, A> Next) : Op<A>;\n\npublic partial class Op : Functor<Op>\n{\n    public static K<Op, B> Map<A, B>(Func<A, B> f, K<Op, A> ma) =>\n        ma switch\n        {\n            ReadLinesOp<A> (var path, var next)             => new ReadLinesOp<B>(path, x => f(next(x))),\n            WriteLinesOp<A> (var path, var lines, var next) => new WriteLinesOp<B>(path, lines, x => f(next(x)))\n        };\n}\n\npublic partial class Op\n{\n    public static Free<Op, Seq<string>> readLines(string path) =>\n        Free.lift(new ReadLinesOp<Seq<string>>(path, identity));\n\n    public static Free<Op, Unit> writeLines(string path, Seq<string> lines) =>\n        Free.lift(new WriteLinesOp<Unit>(path, lines, identity));\n}\n\npublic static class FreeTests\n{\n    public static void Test()\n    {\n        var repr = from lines in Op.readLines(\"c:\\\\temp\\\\test.txt\")\n                   from _     in Op.writeLines(\"c:\\\\temp\\\\test2.txt\", lines)\n                   select unit;\n\n        var comp = Interpret(repr);\n\n        comp.Run();\n    }\n\n    static IO<A> Interpret<A>(K<Free<Op>, A> ma) =>\n        ma switch\n        {\n            Pure<Op, A>(var value) => \n                IO.pure(value),\n            \n            Bind<Op, A>(var bind) =>\n                bind switch\n                {\n                    ReadLinesOp<Free<Op, A>> (var path, var next) => \n                        ReadLines(path).Map(next).Bind(Interpret),\n                    \n                    WriteLinesOp<Free<Op, A>> (var path, var lines, var next) => \n                        WriteLines(path, lines).Map(next).Bind(Interpret)\n                }\n        };\n\n    static IO<Seq<string>> ReadLines(string path) =>\n        IO.liftAsync(() => File.ReadAllLinesAsync(path)).Map(toSeq);\n\n    static IO<Unit> WriteLines(string path, Seq<string> lines) =>\n        IO.liftAsync(async () =>\n                     {\n                         await File.WriteAllLinesAsync(path, lines);\n                         return unit;\n                     });\n}\n"
  },
  {
    "path": "Samples/TestBed/Issues/Discussion1527.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace Issues;\n\npublic static class Discussion1527\n{\n    public static void Run()\n    {\n        Eff<IObservation> r1 = +Think<Eff>(1000);\n        IO<IObservation>  r2 = +Think<IO>(1000);\n\n        Console.WriteLine(r1.Run());\n        Console.WriteLine(r2.Run());\n\n        /*var res = Think(1000).Run();\n\n        Console.WriteLine($\"Output: {res}\");\n\n        var sum1 = Source.forever(1)\n                         .FoldWhile(\n                              (s, x) => s + x,\n                              (s, _) => s <= 10,\n                              0\n                          )\n                         .Take(1)\n                         .Last()\n                         .Run();\n\n        Console.WriteLine(sum1);\n\n        var sum2 = SourceT.forever<IO, int>(1)\n                          .FoldWhile(\n                               (s, x) => s + x,\n                               x => x.State <= 10,\n                               0\n                           )\n                          .As()\n                          .Take(1)\n                          .Last()\n                          .Run();\n\n        Console.WriteLine(sum2);*/\n    }\n\n    static IO<Seq<IObservation>> Think(Duration duration, Func<IObservation, bool>? predicate = null)\n    {\n        var observe = Observations<IO>()\n                         .FoldUntil((s, o) => s + o,\n                                    x => predicate?.Invoke(x.Value) ?? false,\n                                    Seq<IObservation>())\n                         .TakeFor(duration);\n\n        var timeout = SourceT.pure<IO, Seq<IObservation>>([]).Delay(duration);\n\n        return +(observe | timeout).Last();\n    }\n\n    static IO<Option<IObservation>> OneWithTimeout(Duration duration)\n    {\n        var empty        = SourceT.pure<IO, Option<IObservation>>(None);\n        var timeout      = empty.Delay(duration);\n        var observations = Observations<IO>().Map(Some);\n        return +(observations | timeout).Take(1).Last();\n    }\n    \n    static IO<Seq<IObservation>> AllForPeriod(Duration duration) =>\n        +Observations<IO>()\n           .TakeFor(duration)\n           .Collect();\n\n    static IO<Seq<IObservation>> AllForPeriod(Duration duration, Func<IObservation, bool> predicate) =>\n        +Observations<IO>()\n           .Filter(predicate)\n           .TakeFor(duration)\n           .Collect();\n\n    public static K<M, IObservation> Think<M>(Duration duration)\n        where M : MonadIO<M>, Fallible<M>, Alternative<M>\n    {\n        var empty        = SourceT.liftM(M.Empty<IObservation>());\n        var timeout      = empty.Delay(duration);\n        var observations = Observations<M>();\n\n        return (observations | timeout)\n                   .Take(1)\n                   .Last();\n    }\n    \n    public interface IObservation;\n\n    public record Obs(DateTime When) : IObservation;\n\n    static IObservation MakeObservation(DateTime dt)\n    {\n        //Console.WriteLine($\"Making observation: {dt.Ticks}\");\n        return new Obs(dt);\n    }\n\n    static SourceT<M, DateTime> tickTockIO<M>()\n        where M : MonadIO<M>, Alternative<M>\n    {\n        return from token in M.LiftIO(IO.token)\n               from value in SourceT.lift<M, DateTime>(go(token))\n               select value;\n        \n        static async IAsyncEnumerable<DateTime> go(CancellationToken token)\n        {\n            while (true)\n            {\n                if(token.IsCancellationRequested) yield break;\n                await Task.Delay(TimeSpan.FromMilliseconds(5000), token);\n                var now = DateTime.Now;\n                yield return now;\n            }\n        }\n    }\n\n    public static SourceT<M, IObservation> Observations<M>() \n        where M : MonadIO<M>, Alternative<M> =>\n        tickTockIO<M>().Map(MakeObservation);\n\n    /*\n    public static IO<Option<IObservation>> Think(Duration duration) =>\n        Observations\n            .Take(1)\n            .TakeFor(duration)\n            .Last()\n            .Map(Some)\n        | NoObservations;\n\n\n    public static IO<Seq<IObservation>> Think2(Duration duration) =>\n        +Observations\n            .TakeFor(duration)\n            .Collect();*/\n    \n    static readonly IO<Option<IObservation>> NoObservations = \n        IO.pure<Option<IObservation>>(None);\n}\n"
  },
  {
    "path": "Samples/TestBed/Issues/Issue1497.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\n\nnamespace Issues;\n\nusing static AppPrelude;\nusing LanguageExt.Pipes;\nusing LanguageExt;\nusing static LanguageExt.Prelude;\nusing LanguageExt.Traits;\nusing System.Runtime.CompilerServices;\nusing System.Net.Sockets;\nusing System.Net;\nusing System.Text;\nusing LanguageExt.Common;\nusing LanguageExt.Sys;\nusing M = Application;\n\n\npublic static class AppPrelude\n{\n    public static void Test()\n    {\n        var effect = Module<M>.producer | Module<M>.pipe | Module<M>.consumer;\n// effect.Run().As().Run();\n        effect.Run().As().Run.Run(new (AtomHashMap((\"\", \"\")))).Run().Ignore();\n    }\n    \n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public static Application<A> As<A>(this K<Application, A> self) =>\n        (Application<A>)self;\n}\n\npublic record ApplicationState(AtomHashMap<string, string> Cache);\n\npublic record Application<A>(StateT<ApplicationState, IO, A> Run) : K<Application, A>;\n\npublic class Application\n: Deriving.Monad<Application, StateT<ApplicationState, IO>>,\n  Deriving.Stateful<Application, StateT<ApplicationState, IO>, ApplicationState>,\n  MonadIO<Application>\n{\n    public static K<Application, A> LiftIO<A>(IO<A> ma)\n    {\n        return new Application<A>(StateT.liftIO<ApplicationState, IO, A>(ma));\n    }\n\n    public static K<StateT<ApplicationState, IO>, A> Transform<A>(K<Application, A> fa)\n    {\n        return fa.As().Run;\n    }\n\n    public static K<Application, A> CoTransform<A>(K<StateT<ApplicationState, IO>, A> fa)\n    {\n        return new Application<A>(fa.As());\n    }\n\n    public static K<Application, A> Actions<A>(IterableNE<K<Application, A>> fas) =>\n        new Application<A>(\n            from s in StateT.get<IO, ApplicationState>()\n            from r in fas.Select(fa => fa.As().Run.Run(s).Kind()).Actions()\n            from _ in StateT.put<IO, ApplicationState>(r.State)\n            select r.Value);\n}\n\npublic static class Module<M>\nwhere M : MonadIO<M>\n{\n    public static ProducerT<int, M, Unit> producer =>\n        from _1 in IO.lift(() => System.Console.WriteLine(\"Producer\"))\n        from _2 in ProducerT.yieldRepeatIO<M, int>(IO.pure(1))\n        select unit;\n\n    public static PipeT<int, int, M, Unit> pipe =\n        from i  in PipeT.awaiting<M, int, int>() \n        from _1 in IO.lift(() => System.Console.WriteLine(\"Pipe\"))\n        from _2 in PipeT.yield<M, int, int>(i)\n        select unit;\n\n    public static ConsumerT<int, M, Unit> consumer =\n        from x in ConsumerT.awaiting<M, int>()\n        from _1 in IO.lift(() => System.Console.WriteLine(\"Consumer\"))\n        select unit;\n}\n"
  },
  {
    "path": "Samples/TestBed/Issues/IssueTests.cs",
    "content": "using System;\nusing System.Runtime.Serialization;\nusing LanguageExt;\n\nnamespace Issues;\n\npublic static class Issue1453\n{\n    public static void Test()\n    {\n        Deserialize(\"invalid\")\n            .BindFail(_ => Fallback())\n            .Match(Succ: time =>\n                         {\n                             Console.WriteLine(time);\n                             return Unit.Default;\n                         },\n                   Fail: _ =>\n                         {\n                             Console.WriteLine(\"Fail\");\n                             return Unit.Default;\n                         });\n\n        Try<DateTime> Deserialize(string dateTime) =>\n            Try.lift<DateTime>(() => throw new SerializationException());\n    \n        Try<DateTime> Fallback() =>\n            Try.Succ(DateTime.MinValue);\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/PipesTest.cs",
    "content": "﻿using System;\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Pipes;\nusing LanguageExt.Sys;\nusing LanguageExt.Sys.Live;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Pipes.Producer;\nusing static LanguageExt.Pipes.Consumer;\nusing static LanguageExt.Pipes.Pipe;\nusing static LanguageExt.UnitsOfMeasure;\n\nnamespace TestBed;\n\npublic static class PipesTestBed\n{\n    static Producer<Runtime, int, Unit> numbers(int n, int failOn) =>\n        from _ in yield<Runtime, int>(n)\n        from t in Time<Runtime>.sleepFor(1000 * ms)\n        from x in failOn == n \n                    ? FailEff<Runtime, Unit>(Error.New($\"failed on {n}\")) \n                    : unitEff\n        from r in n < 0 \n                    ? Pure(unit) \n                    : numbers(n - 1, failOn)\n        select r;\n    \n    public static Effect<Runtime, Unit> effect => \n        merge(numbers(10, 5), numbers(20, 0)) | writeLine<int>();\n    \n    static Consumer<Runtime, X, Unit> writeLine<X>() =>\n        from x in awaiting<Runtime, X>()\n        from _ in Console<Runtime>.writeLine($\"{x}\")\n        from r in writeLine<X>()\n        select r;\n    \n    public static Effect<Runtime, Unit> effect1 => \n        repeat(producer) | doubleIt | consumer;\n\n    static Producer<Runtime, int, Unit> producer =>\n        from _1 in Console<Runtime>.writeLine(\"before\")\n        from _2 in yieldAll<Runtime, int>(Range(1, 5))\n        from _3 in Console<Runtime>.writeLine(\"after\")\n        select unit;\n\n     static Pipe<Runtime, int, int, Unit> doubleIt =>\n        from x in awaiting<Runtime, int, int>()\n        from _ in yield<Runtime, int, int>(x * 2)\n        select unit;\n    \n    static Consumer<Runtime, int, Unit> consumer =>\n        from i in awaiting<Runtime, int>()\n        from _ in Console<Runtime>.writeLine(i.ToString())\n        from r in consumer\n        select r;\n}\n"
  },
  {
    "path": "Samples/TestBed/Program.cs",
    "content": "﻿////////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                                                                                    //\n//                                                                                                    //\n//     NOTE: This is just my scratch pad for quickly testing stuff, not for human consumption         //\n//                                                                                                    //\n//                                                                                                    //\n////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nusing System;\nusing System.Collections.Generic;\nusing LanguageExt;\nusing System.Threading.Tasks;\nusing Issues;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing TestBed;\nusing static LanguageExt.Prelude;\n\n\npublic class Program\n{\n    static void Main(string[] args)\n    {\n        ////////////////////////////////////////////////////////////////////////////////////////////////////////\n        //                                                                                                    //\n        //                                                                                                    //\n        //     NOTE: This is just my scratch pad for quickly testing stuff, not for human consumption         //\n        //                                                                                                    //\n        //                                                                                                    //\n        ///////////////////////////////////////////v////////////////////////////////////////////////////////////\n\n        Discussion1527.Run();\n        //SourceTTests.Run();\n        //Issues.Discussion1527.Run();\n        //RecurTests.Run();\n        //BracketTest.Run();\n        //AwaitAnyTest.Run();\n        //TestBed.StateStuff.StateForkIO.forkTest.Run(4).Run().Ignore();\n        //Issue1453.Test();\n        //UseTest.Main().GetAwaiter().GetResult();\n        //Issue1426().GetAwaiter().GetResult();\n        //SeqConstructTests.Test();\n        //ResourcesDiscussion1366.Run();\n        //StateTTest();\n        //AtomHashMapTests.Test();\n        //await AtomHashMapPerf.Test();\n        // await PipesTest();\n        // await ObsAffTests.Test();\n        // await AsyncTests();\n        //testing.Run(Runtime.New());\n        //var _ = QueueExample<Runtime>.Issue1065().RunUnit(new Runtime()).Result;\n        //ScheduleTests.Run();\n        //ApplicativeTest.Test().GetAwaiter().GetResult();\n        //Console.WriteLine(PipesTestBed.effect.RunEffect().Run(Runtime.New()).Result);\n        //Issue1230.Run();\n        //Issue1234.Test();\n        //SequenceParallelTest.Run();\n        //FreeTests.Test();\n\n        Console.WriteLine(\"Goodbye, World\");\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/RWSTTests.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\n\n/*\npublic record AppConfig(int X, int Y);\n\npublic record AppState(int Value)\n{\n    public AppState SetValue(int value) =>\n        this with { Value = value };\n}\n\npublic static class App\n{\n    public static App<M, A> As<M, A>(this K<App<M>, A> ma)\n        where M : Monad<M>, SemigroupK<M> =>\n        (App<M, A>)ma;\n    \n    public static K<M, (A Value, AppState State)> Run<M, A>(this K<App<M>, A> ma, AppConfig config, AppState state)\n        where M : Monad<M>, SemigroupK<M> =>\n        ma.As().runApp.Run(config, state).Map(\n            ma => ma switch\n                  {\n                      var (value, _, newState) => (value, newState)\n                  });\n\n    public static App<M, AppConfig> config<M>() \n        where M : Monad<M>, SemigroupK<M> =>\n        Readable.ask<App<M>, AppConfig>().As();\n\n    public static App<M, Unit> modify<M>(Func<AppState, AppState> f) \n        where M : Monad<M>, SemigroupK<M> =>\n        Stateful.modify<App<M>, AppState>(f).As();\n}\n\npublic class App<M> : \n    MonadT<App<M>, M>,\n    Readable<App<M>, AppConfig>,\n    Stateful<App<M>, AppState>\n    where M : Monad<M>, SemigroupK<M>\n{\n    public static K<App<M>, B> Bind<A, B>(K<App<M>, A> ma, Func<A, K<App<M>, B>> f) =>\n        new App<M, B>(ma.As().runApp.Bind(x => f(x).As().runApp));\n\n    public static K<App<M>, B> Map<A, B>(Func<A, B> f, K<App<M>, A> ma) => \n        new App<M, B>(ma.As().runApp.Map(f));\n\n    public static K<App<M>, A> Pure<A>(A value) => \n        new App<M, A>(RWST<AppConfig, Unit, AppState, M, A>.Pure(value));\n\n    public static K<App<M>, B> Apply<A, B>(K<App<M>, Func<A, B>> mf, K<App<M>, A> ma) => \n        new App<M, B>(mf.As().runApp.Apply(ma.As().runApp));\n\n    public static K<App<M>, A> Lift<A>(K<M, A> ma) => \n        new App<M, A>(RWST<AppConfig, Unit, AppState, M, A>.Lift(ma));\n\n    public static K<App<M>, A> Asks<A>(Func<AppConfig, A> f) => \n        new App<M, A>(RWST<AppConfig, Unit, AppState, M, A>.Asks(f));\n\n    public static K<App<M>, A> Local<A>(Func<AppConfig, AppConfig> f, K<App<M>, A> ma) => \n        new App<M, A>(ma.As().runApp.Local(f));\n\n    public static K<App<M>, Unit> Put(AppState value) => \n        new App<M, Unit>(RWST<AppConfig, Unit, AppState, M, Unit>.Put(value));\n\n    public static K<App<M>, Unit> Modify(Func<AppState, AppState> modify) => \n        new App<M, Unit>(RWST<AppConfig, Unit, AppState, M, Unit>.Modify(modify));\n\n    public static K<App<M>, A> Gets<A>(Func<AppState, A> f) => \n        new App<M, A>(RWST<AppConfig, Unit, AppState, M, A>.Gets(f));\n}\n\npublic readonly record struct App<M, A>(RWST<AppConfig, Unit, AppState, M, A> runApp) : K<App<M>, A>\n    where M : Monad<M>, SemigroupK<M>\n{\n    // Your application monad implementation\n}\n\npublic static class RwstTest\n{\n    static IO<Unit> writeLine(object value) =>\n        IO.lift(() => Console.WriteLine(value));\n\n    static void Test()\n    {\nvar app = from config in App.config<IO>()\n          from value  in App<IO>.Pure(config.X * config.Y)\n          from _1     in App.modify<IO>(s => s.SetValue(value)) \n          from _2     in writeLine(value) \n          select unit;\n    }\n}\n*/\n"
  },
  {
    "path": "Samples/TestBed/RecurTests.cs",
    "content": "using System;\nusing System.Diagnostics;\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\n\nnamespace TestBed;\n\npublic class RecurTests\n{\n    public static void Run()\n    {\n        recurIsSameAsBind<Seq>();\n        recurIsSameAsBind<Iterable>();\n        recurIsSameAsBind<Either<Error>>();\n        recurIsSameAsBind<Option>();\n        recurIsSameAsBind<Fin>();\n        recurIsSameAsBind<Try>((mx, my) => mx.Run() == my.Run()) ;\n\n        var xs = insertSort(3, [1, 2, 4]);\n    }\n\n    public static Seq<int> insertSort(int value, Seq<int> sorted) =>\n        sorted.IsEmpty || value < sorted[0] \n            ? value + sorted\n            : sorted[0] + insertSort(value, sorted.Tail);\n\n        \n    public static void recurIsSameAsBind()\n    {\n        var example = toSeq(Range(1, 20000)).Strict();\n\n        var result1 = Monad.recur((0, example), x => sumTail(x)); \n        var result2 = sumNoTail(0, example);\n\n        \n        Option<Next<(int Total, Seq<int> Values), int>> sumTail((int Total, Seq<int> Values) pair) =>\n            pair.Values switch\n            {\n                []          => Next.Done<(int Total, Seq<int> Values), int>(pair.Total),\n                var (x, xs) => Next.Loop<(int Total, Seq<int> Values), int>((pair.Total + x, xs)) \n            };\n\n        Option<int> sumNoTail(int total, Seq<int> values) =>\n            values switch\n            {\n                []          => Pure(total),\n                var (x, xs) => sumNoTail(total + x, xs)\n            };\n    }\n    \n    public static void recurIsSameAsBind<M>(Func<K<M, int>, K<M, int>, bool>? equals = null)\n        where M : Monad<M>\n    {\n        var example = toSeq(Range(1, 20000)).Strict();\n\n        Console.ForegroundColor = ConsoleColor.Yellow;\n        Console.WriteLine(\"------------------------------------------------------------------------------------------\");\n        Console.WriteLine($\"{typeof(M).Name}\");\n        Console.ForegroundColor = ConsoleColor.White;\n        \n        Console.WriteLine(\"Testing Monad.recur\");\n        var sw1     = Stopwatch.StartNew();\n        \n        var result1 = Monad.recur((0, example), sumTail);\n        \n        sw1.Stop();\n        Console.WriteLine($\"{sw1.Elapsed.Nanoseconds} ns\");\n\n        Console.WriteLine();\n\n        Console.WriteLine(\"Testing general recursion\");\n        var sw2     = Stopwatch.StartNew();\n        \n        var result2 = sumNoTail(0, example);\n        \n        sw2.Stop();\n        Console.WriteLine($\"{sw2.Elapsed.Nanoseconds} ns\");\n\n        equals ??= (fa, fb) => fa.Equals(fb);\n        \n        if (!equals(result1, result2))\n        {\n            Console.ForegroundColor = ConsoleColor.Red;\n            Console.WriteLine(\"Monad trait implementation for {typeof(M).Name}.Recur gives a different \"     +\n                              $\"result to the equivalent recursive {typeof(M).Name}.Bind.  This suggests \"   +\n                              $\"an implementation bug, most likely in {typeof(M).Name}.Recur, but possibly \" +\n                              $\"in {typeof(M).Name}.Bind.\");\n            Console.ForegroundColor = ConsoleColor.White;\n        }\n        else\n        {\n            Console.ForegroundColor = ConsoleColor.Green;\n            Console.WriteLine(\"SUCCESS\");\n            Console.ForegroundColor = ConsoleColor.White;\n        }\n        \n        K<M, Next<(int Total, Seq<int> Values), int>> sumTail((int Total, Seq<int> Values) pair) =>\n            pair.Values switch\n            {\n                []          => M.Done<(int, Seq<int>), int>(pair.Total),\n                var (x, xs) => M.Loop<(int, Seq<int>), int>((pair.Total + x, xs)) \n            };\n\n        \n        K<M, Next<(int Total, Seq<int> Values), int>> sumTail2((int Total, Seq<int> Values) pair) =>\n            pair.Values switch\n            {\n                []          => M.Done<(int, Seq<int>), int>(pair.Total),\n                var (x, xs) => M.Loop<(int, Seq<int>), int>((pair.Total + x, xs)) \n            };\n        \n        K<M, int> sumNoTail(int total, Seq<int> values) =>\n            values switch\n            {\n                []          => M.Pure(total),\n                var (x, xs) => sumNoTail(total + x, xs)\n            };\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/ResourcesDiscussion1366.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing LanguageExt;\nusing LanguageExt.Sys.Live;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic static class ResourcesDiscussion1366\n{\n    public static async Task Run()\n    {\n        Console.WriteLine(\"## 1. Expect\");\n        await Expect();\n\n        Console.WriteLine(\"\\n## 2. use using IO\");\n        await Case2();\n\n        Console.WriteLine(\"\\n## 3. use using IO w/ EnvIO\");\n        await Case3();\n\n        Console.WriteLine(\"\\n## 4. use using Eff\");\n        await Case4();\n\n        Console.WriteLine(\"\\n## 5. use using Eff w/ Runtime\");\n        await Case5();\n    }\n\n\n    static async Task Expect()\n    {\n        try\n        {\n            await using var x = new DisposableClass(\"1\");\n            throw new Exception(\"crash\");\n        }\n        catch\n        {\n            // do nothing\n        }\n\n    }\n\n    static async Task Case2()\n    {\n        var io =\n            from r in use(() => new DisposableClass(\"2\"))\n            from x in liftIO(() => throw new Exception(\"crash\"))\n            from _ in release(r)\n            select unit;\n\n        try\n        {\n            await io.RunAsync();\n        }\n        catch\n        {\n            // do nothing\n        }\n    }\n\n    static async Task Case3()\n    {\n        var io =\n            from r in use(() => new DisposableClass(\"3\"))\n            from x in liftIO(() => throw new Exception(\"crash\"))\n            from _ in release(r)\n            select unit;\n\n        try\n        {\n            using var envIO = EnvIO.New();\n            await io.RunAsync(envIO);\n        }\n        catch\n        {\n            // do nothing\n        }\n    }\n\n    static async Task Case4()\n    {\n        Eff<Unit> effect =\n            from r in use(() => new DisposableClass(\"4\"))\n            from x in liftIO(() => throw new Exception(\"crash\"))\n            from _ in release(r)\n            select unit;\n\n        await effect.RunAsync();\n    }\n\n    static async Task Case5()\n    {\n        Eff<Runtime, Unit> effect =\n            from r in use(() => new DisposableClass(\"5\"))\n            from x in liftIO(() => throw new Exception(\"crash\"))\n            from _ in release(r)\n            select unit;\n\n        await effect.RunAsync(Runtime.New());\n    }\n\n    public class DisposableClass(string Id) : IDisposable, IAsyncDisposable\n    {\n        public void Dispose()\n        {\n            Console.WriteLine($\"- Disposed {Id}\");\n        }\n\n        public ValueTask DisposeAsync()\n        {\n            Console.WriteLine($\"- DisposedAsync {Id}\");\n\n            return ValueTask.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/RobotExample.cs",
    "content": "﻿/*\n TODO: RESTORE WITH NEW CODE-GEN SYSTEM\n \nusing System;\nusing System.Collections.Generic;\nusing System.Text;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\n\nnamespace TestBed\n{\n    public abstract class RobotState\n    {\n        public class Unknown : RobotState { public Unknown() { } }\n        public class Up : RobotState { public Up() { } }\n        public class Down : RobotState { public Down() { } }\n    }\n\n    public interface Env\n    {\n        MRobot<RobotState> WhereAreYou();\n        MRobot<Unit> MoveRobotUp();\n        MRobot<Unit> MoveRobotDown();\n    }\n\n    [LanguageExt.RWS(WriterMonoid: typeof(MUnit), Env: typeof(Env), State: typeof(RobotState))]\n    public partial struct MRobot<A>\n    {\n    }\n}\n*/\n"
  },
  {
    "path": "Samples/TestBed/ScheduleTests.cs",
    "content": "﻿using LanguageExt;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.UnitsOfMeasure;\nusing System;\n\nnamespace TestBed;\n\npublic class ScheduleTests\n{\n    public static void Run()\n    {\n        var results = Schedule.linear(1 * sec) | Schedule.recurs(3) | Schedule.repeat(3);\n\n        Console.WriteLine(results.Run().ToSeq());\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/SeqConstructTests.cs",
    "content": "using System.Diagnostics;\nusing LanguageExt;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic static class SeqConstructTests\n{\n    public static void Test()\n    {\n        Create_Seq_with_constructor();\n        Create_Seq_with_collection_expression();\n    }\n\n    public static void Create_Seq_with_constructor()\n    {\n        var seq = new Seq<string>([\"a\", \"b\"]);\n        Debug.Assert(seq.Count == 2);\n    }\n\n    public static void Create_Seq_with_collection_expression()\n    {\n        Seq<string> seq = [\"a\", \"b\"];\n        Debug.Assert(seq.Count == 2);\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/SequenceParallelTest.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Threading.Tasks;\nusing LanguageExt;\nusing LanguageExt.Sys;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic class SequenceParallelTest\n{\n    public static void Run()\n    {\n        SequenceParallelRandomDelayTest().GetAwaiter().GetResult();\n    }\n\n    public static async Task SequenceParallelRandomDelayTest()\n    {\n        var sw = Stopwatch.StartNew();\n        var input = Seq(1, 2, 3, 2, 5, 1, 1, 2, 3, 2, 1, 2, 4, 2, 1, 5, 6, 1, 3, 6, 2);\n\t\n        var eitherIO = input.Map(DoDelay).Traverse(x => x).As();\n        var either = eitherIO.Run().As().Run();\n        \n        Debug.Assert(either.IsRight);\n        either.IfRight(right => Debug.Assert(right == input));\n        \n        sw.Stop();\n\n        System.Console.WriteLine(sw.Elapsed);\n    }\n\n    static EitherT<string, IO, int> DoDelay(int seconds)\n    {\n        return liftIO(() => F(seconds));\n        static async Task<Either<string, int>> F(int seconds)\n        {\n            await Task.Delay(seconds * 1000);\n            return seconds;\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed/SourceTTests.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.Traits;\nusing System.Threading.Tasks;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic static class SourceExt\n{\n\n    public static SourceT<M, A> Log<M, A>(this SourceT<M, A> src, Func<A, string> log)\n        where M: MonadIO<M>, Alternative<M> =>\n        src.Map(x => { Console.WriteLine(log(x)); return x; });\n\n    public static Source<A> Log<A>(this Source<A> src, Func<A, string> log) =>\n        src.Map(x => { Console.WriteLine(log(x)); return x; });\n}\n\npublic delegate void TickEvent(DateTime dt);\n\t\t\t\t\npublic class SourceTTests\n{\n    public static event Action<DateTime> Tick;\n    public static readonly Event<DateTime> tickEvent = Event.from(ref Tick);\n\n    public static void Run()\n    {\n        var t = Task.Run(Clock);\n\n        var ticks = SourceT.iter(from v in tickEvent.Subscribe<IO>()\n                                 from _ in writeLine(v)\n                                 select unit);\n        \n        var app = from f in ticks.ForkIO()\n                  from k in readKey\n                  from _ in f.Cancel\n                  from i in writeLine(\"The messages should have stopped\")\n                  select unit;\n                            ;\n        ignore(app.Run());\n        Console.WriteLine(\"Press any key to exit\");\n        Console.ReadKey();\n    }\n\n    static async Task Clock()\n    {\n        while (true)\n        {\n            await Task.Delay(1000);\n            Tick?.Invoke(DateTime.Now);\n        }\n    }\n    \n    static IO<Unit> writeLine(object? s) => \n        IO.lift(() => Console.WriteLine(s));\n    \n    static IO<ConsoleKeyInfo> readKey => \n        IO.lift(Console.ReadKey);\n}\n"
  },
  {
    "path": "Samples/TestBed/StateAsync.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed.StateStuff;\n\npublic static class StateForkIO\n{\n    public static StateIO<int, Unit> forkTest =>\n        from p1 in showState(\"parent\")\n        from f1 in fork(countTo10(\"fst\"))\n        from f2 in fork(countTo10(\"snd\"))\n        from _  in awaitAll(f1, f2)\n        from p2 in showState(\"parent\")\n        select unit;\n\n    static StateIO<int, Unit> countTo10(string branch) =>\n        from _1 in addToState\n        from st in showState(branch)\n        from _2 in when(st < 10, countTo10(branch))\n        select unit;\n\n    static StateIO<int, Unit> addToState =>\n        Stateful.modify<StateIO<int>, int>(x => x + 1).As();\n    \n    static StateIO<int, int> showState(string branch) =>\n        from s in Stateful.get<StateIO<int>, int>().As()\n        from _ in Console.writeLine($\"{branch}: {s}\")\n        select s;\n}\n\npublic static class Console\n{\n    public static IO<Unit> writeLine(object? obj) =>\n        IO.lift(() => System.Console.WriteLine(obj));\n}\n\n/// <summary>\n/// Wrapper around `StateT IO` so we can add a `MapIO` and `ToIO` \n/// </summary>\npublic record StateIO<S, A>(StateT<S, IO, A> runState) : K<StateIO<S>, A>\n{\n    public IO<(A Value, S State)> Run(S initialState) =>\n        runState.Run(initialState).As();\n    \n    public StateIO<S, B> Map<B>(Func<A, B> f) =>\n        this.Kind().Map(f).As();\n    \n    public StateIO<S, B> Bind<B>(Func<A, K<StateIO<S>, B>> f) =>\n        this.Kind().Bind(f).As();\n    \n    public StateIO<S, C> SelectMany<B, C>(Func<A, K<StateIO<S>, B>> f, Func<A, B, C> g) =>\n        Bind(x => f(x).Map(y => g(x, y)));\n    \n    public StateIO<S, C> SelectMany<B, C>(Func<A, IO<B>> f, Func<A, B, C> g) =>\n        SelectMany(x => MonadIO.liftIO<StateIO<S>, B>(f(x)), g);    \n}\n\n/// <summary>\n/// StateIO extensions\n/// </summary>\npublic static class StateIOExtensions\n{\n    public static StateIO<S, A> As<S, A>(this K<StateIO<S>, A> ma) =>\n        (StateIO<S, A>)ma;\n    \n    public static IO<(A Value, S State)> Run<S, A>(this K<StateIO<S>, A> ma, S initialState) =>\n        ma.As().Run(initialState);    \n}\n\n/// <summary>\n/// StateIO trait implementation\n/// </summary>\npublic class StateIO<S> : \n    Deriving.Monad<StateIO<S>, StateT<S, IO>>,\n    Deriving.Stateful<StateIO<S>, StateT<S, IO>, S>,\n    MonadUnliftIO<StateIO<S>>\n{\n    static K<StateT<S, IO>, A> Natural<StateIO<S>, StateT<S, IO>>.Transform<A>(K<StateIO<S>, A> fa) => \n        fa.As().runState;\n\n    static K<StateIO<S>, A> CoNatural<StateIO<S>, StateT<S, IO>>.CoTransform<A>(K<StateT<S, IO>, A> fa) => \n        new StateIO<S, A>(fa.As());\n\n    static K<StateIO<S>, B> MonadUnliftIO<StateIO<S>>.MapIO<A, B>(K<StateIO<S>, A> ma, Func<IO<A>, IO<B>> f) =>\n        from s in Stateful.get<StateIO<S>, S>()\n        let a = Atom(s)\n        from r in CoNatural.transform<StateIO<S>, StateT<S, IO>, B>(\n            StateT.lift<S, IO, B>(\n                ma.As().runState.Run(s).Map(p =>\n                                            {\n                                                a.Swap(_ => p.State);\n                                                return p.Value;\n                                            }).MapIO(f)))\n        from _ in Stateful.put<StateIO<S>, S>(a.Value)\n        select r;\n\n    static K<StateIO<S>, IO<A>> MonadUnliftIO<StateIO<S>>.ToIO<A>(K<StateIO<S>, A> ma) => \n        from s in Stateful.get<StateIO<S>, S>()\n        let a = Atom(s)\n        from r in CoNatural.transform<StateIO<S>, StateT<S, IO>, IO<A>>(\n            StateT.lift<S, IO, IO<A>>(\n                ma.As().runState.Run(s).Map(p =>\n                                            {\n                                                a.Swap(_ => p.State);\n                                                return p.Value;\n                                            }).ToIO()))\n        from _ in Stateful.put<StateIO<S>, S>(a.Value)\n        select r;\n\n    static K<StateIO<S>, A> MonadIO<StateIO<S>>.LiftIO<A>(IO<A> ma) => \n        new StateIO<S, A>(StateT.lift<S, IO, A>(ma));\n}\n"
  },
  {
    "path": "Samples/TestBed/StateEff.cs",
    "content": "using System;\nusing LanguageExt;\nusing LanguageExt.Common;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed;\n\npublic record StateEff<S, E, A>(Func<EnvIO, S, Either<E, (S State, A Value)>> runStateEff)\n    : K<StateEff<S, E>, A>\n    where E : Error;\n\npublic static class StateEff\n{\n    public static StateEff<S, E, A> As<S, E, A>(this K<StateEff<S, E>, A> ma) \n        where E : Error =>\n        (StateEff<S, E, A>)ma;\n    \n    public static IO<Either<E, (S State, A Value)>> Run<S, E, A>(\n        this K<StateEff<S, E>, A> ma, S initialState) \n        where E : Error =>\n        IO.lift(envIO => ma.As().runStateEff(envIO, initialState));\n}\n\npublic class StateEff<S, E> :\n    Monad<StateEff<S, E>>,\n    Stateful<StateEff<S, E>, S>,\n    Choice<StateEff<S, E>>\n    where E : Error \n{\n    static K<StateEff<S, E>, B> Monad<StateEff<S, E>>.Bind<A, B>(\n        K<StateEff<S, E>, A> ma,\n        Func<A, K<StateEff<S, E>, B>> f) =>\n        new StateEff<S, E, B>(\n            (eio, state) =>\n                ma.As().runStateEff(eio, state) switch\n                {\n                    Either<E, (S State, A Value)>.Right(var (s, v)) =>\n                        f(v).As().runStateEff(eio, s),\n\n                    Either<E, (S State, A Value)>.Left(var e) =>\n                        Left(e)\n                });\n\n    public static K<StateEff<S, E>, B> Recur<A, B>(A value, Func<A, K<StateEff<S, E>, Next<A, B>>> f) => \n        Monad.unsafeRecur(value, f);\n\n    static K<StateEff<S, E>, B> Functor<StateEff<S, E>>.Map<A, B>(Func<A, B> f, K<StateEff<S, E>, A> ma) =>\n        new StateEff<S, E, B>(\n            (eio, state) =>\n                ma.As().runStateEff(eio, state) switch\n                {\n                    Either<E, (S State, A Value)>.Right(var (s, v)) =>\n                        Right((s, f(v))),\n\n                    Either<E, (S State, A Value)>.Left(var e) =>\n                        Left(e)\n                });\n\n    static K<StateEff<S, E>, A> Applicative<StateEff<S, E>>.Pure<A>(A value) =>\n        new StateEff<S, E, A>((_, s) => Right((s, value)));\n\n    static K<StateEff<S, E>, B> Applicative<StateEff<S, E>>.Apply<A, B>(\n        K<StateEff<S, E>, Func<A, B>> mf,\n        K<StateEff<S, E>, A> ma) =>\n        new StateEff<S, E, B>(\n            (eio, state) =>\n                mf.As().runStateEff(eio, state) switch\n                {\n                    Either<E, (S State, Func<A, B> Value)>.Right(var (s1, f)) =>\n                        ma.As().runStateEff(eio, s1) switch\n                        {\n                            Either<E, (S State, A Value)>.Right(var (s2, x)) =>\n                                Right((s2, f(x))),\n\n                            Either<E, (S State, A Value)>.Left(var e) =>\n                                Left(e)\n                        },\n\n                    Either<E, (S State, Func<A, B> Value)>.Left(var e) =>\n                        Left(e)\n                });\n\n    static K<StateEff<S, E>, B> Applicative<StateEff<S, E>>.Apply<A, B>(\n        K<StateEff<S, E>, Func<A, B>> mf,\n        Memo<StateEff<S, E>, A> ma) =>\n        new StateEff<S, E, B>(\n            (eio, state) =>\n                mf.As().runStateEff(eio, state) switch\n                {\n                    Either<E, (S State, Func<A, B> Value)>.Right(var (s1, f)) =>\n                        ma.Value.As().runStateEff(eio, s1) switch\n                        {\n                            Either<E, (S State, A Value)>.Right(var (s2, x)) =>\n                                Right((s2, f(x))),\n\n                            Either<E, (S State, A Value)>.Left(var e) =>\n                                Left(e)\n                        },\n\n                    Either<E, (S State, Func<A, B> Value)>.Left(var e) =>\n                        Left(e)\n                });\n\n    static K<StateEff<S, E>, Unit> Stateful<StateEff<S, E>, S>.Put(S value) =>\n        new StateEff<S, E, Unit>((_, _) => Right((value, unit)));\n\n    static K<StateEff<S, E>, Unit> Stateful<StateEff<S, E>, S>.Modify(Func<S, S> modify) =>\n        new StateEff<S, E, Unit>((_, state) => Right((modify(state), unit)));\n\n    static K<StateEff<S, E>, A> Stateful<StateEff<S, E>, S>.Gets<A>(Func<S, A> f) =>\n        new StateEff<S, E, A>((_, state) => Right((state, f(state))));\n\n    static K<StateEff<S, E>, A> Choice<StateEff<S, E>>.Choose<A>(K<StateEff<S, E>, A> fa, K<StateEff<S, E>, A> fb) =>\n        new StateEff<S, E, A>(\n            (eio, state) =>\n                fa.As().runStateEff(eio, state) switch\n                {\n                    Either<E, (S State, A Value)>.Right succ =>\n                        succ,\n\n                    Either<E, (S State, A Value)>.Left =>\n                        fb.As().runStateEff(eio, state)\n                });\n\n    static K<StateEff<S, E>, A> Choice<StateEff<S, E>>.Choose<A>(K<StateEff<S, E>, A> fa, Memo<StateEff<S, E>, A> fb) => \n        new StateEff<S, E, A>(\n            (eio, state) =>\n                fa.As().runStateEff(eio, state) switch\n                {\n                    Either<E, (S State, A Value)>.Right succ =>\n                        succ,\n\n                    Either<E, (S State, A Value)>.Left =>\n                        fb.Value.As().runStateEff(eio, state)\n                });\n\n    static K<StateEff<S, E>, IO<A>> Maybe.MonadUnliftIO<StateEff<S, E>>.ToIOMaybe<A>(K<StateEff<S, E>, A> ma) =>\n        new StateEff<S, E, IO<A>>(\n            (eio, state) =>\n                ma.As().runStateEff(eio, state) switch\n                {\n                    Either<E, (S State, A Value)>.Right(var (s, v)) =>\n                        Right((s, IO.pure(v))),\n\n                    Either<E, (S State, A Value)>.Left(var e) =>\n                        Left(e)\n                });\n\n    static K<StateEff<S, E>, A> Maybe.MonadIO<StateEff<S, E>>.LiftIOMaybe<A>(K<IO, A> ma) => \n        new StateEff<S, E, A>(\n            (eio, state) => \n            {\n                try\n                {\n                    return Right((state, ma.As().Run(eio)));\n                }\n                catch (Exception e)\n                {\n                    // TODO: Decide how to convert an Exception to `E` -- this is bespoke to your code\n                    //       But if you derive your `E` type from `Error` then you'll find it's easier\n                    throw new NotImplementedException();\n                }\n            }\n        );\n}\n    \n    \n    \n"
  },
  {
    "path": "Samples/TestBed/TestBed.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <LangVersion>default</LangVersion>\n        <StartupObject>Program</StartupObject>\n        <RoslynCodeGenVersion>0.6.1</RoslynCodeGenVersion>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.3\" />\n        <PackageReference Include=\"System.Reactive\" Version=\"5.0.0\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.FSharp\\LanguageExt.FSharp.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Parsec\\LanguageExt.Parsec.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Streaming\\LanguageExt.Streaming.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Rx\\LanguageExt.Rx.csproj\" />\n        <ProjectReference Include=\"..\\..\\LanguageExt.Sys\\LanguageExt.Sys.csproj\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "Samples/TestBed/TestCodeGen.cs",
    "content": "﻿/*\n TODO: RESTORE WITH NEW CODE-GEN SYSTEM\n \n////////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                                                                                    //\n//                                                                                                    //\n//     NOTE: This is just my scratch pad for quickly testing stuff, not for human consumption         //\n//                                                                                                    //\n//                                                                                                    //\n////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nusing System;\nusing System.Diagnostics.Contracts;\nusing System.IO;\nusing System.Threading.Tasks;\nusing LanguageExt;\nusing LanguageExt.ClassInstances;\nusing LanguageExt.Common;\nusing LanguageExt.TypeClasses;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed\n{\n    [Free]\n    public interface FreeIO<T>\n    {\n        [Pure] T Pure(T value);\n        [Fail] T Fail(Error error);\n        string ReadAllText(string path);\n        Unit WriteAllText(string path, string text);\n    }\n    \n    public static partial class FreeIO\n    {\n        public static FreeIO<T> Flatten2<T>(this FreeIO<FreeIO<T>> ma) => ma switch\n        {\n            Pure<FreeIO<T>> v => v.Value,\n            Fail<FreeIO<T>> v => new Fail<T>(v.Error),\n            ReadAllText<FreeIO<T>> v => new ReadAllText<T>(v.Path, n => Flatten(v.Next(n)), fn => Flatten(v.FailNext(fn))),\n            WriteAllText<FreeIO<T>> v => new WriteAllText<T>(v.Path, v.Text, n => Flatten(v.Next(n)), fn => Flatten(v.FailNext(fn))),\n            _ => throw new System.NotSupportedException()\n        };\n    }\n\n    public static class FreeIOTest\n    {\n        public async static Task Test1()\n        {\n            var dsl = from t in FreeIO.ReadAllText(\"I:\\\\temp\\\\test.txt\")\n                      from _ in FreeIO.WriteAllText(\"I:\\\\temp\\\\test2.txt\", t)\n                      select unit;\n\n\n            var res1 = Interpret(dsl);\n\n            var res2 = await InterpretAsync(dsl);\n        }\n\n        public static Either<Error, A> Interpret<A>(FreeIO<A> ma) => ma switch\n        {\n            Pure<A>(var value) => value,\n            Fail<A>(var error) => error,\n            ReadAllText<A>(var path, var next, var failNext) => Interpret(next(Read(path))),\n            WriteAllText<A>(var path, var text, var next, var failNext) => Interpret(next(Write(path, text))),\n            _ => throw new NotSupportedException()\n        };\n\n        static string Read(string path) =>\n            File.ReadAllText(path);\n\n        static Unit Write(string path, string text)\n        {\n            File.WriteAllText(path, text);\n            return unit;\n        }\n\n        public static async Task<A> InterpretAsync<A>(FreeIO<A> ma) => ma switch\n        {\n            Pure<A>(var value) => value,\n            Fail<A>(var error) => await Task.FromException<A>(error),\n            ReadAllText<A>(var path, var next, var failNext) => await InterpretAsync(next(await File.ReadAllTextAsync(path))),\n            WriteAllText<A>(var path, var text, var next, var failNext) => await InterpretAsync(next(await File.WriteAllTextAsync(path, text).ToUnit())),\n            _ => throw new NotSupportedException()\n        };\n    }\n\n    [Free]\n    internal interface Maybe<A>\n    {\n        [Pure] A Just(A value);\n        [Pure] A Nothing();\n\n        public static Maybe<B> Map<B>(Maybe<A> ma, Func<A, B> f) => ma switch\n        {\n            Just<A>(var x) => Maybe.Just(f(x)),\n            _ => Maybe.Nothing<B>()\n        };\n    }\n\n    public static class MaybeFreeTest\n    {\n        public static void Test1()\n        {\n            var ma = Maybe.Just(10);\n            var mb = Maybe.Just(20);\n            var mn = Maybe.Nothing<int>();\n\n            var mr =\n                from a in ma\n                from b in mb\n                select a + b;\n\n            var mnn =\n                from a in ma\n                from b in mb\n                from _ in mn\n                select a + b;\n\n            var r3 = mr switch\n            {\n                Just<int>(var x) => $\"Value is {x}\",\n                _ => \"No value\"\n            };\n\n            Console.WriteLine(mr);\n            Console.WriteLine(mnn);\n        }\n    }\n\n\n    [WithLens]\n    public partial class TestWith : Record<TestWith>\n    {\n        public readonly string Name;\n        public readonly string Surname;\n\n        public TestWith(string name, string surname)\n        {\n            Name = name;\n            Surname = surname;\n        }\n    }\n\n    public interface MIO\n    {\n        Seq<string> ReadAllLines(string fileName);\n        Unit WriteAllLines(string fileName, Seq<string> lines);\n        Person ReadFromDB();\n        int Zero { get; }\n    }\n\n    public class RealIO : MIO\n    {\n        public Seq<string> ReadAllLines(string path) => File.ReadAllLines(path).ToSeq();\n        public Unit WriteAllLines(string path, Seq<string> lines)\n        {\n            File.WriteAllLines(path, lines);\n            return unit;\n        }\n        public Person ReadFromDB() => new Person(\"Spider\", \"Man\", 50);\n        public int Zero => 0;\n    }\n\n    public static class TestSubs\n    {\n        public static void Test()\n        {\n            var comp = from ze in Subsystem.Zero\n                       from ls in Subsystem.ReadAllLines(\"c:/test.txt\")\n                       from _ in Subsystem.WriteAllLines(\"c:/test-copy.txt\", ls)\n                       select ls.Count;\n\n            var res = comp.Run(new RealIO()).IfFail(0);\n        }\n    }\n\n    [Reader(Env: typeof(MIO), Constructor: \"Pure\")]\n    public partial struct Subsystem<A>\n    {\n    }\n\n\n    //[RWS(WriterMonoid: typeof(MSeq<string>), Env: typeof(IO), State: typeof(string), \n    //     Constructor: \"LiftSub\",             Fail: \"FailSub\")]\n    //public partial struct Subsys<T>\n    //{\n    //}\n\n\n    [RWS(WriterMonoid: typeof(MSeq<string>),\n         Env: typeof(MIO),\n         State: typeof(Person),\n         Constructor: \"Pure\",\n         Fail: \"Error\")]\n    public partial struct Subsys<T>\n    {\n    }\n\n    public interface IEnv\n    {\n    }\n\n    public class MultiAccessFields\n    {\n        public MultiAccessFields(string publicString, string internalString, string privateString, string publicStringProp, string internalStringProp, string privateStringProp)\n        {\n            PublicString = publicString;\n            InternalString = internalString;\n            PrivateString = privateString;\n            PublicStringProp = publicStringProp;\n            InternalStringProp = internalStringProp;\n            PrivateStringProp = privateStringProp;\n        }\n\n        public string PublicString;\n        internal string InternalString;\n        private string PrivateString;\n        public string PublicStringProp { get; set; }\n        internal string InternalStringProp { get; set; }\n        private string PrivateStringProp { get; set; }\n    }\n\n    [RWS(WriterMonoid: typeof(MSeq<string>), Env: typeof(IEnv), State: typeof(MultiAccessFields))]\n    public partial struct XClientRws<A> \n    { \n    }\n\n    [WithLens]\n    public partial class TestWith2 : Record<TestWith2>\n    {\n        public readonly Option<string> Name;\n        public readonly Option<string> Surname;\n\n        public TestWith2(Option<string> name, Option<string> surname)\n        {\n            Name = name;\n            Surname = surname;\n        }\n    }\n\n    [WithLens]\n    internal partial class TestWith3<A> : Record<TestWith3<A>> where A : class\n    {\n        public readonly A Value;\n        public readonly Option<string> Name;\n        public readonly Option<string> Surname;\n\n        public TestWith3(A value, Option<string> name, Option<string> surname)\n        {\n            Value = value;\n            Name = name;\n            Surname = surname;\n        }\n    }\n\n    [WithLens]\n    public partial class TestWith4 : Record<TestWith4>\n    {\n        public readonly string New;\n        public readonly string Class;\n        public readonly string Static;\n        public readonly string While;\n\n        public TestWith4(string @new, string @class, string @static, string @while)\n        {\n            New = @new;\n            Class = @class;\n            Static = @static;\n            While = @while;\n        }\n    }\n\n    [Union]\n    public abstract partial class MaybeUnion<A>\n    {\n        public abstract MaybeUnion<A> JustValue(A value);\n        public abstract MaybeUnion<A> NothingValue();\n    }\n\n    [Union]\n    internal interface Test<A>\n    {\n        Test<A> TestSome<B>(MaybeUnion<B> ma);\n        Test<A> TestNone();\n    }\n\n    [Union]\n    public abstract partial class TestSimpleUnion\n    {\n        public abstract TestSimpleUnion Simple1(int x, int y);\n        public abstract TestSimpleUnion Simple2(int x);\n    }\n\n    //[Union]\n    //public abstract partial class Maybe<A>\n    //{\n    //    public abstract Maybe<A> Just(A value);\n    //    public abstract Maybe<A> Nothing();\n    //}\n\n    //[Union]\n    //public interface Shape\n    //{\n    //    Shape Rectangle(float width, float length);\n    //    Shape Circle(float radius);\n    //    Shape Prism(float width, float height);\n    //}\n\n    [Union]\n    public abstract partial class Shape<NumA, A> where NumA : struct, Num<A>\n    {\n        public abstract Shape<NumA, A> Rectangle(A width, A length);\n        public abstract Shape<NumA, A> Circle(A radius);\n        public abstract Shape<NumA, A> Prism(A width, A height);\n    }\n\n    [WithLens]\n    public partial class CustomClass : Record<CustomClass>\n    {\n        public readonly Option<string> Value;\n\n        public CustomClass(Option<string> value)\n        {\n            Value = value;\n        }\n\n        public Option<int> ValueLengthAsExpressionBodiedProperty => Value.Map(x => x.Length);\n\n        public Option<int> ValueLengthAsGetProperty\n        {\n            get { return Value.Map(x => x.Length); }\n        }\n\n        public Option<int> ValueLengthAsExpressionBodiedMethod() => Value.Map(x => x.Length);\n    }\n\n    [Record]\n    public partial struct Person\n    {\n        [Eq(typeof(EqStringOrdinalIgnoreCase))]\n        [Ord(typeof(OrdStringOrdinalIgnoreCase))]\n        [Hashable(typeof(HashableStringOrdinalIgnoreCase))]\n        public readonly string Forename;\n\n        [Eq(typeof(EqStringOrdinalIgnoreCase))]\n        [Ord(typeof(OrdStringOrdinalIgnoreCase))]\n        [Hashable(typeof(HashableStringOrdinalIgnoreCase))]\n        public readonly string Surname;\n\n        public readonly int? Age;\n    }\n}\n*/\n"
  },
  {
    "path": "Samples/TestBed/UseTest.cs",
    "content": "using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LanguageExt;\n\nnamespace TestBed;\n\ninternal class UseTest\n{\n    public static Task Main() =>\n        Method1();\n\n    static async Task Method1()\n    {\n        var op = from disposable in Prelude.use(() => new Disposable1())\n                 from _1 in Method2()\n                 from _2 in IO.lift(() => Console.WriteLine($\"Do hard work: {disposable.Value}\"))\n                 select Unit.Default;\n\n        await op.RunAsync();\n\n        Console.WriteLine(\"IO completed\");\n    }\n\n    static IO<Unit> Method2() =>\n        IO.liftAsync(() => Task.Delay(TimeSpan.FromSeconds(1)).ToUnit());\n}\n\npublic sealed class Disposable1 : IDisposable\n{\n    volatile int Disposed;\n\n    public string Value =>\n        Disposed == 0\n            ? \"This is a valid value\"\n            : throw new ObjectDisposedException(nameof(Disposable1));\n\n    public void Dispose()\n    {\n        if (Interlocked.CompareExchange(ref Disposed, 1, 0) == 0)\n        {\n            Console.WriteLine(\"Disposed\");\n        }\n        else\n        {\n            Console.WriteLine(\"Already disposed\");\n        }\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed.WPF/App.xaml",
    "content": "﻿<Application x:Class=\"TestBed.WPF.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:local=\"clr-namespace:TestBed.WPF\"\n             StartupUri=\"MainWindow.xaml\">\n    <Application.Resources>\n         \n    </Application.Resources>\n</Application>\n"
  },
  {
    "path": "Samples/TestBed.WPF/App.xaml.cs",
    "content": "﻿using System.Windows;\nusing LanguageExt.Effects;\n\nnamespace TestBed.WPF\n{\n    /// <summary>\n    /// Interaction logic for App.xaml\n    /// </summary>\n    public partial class App : Application\n    {\n        public static readonly MinRT Runtime = new ();\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed.WPF/AssemblyInfo.cs",
    "content": "﻿using System.Windows;\n\n[assembly: ThemeInfo(\n    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located\n    //(used if a resource is not found in the page,\n    // or application resource dictionaries)\n    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located\n    //(used if a resource is not found in the page,\n    // app, or any theme specific resource dictionaries)\n)]\n"
  },
  {
    "path": "Samples/TestBed.WPF/AtomIO.cs",
    "content": "﻿/*\nusing System;\nusing LanguageExt;\nusing LanguageExt.Effects.Traits;\nusing static LanguageExt.Prelude;\nusing static LanguageExt.Transducer;\n\nnamespace TestBed.WPF;\n\n/// <summary>\n/// Placeholder implementation: waiting for the real one to be implemented in LanguageExt.Core\n/// </summary>\npublic class AtomIO<RT, E, A>\n    where RT : HasIO<RT, E>\n{\n    public AtomIO(A value) =>\n        Value = value;\n\n    public A Value { get; private set; }\n\n    public IO<RT, E, Unit> Swap(Func<A, A> swap) =>\n        lift(() =>\n        {\n            Value = swap(Value);\n            return unit;\n        });\n\n    public override string ToString() =>\n        Value?.ToString() ?? \"[null]\";\n}\n*/\n"
  },
  {
    "path": "Samples/TestBed.WPF/MainWindow.xaml",
    "content": "﻿<local:WindowRT x:Class=\"TestBed.WPF.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:local=\"clr-namespace:TestBed.WPF\"\n        mc:Ignorable=\"d\"\n        Title=\"Language-Ext WPF Test-Bed\" Height=\"450\" Width=\"800\">\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition />\n            <RowDefinition />\n            <RowDefinition />\n        </Grid.RowDefinitions>        \n        \n        <Button Name=\"CounterButton\" Height=\"100\" Width=\"300\" Click=\"ButtonOnClick\" FontSize=\"25pt\" Grid.Row=\"0\"></Button>\n        <TextBlock Name=\"CursorTextBoxX\" FontSize=\"25pt\" Grid.Row=\"1\">100</TextBlock>\n        <TextBlock Name=\"CursorTextBoxY\" FontSize=\"25pt\" Grid.Row=\"2\">200</TextBlock>\n    </Grid>\n</local:WindowRT>\n"
  },
  {
    "path": "Samples/TestBed.WPF/MainWindow.xaml.cs",
    "content": "﻿using System;\nusing System.Windows;\nusing System.Windows.Input;\nusing LanguageExt;\nusing LanguageExt.Effects;\nusing LanguageExt.Pipes;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed.WPF;\n\n/// <summary>\n/// Main application window\n/// </summary>\npublic partial class MainWindow : WindowRT\n{\n    /// <summary>\n    /// Mutable counter\n    /// </summary>\n    readonly Atom<int> count = Atom(0);\n        \n    /// <summary>\n    /// Construct the window and register the events\n    /// </summary>\n    public MainWindow() : base(App.Runtime)\n    {\n        InitializeComponent();\n        onStart(startup);\n    }\n\n    /// <summary>\n    /// Register the window events\n    /// </summary>\n    Eff<MinRT, Unit> startup =>\n        from _1 in tickIO.ForkIO().As()\n        from _2 in (onMouseMove | Proxy.repeat(showMousePos)).RunEffect().ForkIO()\n        select unit;\n        \n    /// <summary>\n    /// Infinite loop that ticks every second\n    /// </summary>\n    Eff<MinRT, Unit> tickIO =>\n        from _1 in modifyCount(x => x + 1)\n        from _2 in postIO(setContent(CounterButton, $\"{count}\"))\n        from _3 in waitFor(1)\n        from _4 in tickIO           // tail(tickIO)\n        select unit;\n\n    Consumer<MouseEventArgs, Eff<MinRT>, Unit> showMousePos =>\n        from e in Proxy.awaiting<MouseEventArgs>()\n        from _ in postIO(from p in getPosition(e)\n                         from x in setContent(CursorTextBoxX, $\"X: {p.X:F0}\")\n                         from y in setContent(CursorTextBoxY, $\"Y: {p.Y:F0}\")\n                         select unit)\n        select unit;\n\n    /// <summary>\n    /// Standard button click-handler\n    /// </summary>\n    void ButtonOnClick(object? sender, RoutedEventArgs e) =>\n        handle(buttonOnClickIO);\n\n    /// <summary>\n    /// Button handler in the IO monad\n    /// </summary>\n    Eff<MinRT, Unit> buttonOnClickIO =>\n        from _1 in resetCount\n        from _2 in postIO(setContent(CounterButton, $\"{count}\"))\n        select unit;\n        \n    /// <summary>\n    /// Set the count value\n    /// </summary>\n    Eff<MinRT, int> setCount(int value) =>\n        modifyCount(_ => value);\n\n    /// <summary>\n    /// Reset the count value\n    /// </summary>\n    Eff<MinRT, int> resetCount =>\n        modifyCount(_ => 0);\n\n    /// <summary>\n    /// Set the count value\n    /// </summary>\n    Eff<MinRT, int> modifyCount(Func<int, int> f) =>\n        lift(() =>count.Swap(f));\n}\n"
  },
  {
    "path": "Samples/TestBed.WPF/TestBed.WPF.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>WinExe</OutputType>\n        <TargetFramework>net8.0-windows</TargetFramework>\n        <Nullable>enable</Nullable>\n        <UseWPF>true</UseWPF>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Samples/TestBed.WPF/WindowIO.cs",
    "content": "﻿using System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing LanguageExt;\nusing LanguageExt.Pipes;\nusing LanguageExt.Traits;\nusing static LanguageExt.Prelude;\n\nnamespace TestBed.WPF;\n\n/// <summary>\n/// A window base-type that supports some common IO behaviours for use in\n/// derived window-types. \n/// </summary>\npublic class WindowIO<RT> : Window\n{\n    readonly RT Runtime;\n    readonly EnvIO EnvIO;\n\n    /// <summary>\n    /// Constructor\n    /// </summary>\n    protected WindowIO(RT runtime)\n    {\n        Runtime = runtime;\n        EnvIO   = EnvIO.New();\n    }\n    \n    /// <summary>\n    /// Startup launch\n    /// </summary>\n    protected Unit onStart(Eff<RT, Unit> operation) =>\n        operation.Run(Runtime, EnvIO)\n                 .IfFail(e => e.Throw());\n\n    /// <summary>\n    /// Closes any forks created by the window\n    /// </summary>\n    protected override void OnClosed(EventArgs e)\n    {\n        EnvIO.Source.Cancel();\n        base.OnClosed(e);\n    }\n\n    /// <summary>\n    /// Turns an IO operation into a task that is run\n    /// </summary>\n    /// <remarks>\n    /// Useful for wrapping IO event-handlers into a Task base event-handler\n    /// </remarks>\n    protected void handle<A>(Eff<RT, A> operation) =>\n        operation.ForkIO().Run(Runtime, EnvIO).ThrowIfFail();\n        \n    /// <summary>\n    /// Helper IO for setting control text \n    /// </summary>\n    protected static Eff<RT, Unit> setContent(ContentControl control, string text) =>\n        lift(action: () => control.Content = text);\n        \n    /// <summary>\n    /// Helper IO for setting control text \n    /// </summary>\n    protected static Eff<RT, Unit> setContent(TextBlock control, string text) =>\n        lift(action: () => control.Text = text);\n\n    /// <summary>\n    /// Get mouse position\n    /// </summary>\n    protected Eff<RT, Point> getPosition(MouseEventArgs @event) =>\n        lift(() => @event.GetPosition(this));\n\n    protected Producer<MouseEventArgs, Eff<RT>, Unit> onMouseMove =>\n        from rtime  in runtime<RT>()\n        let queue = Proxy.Queue<Eff<RT>, MouseEventArgs>()\n        from hndlr  in use<MouseEventHandler>(\n                         acquire: () => (_, e) => queue.Enqueue(e),\n                         release: h => RemoveHandler(Mouse.MouseMoveEvent, h))\n        from _      in liftEff(() => AddHandler(Mouse.MouseMoveEvent, hndlr, false))\n        from result in queue\n        select result;\n    \n    /// <summary>\n    /// Async delay\n    /// </summary>\n    protected static Eff<RT, Unit> waitFor(double ms) =>\n        IO.yieldFor(ms);\n}\n"
  },
  {
    "path": "Samples/TestBed.WPF/WindowRT.cs",
    "content": "﻿using LanguageExt.Common;\nusing LanguageExt.Effects;\n\nnamespace TestBed.WPF;\n\n/// <summary>\n/// A window base-type that bakes in a runtime \n/// </summary>\npublic class WindowRT : WindowIO<MinRT>\n{\n    public WindowRT(MinRT runtime) : base(runtime)\n    {\n    }\n}\n"
  },
  {
    "path": "Samples/TestBed.Web/Program.cs",
    "content": "﻿using LanguageExt;\nusing static LanguageExt.Prelude;\nvar builder = WebApplication.CreateBuilder(args);\nvar app     = builder.Build();\n\napp.MapGet(\"/sync\",\n           () =>\n           {\n               var effect = yieldFor(1000).Map(\"Hello, World\");\n               return effect.Run();\n           });\n\napp.MapGet(\"/async\",\n           async () =>\n           {\n               var effect = yieldFor(1000).Map(\"Hello, World\");\n               return await effect.RunAsync();\n           });\n\napp.MapGet(\"/fork-sync\", \n           () => \n           {\n               var effect      = yieldFor(1000).Map(\"Hello, World\");\n               var computation = awaitIO(fork(effect));\n               return computation.Run();\n           });\n\napp.MapGet(\"/fork-async\",\n           () =>\n           {\n               var effect      = yieldFor(1000).Map(\"Hello, World\");\n               var computation = awaitIO(fork(effect));\n               return computation.Run();\n           });\n\napp.Run();\n"
  },
  {
    "path": "Samples/TestBed.Web/TestBed.Web.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <Nullable>enable</Nullable>\n        <ImplicitUsings>enable</ImplicitUsings>\n    </PropertyGroup>\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\LanguageExt.Core\\LanguageExt.Core.csproj\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "Samples/TestBed.Web.Runner/Program.cs",
    "content": "﻿using NBomber.Contracts;\nusing NBomber.CSharp;\nusing NBomber.Http.CSharp;\n\nvar http = new HttpClient();\n\nvar sim = (string name) =>\n              Scenario.Create(name, async context =>\n                                      {\n                                          var request  = Http.CreateRequest(\"GET\", $\"http://localhost:5000/{name}\");\n                                          var response = await Http.Send(http, request).ConfigureAwait(false);\n                                          return response;\n                                      })\n                    //.WithoutWarmUp()\n                      .WithLoadSimulations(\n                           Simulation.Inject(rate: 500,\n                                             interval: TimeSpan.FromSeconds(1),\n                                             during: TimeSpan.FromSeconds(30)));\n\nNBomberRunner.RegisterScenarios(sim(\"async\")).Run();\nNBomberRunner.RegisterScenarios(sim(\"sync\")).Run();\nNBomberRunner.RegisterScenarios(sim(\"fork-async\")).Run();\nNBomberRunner.RegisterScenarios(sim(\"fork-sync\")).Run();\n"
  },
  {
    "path": "Samples/TestBed.Web.Runner/TestBed.Web.Runner.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n        <TargetFramework>net10.0</TargetFramework>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <PackageReference Include=\"NBomber\" Version=\"6.1.2\" />\n        <PackageReference Include=\"NBomber.Http\" Version=\"6.1.0\" />\n    </ItemGroup>\n\n</Project>"
  },
  {
    "path": "clean.sh",
    "content": "echo cleaing bin, obj, and /louthy.github.io/language-ext\n\n# Artifacts is where the DLLs are compiled to \nArtifacts=/media/paul/raid/dev/artifacts\n\n# $LangExtRoot is where the source code root should be\nLangExtRoot=/media/paul/raid/dev/language-ext\n\nrm -rf $Artifacts\n\nrm -rf $LangExtRoot/LanguageExt.Core/bin\nrm -rf $LangExtRoot/LanguageExt.Pipes/bin\nrm -rf $LangExtRoot/LanguageExt.Streaming/bin\nrm -rf $LangExtRoot/LanguageExt.Parsec/bin\nrm -rf $LangExtRoot/LanguageExt.FSharp/bin\nrm -rf $LangExtRoot/LanguageExt.Rx/bin\nrm -rf $LangExtRoot/LanguageExt.Sys/bin\n\nrm -rf $LangExtRoot/LanguageExt.Core/obj\nrm -rf $LangExtRoot/LanguageExt.Pipes/obj\nrm -rf $LangExtRoot/LanguageExt.Streaming/obj\nrm -rf $LangExtRoot/LanguageExt.Parsec/obj\nrm -rf $LangExtRoot/LanguageExt.FSharp/obj\nrm -rf $LangExtRoot/LanguageExt.Rx/obj\nrm -rf $LangExtRoot/LanguageExt.Sys/obj\n\necho cleaned\n"
  },
  {
    "path": "docs.sh",
    "content": "# $BestFormBin is where the bestform.exe is compiled to \nBestFormBin=/media/paul/raid/dev/best-form/bestform\n\n# $LangExtRoot is where the source code root should be\nLangExtRoot=/media/paul/raid/dev/language-ext\n\n# $LangExtDocs is where the docs root should be\nLangExtDocs=/media/paul/raid/dev/louthy.github.io\n\necho cleaning the docs\n\nrm -rf $LangExtDocs/language-ext/LanguageExt.Core\nrm -rf $LangExtDocs/language-ext/LanguageExt.Streaming\nrm -rf $LangExtDocs/language-ext/LanguageExt.Parsec\nrm -rf $LangExtDocs/language-ext/LanguageExt.FSharp\nrm -rf $LangExtDocs/language-ext/LanguageExt.Rx\nrm -rf $LangExtDocs/language-ext/LanguageExt.Sys\n\necho building the docs\n\ndotnet build $BestFormBin/bestform.csproj -c Release\ndotnet run --project $BestFormBin -c Release --no-build \"LanguageExt.Core\" \"$LangExtRoot/LanguageExt.Core\" \"$LangExtDocs/language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\ndotnet run --project $BestFormBin -c Release --no-build \"LanguageExt.Streaming\" \"$LangExtRoot/LanguageExt.Streaming\" \"$LangExtDocs/language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\ndotnet run --project $BestFormBin -c Release --no-build \"LanguageExt.Parsec\" \"$LangExtRoot/LanguageExt.Parsec\" \"$LangExtDocs/language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\ndotnet run --project $BestFormBin -c Release --no-build \"LanguageExt.FSharp\" \"$LangExtRoot/LanguageExt.FSharp\" \"$LangExtDocs/language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\ndotnet run --project $BestFormBin -c Release --no-build \"LanguageExt.Rx\" \"$LangExtRoot/LanguageExt.Rx\" \"$LangExtDocs/language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\ndotnet run --project $BestFormBin -c Release --no-build \"LanguageExt.Sys\" \"$LangExtRoot/LanguageExt.Sys\" \"$LangExtDocs/language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\n\necho committing docs to git\n\ncd $LangExtDocs || exit\n\ngit add .\ngit commit -m \"Language-ext documentation update\"\ngit push\n\necho finished commmitting docs to git\n"
  },
  {
    "path": "inc.bat",
    "content": "pjv\\pjv.exe inc"
  },
  {
    "path": "language-ext.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.28803.156\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"LanguageExt.Core\", \"LanguageExt.Core\\LanguageExt.Core.csproj\", \"{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"LanguageExt.FSharp\", \"LanguageExt.FSharp\\LanguageExt.FSharp.csproj\", \"{F7218BC7-BB70-48D7-8D43-0006E880F5BA}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"LanguageExt.Parsec\", \"LanguageExt.Parsec\\LanguageExt.Parsec.csproj\", \"{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Samples\", \"Samples\", \"{1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"TestBed\", \"Samples\\TestBed\\TestBed.csproj\", \"{3D165617-8A90-4BEB-B951-6168EDDA232D}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"LanguageExt.Tests\", \"LanguageExt.Tests\\LanguageExt.Tests.csproj\", \"{E882F67B-24EC-444B-B748-EE9BEFF904E2}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"LanguageExt.Rx\", \"LanguageExt.Rx\\LanguageExt.Rx.csproj\", \"{A191CF80-FC53-4142-9769-CF949F3277B9}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"LanguageExt.Benchmarks\", \"LanguageExt.Benchmarks\\LanguageExt.Benchmarks.csproj\", \"{4F7FCDBC-F37A-493B-A648-107F69F10EFF}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"LanguageExt.Sys\", \"LanguageExt.Sys\\LanguageExt.Sys.csproj\", \"{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"EffectsExamples\", \"Samples\\EffectsExamples\\EffectsExamples.csproj\", \"{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"TestBed.WPF\", \"Samples\\TestBed.WPF\\TestBed.WPF.csproj\", \"{F17CB314-8CC5-4343-AAE8-7292B700E5BA}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"IOExmples\", \"Samples\\IOExmples\\IOExmples.csproj\", \"{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"CardGame\", \"Samples\\CardGame\\CardGame.csproj\", \"{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Newsletter\", \"Samples\\Newsletter\\Newsletter\\Newsletter.csproj\", \"{32BB0F08-5A9D-4245-8721-2A3B12607270}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Streams\", \"Samples\\Streams\\Streams.csproj\", \"{B4D4721B-A599-4149-BD3A-822C277FC0FE}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"TestBed.Web\", \"Samples\\TestBed.Web\\TestBed.Web.csproj\", \"{A7058669-DC59-4FFA-9A04-143D9569F55D}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"TestBed.Web.Runner\", \"Samples\\TestBed.Web.Runner\\TestBed.Web.Runner.csproj\", \"{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"DomainTypesExamples\", \"Samples\\DomainTypesExamples\\DomainTypesExamples.csproj\", \"{72F07BEF-4379-4FD9-8CBA-CFB01D004718}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"CreditCardValidation\", \"Samples\\CreditCardValidation\\CreditCardValidation.csproj\", \"{AF8ED740-D77D-4080-9952-59232C57767C}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"LanguageExt.Streaming\", \"LanguageExt.Streaming\\LanguageExt.Streaming.csproj\", \"{6661A967-81D7-4236-99BC-AD42F71B6C1F}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"PipesExamples\", \"Samples\\PipesExamples\\PipesExamples.csproj\", \"{8CE4D269-B685-438C-AA1B-48D3E73C60DB}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"LanguageExt.XUnitExt\", \"LanguageExt.XUnitExt\\LanguageExt.XUnitExt.csproj\", \"{3F01D095-EA20-44B5-8B0D-4713601B0D9E}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"LanguageExt.Megaparsec\", \"LanguageExt.Megaparsec\\LanguageExt.Megaparsec.csproj\", \"{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"BlazorApp\", \"Samples\\BlazorApp\\BlazorApp.csproj\", \"{B5D1D911-24D0-4910-84C7-82F57EA65B33}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Release|x64.Build.0 = Release|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{4537B8A8-6CA4-4DCB-B30E-7CADD29A324F}.Release|x86.Build.0 = Release|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Release|x64.Build.0 = Release|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{F7218BC7-BB70-48D7-8D43-0006E880F5BA}.Release|x86.Build.0 = Release|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Release|x64.Build.0 = Release|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{29E65953-E2D9-4C9F-82FE-DEF50BBA4A48}.Release|x86.Build.0 = Release|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Release|x64.Build.0 = Release|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D}.Release|x86.Build.0 = Release|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Release|x64.Build.0 = Release|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{E882F67B-24EC-444B-B748-EE9BEFF904E2}.Release|x86.Build.0 = Release|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Release|x64.Build.0 = Release|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{A191CF80-FC53-4142-9769-CF949F3277B9}.Release|x86.Build.0 = Release|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Release|x64.Build.0 = Release|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{4F7FCDBC-F37A-493B-A648-107F69F10EFF}.Release|x86.Build.0 = Release|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Release|x64.Build.0 = Release|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{8D43E156-DE9A-46CD-A732-9F66A1F84B1D}.Release|x86.Build.0 = Release|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Release|x64.Build.0 = Release|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47}.Release|x86.Build.0 = Release|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Release|x64.Build.0 = Release|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{A5CEDB48-F840-4462-8BE9-65BF35C8D5A2}.Release|x86.Build.0 = Release|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Release|x64.Build.0 = Release|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA}.Release|x86.Build.0 = Release|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Release|x64.Build.0 = Release|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF}.Release|x86.Build.0 = Release|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Release|x64.Build.0 = Release|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2}.Release|x86.Build.0 = Release|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Release|x64.Build.0 = Release|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270}.Release|x86.Build.0 = Release|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Release|x64.Build.0 = Release|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE}.Release|x86.Build.0 = Release|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Release|x64.Build.0 = Release|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D}.Release|x86.Build.0 = Release|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Release|x64.Build.0 = Release|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5}.Release|x86.Build.0 = Release|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Release|x64.Build.0 = Release|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718}.Release|x86.Build.0 = Release|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Release|x64.Build.0 = Release|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C}.Release|x86.Build.0 = Release|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Release|x64.Build.0 = Release|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{6661A967-81D7-4236-99BC-AD42F71B6C1F}.Release|x86.Build.0 = Release|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Release|x64.Build.0 = Release|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB}.Release|x86.Build.0 = Release|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Release|x64.Build.0 = Release|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{3F01D095-EA20-44B5-8B0D-4713601B0D9E}.Release|x86.Build.0 = Release|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Release|x64.Build.0 = Release|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{9A2A964B-EF1B-4BB9-B57F-7E4798BFC1D6}.Release|x86.Build.0 = Release|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Release|x64.Build.0 = Release|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{3D165617-8A90-4BEB-B951-6168EDDA232D} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{A23ED3D6-6A1A-457C-A55A-21BCDC886A47} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{F17CB314-8CC5-4343-AAE8-7292B700E5BA} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{BA5DF6B6-378C-4880-9CC3-802F3B560EFF} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{B309F69E-87C4-43F3-9766-FCCDE6AC66A2} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{32BB0F08-5A9D-4245-8721-2A3B12607270} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{B4D4721B-A599-4149-BD3A-822C277FC0FE} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{A7058669-DC59-4FFA-9A04-143D9569F55D} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{F6CB0C45-09D5-4178-AEA6-F113E24FEEC5} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{72F07BEF-4379-4FD9-8CBA-CFB01D004718} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{AF8ED740-D77D-4080-9952-59232C57767C} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{8CE4D269-B685-438C-AA1B-48D3E73C60DB} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\t\t{B5D1D911-24D0-4910-84C7-82F57EA65B33} = {1ABB8B79-9BF2-4C51-A920-9C17BF11273F}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {ACEEC9A9-FE4F-43DD-918D-443A19399CE1}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "language-ext.sln.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARGUMENT/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARRAY_AND_OBJECT_INITIALIZER/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_BINARY_PATTERNS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXPRESSION/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_LIST_PATTERN/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_PARAMETER/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_PROPERTY_PATTERN/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_SWITCH_EXPRESSION/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTIPLE_DECLARATION/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_CONSTRAINS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_LIST/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_TUPLE_COMPONENTS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_ANONYMOUS_METHOD_BLOCK/@EntryValue\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_PRIMARY_CONSTRUCTOR_DECL_PARS/@EntryValue\">OUTSIDE_AND_INSIDE</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_METHOD_DECL_PARS/@EntryValue\">OUTSIDE</s:String>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_BINARY_EXPRESSIONS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_COMMENTS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_NESTED_TERNARY/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_PROPERTY_PATTERNS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_SWITCH_EXPRESSIONS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_SWITCH_SECTIONS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_VARIABLES/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/OUTDENT_BINARY_OPS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/OUTDENT_BINARY_PATTERN_OPS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/OUTDENT_COMMAS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/OUTDENT_DOTS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue\">False</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue\">True</s:Boolean></wpf:ResourceDictionary>"
  },
  {
    "path": "pack.bat",
    "content": "echo building the docs\n\n:: %LangExtRoot% is where the source code root should be (i.e. c:\\dev\\language-ext)\n:: %LangExtDocs% is where the docs root should be (i.e. c:\\dev\\louthy.github.io)\n\nQ:\ncd Q:\\Dev\\best-form\\bestform\\bin\\Release\\net8.0\nbestform.exe \"LanguageExt.Core\" \"%LangExtRoot%\\LanguageExt.Core\" \"%LangExtDocs%\\language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\nbestform.exe \"LanguageExt.Parsec\" \"%LangExtRoot%\\LanguageExt.Parsec\" \"%LangExtDocs%\\language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\nbestform.exe \"LanguageExt.FSharp\" \"%LangExtRoot%\\LanguageExt.FSharp\" \"%LangExtDocs%\\language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\nbestform.exe \"LanguageExt.Rx\" \"%LangExtRoot%\\LanguageExt.Rx\" \"%LangExtDocs%\\language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\nbestform.exe \"LanguageExt.Sys\" \"%LangExtRoot%\\LanguageExt.Sys\" \"%LangExtDocs%\\language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\nbestform.exe \"LanguageExt.Streaming\" \"%LangExtRoot%\\LanguageExt.Streaming\" \"%LangExtDocs%\\language-ext\" \"https://github.com/louthy/language-ext/tree/main\"\n\necho committing them to git\n\ncd %LangExtDocs%\n\ngit add .\ngit commit -m \"Language-ext documentation update\"\ngit push\n\ncd %LangExtRoot%\n\necho building the artefacts\n\ndotnet restore\ndotnet pack LanguageExt.Core -c Release -o ../../artifacts/bin\ndotnet pack LanguageExt.FSharp -c Release -o ../../artifacts/bin\ndotnet pack LanguageExt.Parsec -c Release -o ../../artifacts/bin\ndotnet pack LanguageExt.Rx -c Release -o ../../artifacts/bin\ndotnet pack LanguageExt.Sys -c Release -o ../../artifacts/bin\ndotnet pack LanguageExt.Streaming -c Release -o ../../artifacts/bin\n\n"
  },
  {
    "path": "pack.sh",
    "content": "# Artifacts is where the DLLs are compiled to \nArtifacts=/media/paul/raid/dev/artifacts\n\n# $LangExtRoot is where the source code root should be\nLangExtRoot=/media/paul/raid/dev/language-ext\n\nsh clean.sh\nsh docs.sh\n\ncd $LangExtRoot || exit\n\necho building the artefacts\n \ndotnet restore\ndotnet pack LanguageExt.Core -c Release -o $Artifacts\ndotnet pack LanguageExt.Streaming -c Release -o $Artifacts\ndotnet pack LanguageExt.FSharp -c Release -o $Artifacts\ndotnet pack LanguageExt.Parsec -c Release -o $Artifacts\ndotnet pack LanguageExt.Rx -c Release -o $Artifacts\ndotnet pack LanguageExt.Sys -c Release -o $Artifacts\n\nsh ../push-language-ext.sh"
  },
  {
    "path": "pjv/LanguageExt.Core.3.1.9-beta.nuspec",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<package xmlns=\"http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd\">\n    <metadata>\n        <id>LanguageExt.Core</id>\n        <version>3.1.9-beta</version>\n        <title>LanguageExt.Core</title>\n        <authors>Paul Louth</authors>\n        <owners>Paul Louth</owners>\n        <licenseUrl>https://github.com/louthy/language-ext/blob/master/LICENSE.md</licenseUrl>\n        <projectUrl>https://github.com/louthy/language-ext</projectUrl>\n        <iconUrl>https://raw.githubusercontent.com/louthy/language-ext/master/backers-images/lang-ext-thumb.png</iconUrl>\n        <requireLicenseAcceptance>false</requireLicenseAcceptance>\n        <description>This library uses and abuses the features of C# 6 and 7 to provide a functional 'Base class library', that, if you squint, can look like extensions to the language itself.</description>\n        <copyright>Copyright (c) Paul Louth. All rights reserved.</copyright>\n        <tags>C#, Functional, Language Extension, Monad, Option, Either, Reader, Writer, State, List, Set, Map, Queue, Memo, Memoization, Immutable, Lambda, Pattern Matching, Tuple</tags>\n        <dependencies>\n            <group targetFramework=\".NETFramework4.5\">\n                <dependency id=\"Microsoft.CSharp\" version=\"4.5.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.Reflection.Emit\" version=\"4.3.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.ValueTuple\" version=\"4.5.0\" exclude=\"Build,Analyzers\" />\n            </group>\n            <group targetFramework=\".NETStandard2.0\">\n                <dependency id=\"Microsoft.CSharp\" version=\"4.5.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.Diagnostics.Contracts\" version=\"4.3.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.Globalization.Extensions\" version=\"4.3.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.Linq\" version=\"4.3.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.Linq.Queryable\" version=\"4.3.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.Reflection.Emit\" version=\"4.3.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.Reflection.Emit.Lightweight\" version=\"4.3.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.Runtime.Serialization.Formatters\" version=\"4.3.0\" exclude=\"Build,Analyzers\" />\n                <dependency id=\"System.ValueTuple\" version=\"4.5.0\" exclude=\"Build,Analyzers\" />\n            </group>\n        </dependencies>\n    </metadata>\n    <files>\n        <file src=\"lib\\net45\\LanguageExt.Core.dll\" target=\"lib\\net45\\LanguageExt.Core.dll\" />\n        <file src=\"lib\\net45\\LanguageExt.Core.xml\" target=\"lib\\net45\\LanguageExt.Core.xml\" />\n        <file src=\"lib\\netstandard2.0\\LanguageExt.Core.dll\" target=\"lib\\netstandard2.0\\LanguageExt.Core.dll\" />\n        <file src=\"lib\\netstandard2.0\\LanguageExt.Core.xml\" target=\"lib\\netstandard2.0\\LanguageExt.Core.xml\" />\n    </files>\n</package>"
  }
]